1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
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"
88 #include "intervals.h"
93 #include <X11/Shell.h>
96 #ifdef HAVE_SYS_TIME_H
105 extern void free_frame_menubar
P_ ((struct frame
*));
106 extern struct frame
*x_menubar_window_to_frame
P_ ((struct x_display_info
*,
109 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
111 extern void _XEditResCheckMessages ();
112 #endif /* not NO_EDITRES */
114 /* Include toolkit specific headers for the scroll bar widget. */
116 #ifdef USE_TOOLKIT_SCROLL_BARS
117 #if defined USE_MOTIF
118 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
119 #include <Xm/ScrollBar.h>
120 #include <Xm/ScrollBarP.h>
121 #else /* !USE_MOTIF i.e. use Xaw */
124 #include <X11/Xaw3d/Simple.h>
125 #include <X11/Xaw3d/Scrollbar.h>
126 #define ARROW_SCROLLBAR
127 #include <X11/Xaw3d/ScrollbarP.h>
128 #else /* !HAVE_XAW3D */
129 #include <X11/Xaw/Simple.h>
130 #include <X11/Xaw/Scrollbar.h>
131 #endif /* !HAVE_XAW3D */
133 #define XtNpickTop "pickTop"
134 #endif /* !XtNpickTop */
135 #endif /* !USE_MOTIF */
136 #endif /* USE_TOOLKIT_SCROLL_BARS */
138 #endif /* USE_X_TOOLKIT */
140 #ifndef USE_X_TOOLKIT
141 #define x_any_window_to_frame x_window_to_frame
142 #define x_top_window_to_frame x_window_to_frame
147 #ifndef XtNinitialState
148 #define XtNinitialState "initialState"
153 #define min(a,b) ((a) < (b) ? (a) : (b))
156 #define max(a,b) ((a) > (b) ? (a) : (b))
159 #define abs(x) ((x) < 0 ? -(x) : (x))
161 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
164 /* Bitmaps for truncated lines. */
169 LEFT_TRUNCATION_BITMAP
,
170 RIGHT_TRUNCATION_BITMAP
,
171 OVERLAY_ARROW_BITMAP
,
172 CONTINUED_LINE_BITMAP
,
173 CONTINUATION_LINE_BITMAP
,
177 /* Bitmap drawn to indicate lines not displaying text if
178 `indicate-empty-lines' is non-nil. */
182 static unsigned char zv_bits
[] = {
183 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
185 /* An arrow like this: `<-'. */
188 #define left_height 8
189 static unsigned char left_bits
[] = {
190 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
192 /* Right truncation arrow bitmap `->'. */
194 #define right_width 8
195 #define right_height 8
196 static unsigned char right_bits
[] = {
197 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
199 /* Marker for continued lines. */
201 #define continued_width 8
202 #define continued_height 8
203 static unsigned char continued_bits
[] = {
204 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
206 /* Marker for continuation lines. */
208 #define continuation_width 8
209 #define continuation_height 8
210 static unsigned char continuation_bits
[] = {
211 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
213 /* Overlay arrow bitmap. */
219 static unsigned char ov_bits
[] = {
220 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
222 /* A triangular arrow. */
225 static unsigned char ov_bits
[] = {
226 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
230 extern Lisp_Object Qhelp_echo
;
233 /* Non-zero means Emacs uses toolkit scroll bars. */
235 int x_toolkit_scroll_bars_p
;
237 /* If a string, XTread_socket generates an event to display that string.
238 (The display is done in read_char.) */
240 static Lisp_Object help_echo
;
241 static Lisp_Object help_echo_window
;
242 static Lisp_Object help_echo_object
;
243 static int help_echo_pos
;
245 /* Temporary variable for XTread_socket. */
247 static Lisp_Object previous_help_echo
;
249 /* Non-zero means that a HELP_EVENT has been generated since Emacs
252 static int any_help_event_p
;
254 /* Non-zero means draw block and hollow cursor as wide as the glyph
255 under it. For example, if a block cursor is over a tab, it will be
256 drawn as wide as that tab on the display. */
258 int x_stretch_cursor_p
;
260 /* This is a chain of structures for all the X displays currently in
263 struct x_display_info
*x_display_list
;
265 /* This is a list of cons cells, each of the form (NAME
266 . FONT-LIST-CACHE), one for each element of x_display_list and in
267 the same order. NAME is the name of the frame. FONT-LIST-CACHE
268 records previous values returned by x-list-fonts. */
270 Lisp_Object x_display_name_list
;
272 /* Frame being updated by update_frame. This is declared in term.c.
273 This is set by update_begin and looked at by all the XT functions.
274 It is zero while not inside an update. In that case, the XT
275 functions assume that `selected_frame' is the frame to apply to. */
277 extern struct frame
*updating_frame
;
279 extern int waiting_for_input
;
281 /* This is a frame waiting to be auto-raised, within XTread_socket. */
283 struct frame
*pending_autoraise_frame
;
286 /* The application context for Xt use. */
287 XtAppContext Xt_app_con
;
288 static String Xt_default_resources
[] = {0};
289 #endif /* USE_X_TOOLKIT */
291 /* Nominal cursor position -- where to draw output.
292 HPOS and VPOS are window relative glyph matrix coordinates.
293 X and Y are window relative pixel coordinates. */
295 struct cursor_pos output_cursor
;
297 /* Non-zero means user is interacting with a toolkit scroll bar. */
299 static int toolkit_scroll_bar_interaction
;
303 Formerly, we used PointerMotionHintMask (in standard_event_mask)
304 so that we would have to call XQueryPointer after each MotionNotify
305 event to ask for another such event. However, this made mouse tracking
306 slow, and there was a bug that made it eventually stop.
308 Simply asking for MotionNotify all the time seems to work better.
310 In order to avoid asking for motion events and then throwing most
311 of them away or busy-polling the server for mouse positions, we ask
312 the server for pointer motion hints. This means that we get only
313 one event per group of mouse movements. "Groups" are delimited by
314 other kinds of events (focus changes and button clicks, for
315 example), or by XQueryPointer calls; when one of these happens, we
316 get another MotionNotify event the next time the mouse moves. This
317 is at least as efficient as getting motion events when mouse
318 tracking is on, and I suspect only negligibly worse when tracking
321 /* Where the mouse was last time we reported a mouse event. */
323 FRAME_PTR last_mouse_frame
;
324 static XRectangle last_mouse_glyph
;
325 static Lisp_Object last_mouse_press_frame
;
327 /* The scroll bar in which the last X motion event occurred.
329 If the last X motion event occurred in a scroll bar, we set this so
330 XTmouse_position can know whether to report a scroll bar motion or
333 If the last X motion event didn't occur in a scroll bar, we set
334 this to Qnil, to tell XTmouse_position to return an ordinary motion
337 static Lisp_Object last_mouse_scroll_bar
;
339 /* This is a hack. We would really prefer that XTmouse_position would
340 return the time associated with the position it returns, but there
341 doesn't seem to be any way to wrest the time-stamp from the server
342 along with the position query. So, we just keep track of the time
343 of the last movement we received, and return that in hopes that
344 it's somewhat accurate. */
346 static Time last_mouse_movement_time
;
348 /* Incremented by XTread_socket whenever it really tries to read
352 static int volatile input_signal_count
;
354 static int input_signal_count
;
357 /* Used locally within XTread_socket. */
359 static int x_noop_count
;
361 /* Initial values of argv and argc. */
363 extern char **initial_argv
;
364 extern int initial_argc
;
366 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
368 /* Tells if a window manager is present or not. */
370 extern Lisp_Object Vx_no_window_manager
;
372 extern Lisp_Object Qface
, Qmouse_face
;
376 /* A mask of extra modifier bits to put into every keyboard char. */
378 extern int extra_keyboard_modifiers
;
380 static Lisp_Object Qvendor_specific_keysyms
;
382 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
383 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
386 /* Enumeration for overriding/changing the face to use for drawing
387 glyphs in x_draw_glyphs. */
389 enum draw_glyphs_face
399 static const XColor
*x_color_cells
P_ ((struct frame
*, int *));
400 static void x_update_window_end
P_ ((struct window
*, int, int));
401 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
402 void x_delete_display
P_ ((struct x_display_info
*));
403 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
405 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
407 static void set_output_cursor
P_ ((struct cursor_pos
*));
408 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
409 int *, int *, int *));
410 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
411 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
412 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
413 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
414 static void show_mouse_face
P_ ((struct x_display_info
*,
415 enum draw_glyphs_face
));
416 static int x_io_error_quitter
P_ ((Display
*));
417 int x_catch_errors
P_ ((Display
*));
418 void x_uncatch_errors
P_ ((Display
*, int));
419 void x_lower_frame
P_ ((struct frame
*));
420 void x_scroll_bar_clear
P_ ((struct frame
*));
421 int x_had_errors_p
P_ ((Display
*));
422 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
423 void x_raise_frame
P_ ((struct frame
*));
424 void x_set_window_size
P_ ((struct frame
*, int, int, int));
425 void x_wm_set_window_state
P_ ((struct frame
*, int));
426 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
427 void x_initialize
P_ ((void));
428 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
429 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
430 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
432 enum draw_glyphs_face
));
433 static void x_update_end
P_ ((struct frame
*));
434 static void XTframe_up_to_date
P_ ((struct frame
*));
435 static void XTreassert_line_highlight
P_ ((int, int));
436 static void x_change_line_highlight
P_ ((int, int, int, int));
437 static void XTset_terminal_modes
P_ ((void));
438 static void XTreset_terminal_modes
P_ ((void));
439 static void XTcursor_to
P_ ((int, int, int, int));
440 static void x_write_glyphs
P_ ((struct glyph
*, int));
441 static void x_clear_end_of_line
P_ ((int));
442 static void x_clear_frame
P_ ((void));
443 static void x_clear_cursor
P_ ((struct window
*));
444 static void frame_highlight
P_ ((struct frame
*));
445 static void frame_unhighlight
P_ ((struct frame
*));
446 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
447 static void XTframe_rehighlight
P_ ((struct frame
*));
448 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
449 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
450 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
451 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
453 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
454 static void expose_window_tree
P_ ((struct window
*, XRectangle
*));
455 static void expose_window
P_ ((struct window
*, XRectangle
*));
456 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
457 XRectangle
*, enum glyph_row_area
));
458 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
460 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
461 static void x_update_window_cursor
P_ ((struct window
*, int));
462 static void x_erase_phys_cursor
P_ ((struct window
*));
463 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
464 static void x_draw_bitmap
P_ ((struct window
*, struct glyph_row
*,
467 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
469 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
470 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
471 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
472 static void x_flush
P_ ((struct frame
*f
));
473 static void x_update_begin
P_ ((struct frame
*));
474 static void x_update_window_begin
P_ ((struct window
*));
475 static void x_draw_vertical_border
P_ ((struct window
*));
476 static void x_after_update_window_line
P_ ((struct glyph_row
*));
477 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
478 static void x_produce_stretch_glyph
P_ ((struct it
*));
481 /* Flush display of frame F, or of all frames if F is null. */
490 Lisp_Object rest
, frame
;
491 FOR_EACH_FRAME (rest
, frame
)
492 x_flush (XFRAME (frame
));
494 else if (FRAME_X_P (f
))
495 XFlush (FRAME_X_DISPLAY (f
));
500 /* Remove calls to XFlush by defining XFlush to an empty replacement.
501 Calls to XFlush should be unnecessary because the X output buffer
502 is flushed automatically as needed by calls to XPending,
503 XNextEvent, or XWindowEvent according to the XFlush man page.
504 XTread_socket calls XPending. Removing XFlush improves
507 #define XFlush(DISPLAY) (void) 0
510 /***********************************************************************
512 ***********************************************************************/
516 /* This is a function useful for recording debugging information about
517 the sequence of occurrences in this file. */
525 struct record event_record
[100];
527 int event_record_index
;
529 record_event (locus
, type
)
533 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
534 event_record_index
= 0;
536 event_record
[event_record_index
].locus
= locus
;
537 event_record
[event_record_index
].type
= type
;
538 event_record_index
++;
545 /* Return the struct x_display_info corresponding to DPY. */
547 struct x_display_info
*
548 x_display_info_for_display (dpy
)
551 struct x_display_info
*dpyinfo
;
553 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
554 if (dpyinfo
->display
== dpy
)
562 /***********************************************************************
563 Starting and ending an update
564 ***********************************************************************/
566 /* Start an update of frame F. This function is installed as a hook
567 for update_begin, i.e. it is called when update_begin is called.
568 This function is called prior to calls to x_update_window_begin for
569 each window being updated. Currently, there is nothing to do here
570 because all interesting stuff is done on a window basis. */
580 /* Start update of window W. Set the global variable updated_window
581 to the window being updated and set output_cursor to the cursor
585 x_update_window_begin (w
)
588 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
589 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
592 set_output_cursor (&w
->cursor
);
596 if (f
== display_info
->mouse_face_mouse_frame
)
598 /* Don't do highlighting for mouse motion during the update. */
599 display_info
->mouse_face_defer
= 1;
601 /* If F needs to be redrawn, simply forget about any prior mouse
603 if (FRAME_GARBAGED_P (f
))
604 display_info
->mouse_face_window
= Qnil
;
606 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
607 their mouse_face_p flag set, which means that they are always
608 unequal to rows in a desired matrix which never have that
609 flag set. So, rows containing mouse-face glyphs are never
610 scrolled, and we don't have to switch the mouse highlight off
611 here to prevent it from being scrolled. */
613 /* Can we tell that this update does not affect the window
614 where the mouse highlight is? If so, no need to turn off.
615 Likewise, don't do anything if the frame is garbaged;
616 in that case, the frame's current matrix that we would use
617 is all wrong, and we will redisplay that line anyway. */
618 if (!NILP (display_info
->mouse_face_window
)
619 && w
== XWINDOW (display_info
->mouse_face_window
))
623 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
624 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
627 if (i
< w
->desired_matrix
->nrows
)
628 clear_mouse_face (display_info
);
637 /* Draw a vertical window border to the right of window W if W doesn't
638 have vertical scroll bars. */
641 x_draw_vertical_border (w
)
644 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
646 /* Redraw borders between horizontally adjacent windows. Don't
647 do it for frames with vertical scroll bars because either the
648 right scroll bar of a window, or the left scroll bar of its
649 neighbor will suffice as a border. */
650 if (!WINDOW_RIGHTMOST_P (w
)
651 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
655 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
656 x1
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
659 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
660 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
665 /* End update of window W (which is equal to updated_window).
667 Draw vertical borders between horizontally adjacent windows, and
668 display W's cursor if CURSOR_ON_P is non-zero.
670 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
671 glyphs in mouse-face were overwritten. In that case we have to
672 make sure that the mouse-highlight is properly redrawn.
674 W may be a menu bar pseudo-window in case we don't have X toolkit
675 support. Such windows don't have a cursor, so don't display it
679 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
681 int cursor_on_p
, mouse_face_overwritten_p
;
683 if (!w
->pseudo_window_p
)
685 struct x_display_info
*dpyinfo
686 = FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
690 /* If a row with mouse-face was overwritten, arrange for
691 XTframe_up_to_date to redisplay the mouse highlight. */
692 if (mouse_face_overwritten_p
)
694 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
695 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
696 dpyinfo
->mouse_face_window
= Qnil
;
700 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
702 output_cursor
.x
, output_cursor
.y
);
704 x_draw_vertical_border (w
);
708 updated_window
= NULL
;
712 /* End update of frame F. This function is installed as a hook in
719 /* Mouse highlight may be displayed again. */
720 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
723 XFlush (FRAME_X_DISPLAY (f
));
728 /* This function is called from various places in xdisp.c whenever a
729 complete update has been performed. The global variable
730 updated_window is not available here. */
733 XTframe_up_to_date (f
)
738 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
740 if (dpyinfo
->mouse_face_deferred_gc
741 || f
== dpyinfo
->mouse_face_mouse_frame
)
744 if (dpyinfo
->mouse_face_mouse_frame
)
745 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
746 dpyinfo
->mouse_face_mouse_x
,
747 dpyinfo
->mouse_face_mouse_y
);
748 dpyinfo
->mouse_face_deferred_gc
= 0;
755 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
756 arrow bitmaps, or clear the areas where they would be displayed
757 before DESIRED_ROW is made current. The window being updated is
758 found in updated_window. This function It is called from
759 update_window_line only if it is known that there are differences
760 between bitmaps to be drawn between current row and DESIRED_ROW. */
763 x_after_update_window_line (desired_row
)
764 struct glyph_row
*desired_row
;
766 struct window
*w
= updated_window
;
770 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
773 x_draw_row_bitmaps (w
, desired_row
);
775 /* When a window has disappeared, make sure that no rest of
776 full-width rows stays visible in the internal border. */
777 if (windows_or_buffers_changed
)
779 struct frame
*f
= XFRAME (w
->frame
);
780 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
781 int height
= desired_row
->visible_height
;
782 int x
= (window_box_right (w
, -1)
783 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
784 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
786 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
787 x
, y
, width
, height
, False
);
795 /* Draw the bitmap WHICH in one of the areas to the left or right of
796 window W. ROW is the glyph row for which to display the bitmap; it
797 determines the vertical position at which the bitmap has to be
801 x_draw_bitmap (w
, row
, which
)
803 struct glyph_row
*row
;
804 enum bitmap_type which
;
806 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
807 Display
*display
= FRAME_X_DISPLAY (f
);
808 Window window
= FRAME_X_WINDOW (f
);
812 GC gc
= f
->output_data
.x
->normal_gc
;
814 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
816 /* Must clip because of partially visible lines. */
817 x_clip_to_row (w
, row
, gc
, 1);
821 case LEFT_TRUNCATION_BITMAP
:
825 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
827 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
830 case OVERLAY_ARROW_BITMAP
:
834 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
836 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
839 case RIGHT_TRUNCATION_BITMAP
:
843 x
= window_box_right (w
, -1);
844 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
847 case CONTINUED_LINE_BITMAP
:
850 bits
= continued_bits
;
851 x
= window_box_right (w
, -1);
852 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
855 case CONTINUATION_LINE_BITMAP
:
856 wd
= continuation_width
;
857 h
= continuation_height
;
858 bits
= continuation_bits
;
859 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
861 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
868 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
870 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
877 /* Convert to frame coordinates. Set dy to the offset in the row to
878 start drawing the bitmap. */
879 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
880 dy
= (row
->height
- h
) / 2;
882 /* Draw the bitmap. I believe these small pixmaps can be cached
884 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
885 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
887 face
->background
, depth
);
888 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
889 XFreePixmap (display
, pixmap
);
890 XSetClipMask (display
, gc
, None
);
894 /* Draw flags bitmaps for glyph row ROW on window W. Call this
895 function with input blocked. */
898 x_draw_row_bitmaps (w
, row
)
900 struct glyph_row
*row
;
902 struct frame
*f
= XFRAME (w
->frame
);
903 enum bitmap_type bitmap
;
905 int header_line_height
= -1;
907 xassert (interrupt_input_blocked
);
909 /* If row is completely invisible, because of vscrolling, we
910 don't have to draw anything. */
911 if (row
->visible_height
<= 0)
914 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
915 PREPARE_FACE_FOR_DISPLAY (f
, face
);
917 /* Decide which bitmap to draw at the left side. */
918 if (row
->overlay_arrow_p
)
919 bitmap
= OVERLAY_ARROW_BITMAP
;
920 else if (row
->truncated_on_left_p
)
921 bitmap
= LEFT_TRUNCATION_BITMAP
;
922 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
923 bitmap
= CONTINUATION_LINE_BITMAP
;
924 else if (row
->indicate_empty_line_p
)
925 bitmap
= ZV_LINE_BITMAP
;
929 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
931 if (bitmap
== NO_BITMAP
932 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
933 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
935 /* If W has a vertical border to its left, don't draw over it. */
936 int border
= ((XFASTINT (w
->left
) > 0
937 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
939 int left
= window_box_left (w
, -1);
941 if (header_line_height
< 0)
942 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
944 /* In case the same realized face is used for bitmap areas and
945 for something displayed in the text (e.g. face `region' on
946 mono-displays, the fill style may have been changed to
947 FillSolid in x_draw_glyph_string_background. */
949 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
951 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
953 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
956 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
958 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
960 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
961 row
->visible_height
);
963 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
966 /* Draw the left bitmap. */
967 if (bitmap
!= NO_BITMAP
)
968 x_draw_bitmap (w
, row
, bitmap
);
970 /* Decide which bitmap to draw at the right side. */
971 if (row
->truncated_on_right_p
)
972 bitmap
= RIGHT_TRUNCATION_BITMAP
;
973 else if (row
->continued_p
)
974 bitmap
= CONTINUED_LINE_BITMAP
;
978 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
980 if (bitmap
== NO_BITMAP
981 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
982 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
984 int right
= window_box_right (w
, -1);
986 if (header_line_height
< 0)
987 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
989 /* In case the same realized face is used for bitmap areas and
990 for something displayed in the text (e.g. face `region' on
991 mono-displays, the fill style may have been changed to
992 FillSolid in x_draw_glyph_string_background. */
994 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
996 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
997 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1000 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1002 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
1003 row
->visible_height
);
1005 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1008 /* Draw the right bitmap. */
1009 if (bitmap
!= NO_BITMAP
)
1010 x_draw_bitmap (w
, row
, bitmap
);
1014 /***********************************************************************
1016 ***********************************************************************/
1018 /* External interface to control of standout mode. Not used for X
1019 frames. Aborts when called. */
1022 XTreassert_line_highlight (new, vpos
)
1029 /* Call this when about to modify line at position VPOS and change
1030 whether it is highlighted. Not used for X frames. Aborts when
1034 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1035 int new_highlight
, vpos
, y
, first_unused_hpos
;
1041 /* This is called when starting Emacs and when restarting after
1042 suspend. When starting Emacs, no X window is mapped. And nothing
1043 must be done to Emacs's own window if it is suspended (though that
1047 XTset_terminal_modes ()
1051 /* This is called when exiting or suspending Emacs. Exiting will make
1052 the X-windows go away, and suspending requires no action. */
1055 XTreset_terminal_modes ()
1061 /***********************************************************************
1063 ***********************************************************************/
1065 /* Set the global variable output_cursor to CURSOR. All cursor
1066 positions are relative to updated_window. */
1069 set_output_cursor (cursor
)
1070 struct cursor_pos
*cursor
;
1072 output_cursor
.hpos
= cursor
->hpos
;
1073 output_cursor
.vpos
= cursor
->vpos
;
1074 output_cursor
.x
= cursor
->x
;
1075 output_cursor
.y
= cursor
->y
;
1079 /* Set a nominal cursor position.
1081 HPOS and VPOS are column/row positions in a window glyph matrix. X
1082 and Y are window text area relative pixel positions.
1084 If this is done during an update, updated_window will contain the
1085 window that is being updated and the position is the future output
1086 cursor position for that window. If updated_window is null, use
1087 selected_window and display the cursor at the given position. */
1090 XTcursor_to (vpos
, hpos
, y
, x
)
1091 int vpos
, hpos
, y
, x
;
1095 /* If updated_window is not set, work on selected_window. */
1099 w
= XWINDOW (selected_window
);
1101 /* Set the output cursor. */
1102 output_cursor
.hpos
= hpos
;
1103 output_cursor
.vpos
= vpos
;
1104 output_cursor
.x
= x
;
1105 output_cursor
.y
= y
;
1107 /* If not called as part of an update, really display the cursor.
1108 This will also set the cursor position of W. */
1109 if (updated_window
== NULL
)
1112 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1113 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1120 /***********************************************************************
1122 ***********************************************************************/
1124 /* Function prototypes of this page. */
1126 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1130 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1131 int, XChar2b
*, int));
1132 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1133 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1134 static void x_append_glyph
P_ ((struct it
*));
1135 static void x_append_composite_glyph
P_ ((struct it
*));
1136 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1138 static void x_produce_glyphs
P_ ((struct it
*));
1139 static void x_produce_image_glyph
P_ ((struct it
*it
));
1142 /* Return a pointer to per-char metric information in FONT of a
1143 character pointed by B which is a pointer to an XChar2b. */
1145 #define PER_CHAR_METRIC(font, b) \
1147 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1148 + (((font)->min_byte1 || (font)->max_byte1) \
1149 ? (((b)->byte1 - (font)->min_byte1) \
1150 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1152 : &((font)->max_bounds))
1155 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1156 is not contained in the font. */
1158 static INLINE XCharStruct
*
1159 x_per_char_metric (font
, char2b
)
1163 /* The result metric information. */
1164 XCharStruct
*pcm
= NULL
;
1166 xassert (font
&& char2b
);
1168 if (font
->per_char
!= NULL
)
1170 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1172 /* min_char_or_byte2 specifies the linear character index
1173 corresponding to the first element of the per_char array,
1174 max_char_or_byte2 is the index of the last character. A
1175 character with non-zero CHAR2B->byte1 is not in the font.
1176 A character with byte2 less than min_char_or_byte2 or
1177 greater max_char_or_byte2 is not in the font. */
1178 if (char2b
->byte1
== 0
1179 && char2b
->byte2
>= font
->min_char_or_byte2
1180 && char2b
->byte2
<= font
->max_char_or_byte2
)
1181 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1185 /* If either min_byte1 or max_byte1 are nonzero, both
1186 min_char_or_byte2 and max_char_or_byte2 are less than
1187 256, and the 2-byte character index values corresponding
1188 to the per_char array element N (counting from 0) are:
1190 byte1 = N/D + min_byte1
1191 byte2 = N\D + min_char_or_byte2
1195 D = max_char_or_byte2 - min_char_or_byte2 + 1
1196 / = integer division
1197 \ = integer modulus */
1198 if (char2b
->byte1
>= font
->min_byte1
1199 && char2b
->byte1
<= font
->max_byte1
1200 && char2b
->byte2
>= font
->min_char_or_byte2
1201 && char2b
->byte2
<= font
->max_char_or_byte2
)
1203 pcm
= (font
->per_char
1204 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1205 * (char2b
->byte1
- font
->min_byte1
))
1206 + (char2b
->byte2
- font
->min_char_or_byte2
));
1212 /* If the per_char pointer is null, all glyphs between the first
1213 and last character indexes inclusive have the same
1214 information, as given by both min_bounds and max_bounds. */
1215 if (char2b
->byte2
>= font
->min_char_or_byte2
1216 && char2b
->byte2
<= font
->max_char_or_byte2
)
1217 pcm
= &font
->max_bounds
;
1220 return ((pcm
== NULL
1221 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1226 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1227 the two-byte form of C. Encoding is returned in *CHAR2B. */
1230 x_encode_char (c
, char2b
, font_info
)
1233 struct font_info
*font_info
;
1235 int charset
= CHAR_CHARSET (c
);
1236 XFontStruct
*font
= font_info
->font
;
1238 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1239 This may be either a program in a special encoder language or a
1241 if (font_info
->font_encoder
)
1243 /* It's a program. */
1244 struct ccl_program
*ccl
= font_info
->font_encoder
;
1246 if (CHARSET_DIMENSION (charset
) == 1)
1248 ccl
->reg
[0] = charset
;
1249 ccl
->reg
[1] = char2b
->byte2
;
1253 ccl
->reg
[0] = charset
;
1254 ccl
->reg
[1] = char2b
->byte1
;
1255 ccl
->reg
[2] = char2b
->byte2
;
1258 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1260 /* We assume that MSBs are appropriately set/reset by CCL
1262 if (font
->max_byte1
== 0) /* 1-byte font */
1263 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1265 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1267 else if (font_info
->encoding
[charset
])
1269 /* Fixed encoding scheme. See fontset.h for the meaning of the
1270 encoding numbers. */
1271 int enc
= font_info
->encoding
[charset
];
1273 if ((enc
== 1 || enc
== 2)
1274 && CHARSET_DIMENSION (charset
) == 2)
1275 char2b
->byte1
|= 0x80;
1277 if (enc
== 1 || enc
== 3)
1278 char2b
->byte2
|= 0x80;
1283 /* Get face and two-byte form of character C in face FACE_ID on frame
1284 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1285 means we want to display multibyte text. Value is a pointer to a
1286 realized face that is ready for display. */
1288 static INLINE
struct face
*
1289 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1295 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1299 /* Unibyte case. We don't have to encode, but we have to make
1300 sure to use a face suitable for unibyte. */
1303 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1304 face
= FACE_FROM_ID (f
, face_id
);
1306 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1308 /* Case of ASCII in a face known to fit ASCII. */
1314 int c1
, c2
, charset
;
1316 /* Split characters into bytes. If c2 is -1 afterwards, C is
1317 really a one-byte character so that byte1 is zero. */
1318 SPLIT_CHAR (c
, charset
, c1
, c2
);
1320 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1322 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1324 /* Maybe encode the character in *CHAR2B. */
1325 if (face
->font
!= NULL
)
1327 struct font_info
*font_info
1328 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1330 x_encode_char (c
, char2b
, font_info
);
1334 /* Make sure X resources of the face are allocated. */
1335 xassert (face
!= NULL
);
1336 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1342 /* Get face and two-byte form of character glyph GLYPH on frame F.
1343 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1344 a pointer to a realized face that is ready for display. */
1346 static INLINE
struct face
*
1347 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1349 struct glyph
*glyph
;
1355 xassert (glyph
->type
== CHAR_GLYPH
);
1356 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1361 if (!glyph
->multibyte_p
)
1363 /* Unibyte case. We don't have to encode, but we have to make
1364 sure to use a face suitable for unibyte. */
1366 char2b
->byte2
= glyph
->u
.ch
;
1368 else if (glyph
->u
.ch
< 128
1369 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1371 /* Case of ASCII in a face known to fit ASCII. */
1373 char2b
->byte2
= glyph
->u
.ch
;
1377 int c1
, c2
, charset
;
1379 /* Split characters into bytes. If c2 is -1 afterwards, C is
1380 really a one-byte character so that byte1 is zero. */
1381 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1383 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1385 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1387 /* Maybe encode the character in *CHAR2B. */
1388 if (charset
!= CHARSET_ASCII
)
1390 struct font_info
*font_info
1391 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1394 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1397 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1402 /* Make sure X resources of the face are allocated. */
1403 xassert (face
!= NULL
);
1404 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1409 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1410 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1416 struct glyph
*glyph
;
1417 enum glyph_row_area area
= it
->area
;
1419 xassert (it
->glyph_row
);
1420 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1422 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1423 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1425 glyph
->charpos
= CHARPOS (it
->position
);
1426 glyph
->object
= it
->object
;
1427 glyph
->pixel_width
= it
->pixel_width
;
1428 glyph
->voffset
= it
->voffset
;
1429 glyph
->type
= CHAR_GLYPH
;
1430 glyph
->multibyte_p
= it
->multibyte_p
;
1431 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1432 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1433 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1434 || it
->phys_descent
> it
->descent
);
1435 glyph
->padding_p
= 0;
1436 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1437 glyph
->face_id
= it
->face_id
;
1438 glyph
->u
.ch
= it
->char_to_display
;
1439 ++it
->glyph_row
->used
[area
];
1443 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1444 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1447 x_append_composite_glyph (it
)
1450 struct glyph
*glyph
;
1451 enum glyph_row_area area
= it
->area
;
1453 xassert (it
->glyph_row
);
1455 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1456 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1458 glyph
->charpos
= CHARPOS (it
->position
);
1459 glyph
->object
= it
->object
;
1460 glyph
->pixel_width
= it
->pixel_width
;
1461 glyph
->voffset
= it
->voffset
;
1462 glyph
->type
= COMPOSITE_GLYPH
;
1463 glyph
->multibyte_p
= it
->multibyte_p
;
1464 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1465 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1466 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1467 || it
->phys_descent
> it
->descent
);
1468 glyph
->padding_p
= 0;
1469 glyph
->glyph_not_available_p
= 0;
1470 glyph
->face_id
= it
->face_id
;
1471 glyph
->u
.cmp_id
= it
->cmp_id
;
1472 ++it
->glyph_row
->used
[area
];
1477 /* Change IT->ascent and IT->height according to the setting of
1481 take_vertical_position_into_account (it
)
1486 if (it
->voffset
< 0)
1487 /* Increase the ascent so that we can display the text higher
1489 it
->ascent
+= abs (it
->voffset
);
1491 /* Increase the descent so that we can display the text lower
1493 it
->descent
+= it
->voffset
;
1498 /* Produce glyphs/get display metrics for the image IT is loaded with.
1499 See the description of struct display_iterator in dispextern.h for
1500 an overview of struct display_iterator. */
1503 x_produce_image_glyph (it
)
1509 xassert (it
->what
== IT_IMAGE
);
1511 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1512 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1515 /* Make sure X resources of the face and image are loaded. */
1516 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1517 prepare_image_for_display (it
->f
, img
);
1519 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1520 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1521 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1525 if (face
->box
!= FACE_NO_BOX
)
1527 it
->ascent
+= face
->box_line_width
;
1528 it
->descent
+= face
->box_line_width
;
1530 if (it
->start_of_box_run_p
)
1531 it
->pixel_width
+= face
->box_line_width
;
1532 if (it
->end_of_box_run_p
)
1533 it
->pixel_width
+= face
->box_line_width
;
1536 take_vertical_position_into_account (it
);
1540 struct glyph
*glyph
;
1541 enum glyph_row_area area
= it
->area
;
1543 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1544 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1546 glyph
->charpos
= CHARPOS (it
->position
);
1547 glyph
->object
= it
->object
;
1548 glyph
->pixel_width
= it
->pixel_width
;
1549 glyph
->voffset
= it
->voffset
;
1550 glyph
->type
= IMAGE_GLYPH
;
1551 glyph
->multibyte_p
= it
->multibyte_p
;
1552 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1553 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1554 glyph
->overlaps_vertically_p
= 0;
1555 glyph
->padding_p
= 0;
1556 glyph
->glyph_not_available_p
= 0;
1557 glyph
->face_id
= it
->face_id
;
1558 glyph
->u
.img_id
= img
->id
;
1559 ++it
->glyph_row
->used
[area
];
1565 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1566 of the glyph, WIDTH and HEIGHT are the width and height of the
1567 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1568 ascent of the glyph (0 <= ASCENT <= 1). */
1571 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1577 struct glyph
*glyph
;
1578 enum glyph_row_area area
= it
->area
;
1580 xassert (ascent
>= 0 && ascent
<= 1);
1582 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1583 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1585 glyph
->charpos
= CHARPOS (it
->position
);
1586 glyph
->object
= object
;
1587 glyph
->pixel_width
= width
;
1588 glyph
->voffset
= it
->voffset
;
1589 glyph
->type
= STRETCH_GLYPH
;
1590 glyph
->multibyte_p
= it
->multibyte_p
;
1591 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1592 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1593 glyph
->overlaps_vertically_p
= 0;
1594 glyph
->padding_p
= 0;
1595 glyph
->glyph_not_available_p
= 0;
1596 glyph
->face_id
= it
->face_id
;
1597 glyph
->u
.stretch
.ascent
= height
* ascent
;
1598 glyph
->u
.stretch
.height
= height
;
1599 ++it
->glyph_row
->used
[area
];
1604 /* Produce a stretch glyph for iterator IT. IT->object is the value
1605 of the glyph property displayed. The value must be a list
1606 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1609 1. `:width WIDTH' specifies that the space should be WIDTH *
1610 canonical char width wide. WIDTH may be an integer or floating
1613 2. `:relative-width FACTOR' specifies that the width of the stretch
1614 should be computed from the width of the first character having the
1615 `glyph' property, and should be FACTOR times that width.
1617 3. `:align-to HPOS' specifies that the space should be wide enough
1618 to reach HPOS, a value in canonical character units.
1620 Exactly one of the above pairs must be present.
1622 4. `:height HEIGHT' specifies that the height of the stretch produced
1623 should be HEIGHT, measured in canonical character units.
1625 5. `:relative-height FACTOR' specifies that the height of the the
1626 stretch should be FACTOR times the height of the characters having
1629 Either none or exactly one of 4 or 5 must be present.
1631 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1632 of the stretch should be used for the ascent of the stretch.
1633 ASCENT must be in the range 0 <= ASCENT <= 100. */
1636 ((INTEGERP (X) || FLOATP (X)) \
1642 x_produce_stretch_glyph (it
)
1645 /* (space :width WIDTH :height HEIGHT. */
1647 extern Lisp_Object Qspace
;
1649 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1650 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1651 extern Lisp_Object QCalign_to
;
1652 Lisp_Object prop
, plist
;
1653 double width
= 0, height
= 0, ascent
= 0;
1654 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1655 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1657 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1659 /* List should start with `space'. */
1660 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1661 plist
= XCDR (it
->object
);
1663 /* Compute the width of the stretch. */
1664 if (prop
= Fplist_get (plist
, QCwidth
),
1666 /* Absolute width `:width WIDTH' specified and valid. */
1667 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1668 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1671 /* Relative width `:relative-width FACTOR' specified and valid.
1672 Compute the width of the characters having the `glyph'
1675 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1678 if (it
->multibyte_p
)
1680 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1681 - IT_BYTEPOS (*it
));
1682 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1685 it2
.c
= *p
, it2
.len
= 1;
1687 it2
.glyph_row
= NULL
;
1688 it2
.what
= IT_CHARACTER
;
1689 x_produce_glyphs (&it2
);
1690 width
= NUMVAL (prop
) * it2
.pixel_width
;
1692 else if (prop
= Fplist_get (plist
, QCalign_to
),
1694 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1696 /* Nothing specified -> width defaults to canonical char width. */
1697 width
= CANON_X_UNIT (it
->f
);
1699 /* Compute height. */
1700 if (prop
= Fplist_get (plist
, QCheight
),
1702 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1703 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1705 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1707 height
= FONT_HEIGHT (font
);
1709 /* Compute percentage of height used for ascent. If
1710 `:ascent ASCENT' is present and valid, use that. Otherwise,
1711 derive the ascent from the font in use. */
1712 if (prop
= Fplist_get (plist
, QCascent
),
1713 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1714 ascent
= NUMVAL (prop
) / 100.0;
1716 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1725 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1726 if (!STRINGP (object
))
1727 object
= it
->w
->buffer
;
1728 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1731 it
->pixel_width
= width
;
1732 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1733 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1736 if (face
->box
!= FACE_NO_BOX
)
1738 it
->ascent
+= face
->box_line_width
;
1739 it
->descent
+= face
->box_line_width
;
1741 if (it
->start_of_box_run_p
)
1742 it
->pixel_width
+= face
->box_line_width
;
1743 if (it
->end_of_box_run_p
)
1744 it
->pixel_width
+= face
->box_line_width
;
1747 take_vertical_position_into_account (it
);
1750 /* Return proper value to be used as baseline offset of font that has
1751 ASCENT and DESCENT to draw characters by the font at the vertical
1752 center of the line of frame F.
1754 Here, out task is to find the value of BOFF in the following figure;
1756 -------------------------+-----------+-
1757 -+-+---------+-+ | |
1759 | | | | F_ASCENT F_HEIGHT
1762 | | |-|-+------+-----------|------- baseline
1764 | |---------|-+-+ | |
1766 -+-+---------+-+ F_DESCENT |
1767 -------------------------+-----------+-
1769 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1770 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1771 DESCENT = FONT->descent
1772 HEIGHT = FONT_HEIGHT (FONT)
1773 F_DESCENT = (F->output_data.x->font->descent
1774 - F->output_data.x->baseline_offset)
1775 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1778 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1780 + (FRAME_LINE_HEIGHT ((F)) + 1 - FONT_HEIGHT ((FONT))) / 2 \
1781 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1783 /* Produce glyphs/get display metrics for the display element IT is
1784 loaded with. See the description of struct display_iterator in
1785 dispextern.h for an overview of struct display_iterator. */
1788 x_produce_glyphs (it
)
1791 it
->glyph_not_available_p
= 0;
1793 if (it
->what
== IT_CHARACTER
)
1797 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1799 int font_not_found_p
;
1800 struct font_info
*font_info
;
1801 int boff
; /* baseline offset */
1802 /* We may change it->multibyte_p upon unibyte<->multibyte
1803 conversion. So, save the current value now and restore it
1806 Note: It seems that we don't have to record multibyte_p in
1807 struct glyph because the character code itself tells if or
1808 not the character is multibyte. Thus, in the future, we must
1809 consider eliminating the field `multibyte_p' in the struct
1812 int saved_multibyte_p
= it
->multibyte_p
;
1814 /* Maybe translate single-byte characters to multibyte, or the
1816 it
->char_to_display
= it
->c
;
1817 if (!ASCII_BYTE_P (it
->c
))
1819 if (unibyte_display_via_language_environment
1820 && SINGLE_BYTE_CHAR_P (it
->c
)
1822 || !NILP (Vnonascii_translation_table
)))
1824 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1825 it
->multibyte_p
= 1;
1826 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1827 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1829 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1830 && !it
->multibyte_p
)
1832 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1833 it
->multibyte_p
= 0;
1834 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1835 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1839 /* Get font to use. Encode IT->char_to_display. */
1840 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1841 it
->face_id
, &char2b
,
1845 /* When no suitable font found, use the default font. */
1846 font_not_found_p
= font
== NULL
;
1847 if (font_not_found_p
)
1849 font
= FRAME_FONT (it
->f
);
1850 boff
= it
->f
->output_data
.x
->baseline_offset
;
1855 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1856 boff
= font_info
->baseline_offset
;
1857 if (font_info
->vertical_centering
)
1858 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1861 if (it
->char_to_display
>= ' '
1862 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1864 /* Either unibyte or ASCII. */
1869 pcm
= x_per_char_metric (font
, &char2b
);
1870 it
->ascent
= font
->ascent
+ boff
;
1871 it
->descent
= font
->descent
- boff
;
1875 it
->phys_ascent
= pcm
->ascent
+ boff
;
1876 it
->phys_descent
= pcm
->descent
- boff
;
1877 it
->pixel_width
= pcm
->width
;
1881 it
->glyph_not_available_p
= 1;
1882 it
->phys_ascent
= font
->ascent
+ boff
;
1883 it
->phys_descent
= font
->descent
- boff
;
1884 it
->pixel_width
= FONT_WIDTH (font
);
1887 /* If this is a space inside a region of text with
1888 `space-width' property, change its width. */
1889 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1891 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1893 /* If face has a box, add the box thickness to the character
1894 height. If character has a box line to the left and/or
1895 right, add the box line width to the character's width. */
1896 if (face
->box
!= FACE_NO_BOX
)
1898 int thick
= face
->box_line_width
;
1900 it
->ascent
+= thick
;
1901 it
->descent
+= thick
;
1903 if (it
->start_of_box_run_p
)
1904 it
->pixel_width
+= thick
;
1905 if (it
->end_of_box_run_p
)
1906 it
->pixel_width
+= thick
;
1909 /* If face has an overline, add the height of the overline
1910 (1 pixel) and a 1 pixel margin to the character height. */
1911 if (face
->overline_p
)
1914 take_vertical_position_into_account (it
);
1916 /* If we have to actually produce glyphs, do it. */
1921 /* Translate a space with a `space-width' property
1922 into a stretch glyph. */
1923 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1924 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1925 it
->ascent
+ it
->descent
, ascent
);
1928 x_append_glyph (it
);
1930 /* If characters with lbearing or rbearing are displayed
1931 in this line, record that fact in a flag of the
1932 glyph row. This is used to optimize X output code. */
1933 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1934 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1937 else if (it
->char_to_display
== '\n')
1939 /* A newline has no width but we need the height of the line. */
1940 it
->pixel_width
= 0;
1942 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1943 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1945 if (face
->box
!= FACE_NO_BOX
)
1947 int thick
= face
->box_line_width
;
1948 it
->ascent
+= thick
;
1949 it
->descent
+= thick
;
1952 else if (it
->char_to_display
== '\t')
1954 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1955 int x
= it
->current_x
+ it
->continuation_lines_width
;
1956 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1958 /* If the distance from the current position to the next tab
1959 stop is less than a canonical character width, use the
1960 tab stop after that. */
1961 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1962 next_tab_x
+= tab_width
;
1964 it
->pixel_width
= next_tab_x
- x
;
1966 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1967 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1971 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1972 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1973 it
->ascent
+ it
->descent
, ascent
);
1978 /* A multi-byte character. Assume that the display width of the
1979 character is the width of the character multiplied by the
1980 width of the font. */
1982 /* If we found a font, this font should give us the right
1983 metrics. If we didn't find a font, use the frame's
1984 default font and calculate the width of the character
1985 from the charset width; this is what old redisplay code
1987 pcm
= x_per_char_metric (font
, &char2b
);
1988 if (font_not_found_p
|| !pcm
)
1990 int charset
= CHAR_CHARSET (it
->char_to_display
);
1992 it
->glyph_not_available_p
= 1;
1993 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
1994 * CHARSET_WIDTH (charset
));
1995 it
->phys_ascent
= font
->ascent
+ boff
;
1996 it
->phys_descent
= font
->descent
- boff
;
2000 it
->pixel_width
= pcm
->width
;
2001 it
->phys_ascent
= pcm
->ascent
+ boff
;
2002 it
->phys_descent
= pcm
->descent
- boff
;
2004 && (pcm
->lbearing
< 0
2005 || pcm
->rbearing
> pcm
->width
))
2006 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2009 it
->ascent
= font
->ascent
+ boff
;
2010 it
->descent
= font
->descent
- boff
;
2011 if (face
->box
!= FACE_NO_BOX
)
2013 int thick
= face
->box_line_width
;
2014 it
->ascent
+= thick
;
2015 it
->descent
+= thick
;
2017 if (it
->start_of_box_run_p
)
2018 it
->pixel_width
+= thick
;
2019 if (it
->end_of_box_run_p
)
2020 it
->pixel_width
+= thick
;
2023 /* If face has an overline, add the height of the overline
2024 (1 pixel) and a 1 pixel margin to the character height. */
2025 if (face
->overline_p
)
2028 take_vertical_position_into_account (it
);
2031 x_append_glyph (it
);
2033 it
->multibyte_p
= saved_multibyte_p
;
2035 else if (it
->what
== IT_COMPOSITION
)
2037 /* Note: A composition is represented as one glyph in the
2038 glyph matrix. There are no padding glyphs. */
2041 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2043 int font_not_found_p
;
2044 struct font_info
*font_info
;
2045 int boff
; /* baseline offset */
2046 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2048 /* Maybe translate single-byte characters to multibyte. */
2049 it
->char_to_display
= it
->c
;
2050 if (unibyte_display_via_language_environment
2051 && SINGLE_BYTE_CHAR_P (it
->c
)
2054 && !NILP (Vnonascii_translation_table
))))
2056 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2059 /* Get face and font to use. Encode IT->char_to_display. */
2060 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2061 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2062 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2063 it
->face_id
, &char2b
, it
->multibyte_p
);
2066 /* When no suitable font found, use the default font. */
2067 font_not_found_p
= font
== NULL
;
2068 if (font_not_found_p
)
2070 font
= FRAME_FONT (it
->f
);
2071 boff
= it
->f
->output_data
.x
->baseline_offset
;
2076 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2077 boff
= font_info
->baseline_offset
;
2078 if (font_info
->vertical_centering
)
2079 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2082 /* There are no padding glyphs, so there is only one glyph to
2083 produce for the composition. Important is that pixel_width,
2084 ascent and descent are the values of what is drawn by
2085 draw_glyphs (i.e. the values of the overall glyphs composed). */
2088 /* If we have not yet calculated pixel size data of glyphs of
2089 the composition for the current face font, calculate them
2090 now. Theoretically, we have to check all fonts for the
2091 glyphs, but that requires much time and memory space. So,
2092 here we check only the font of the first glyph. This leads
2093 to incorrect display very rarely, and C-l (recenter) can
2094 correct the display anyway. */
2095 if (cmp
->font
!= (void *) font
)
2097 /* Ascent and descent of the font of the first character of
2098 this composition (adjusted by baseline offset). Ascent
2099 and descent of overall glyphs should not be less than
2100 them respectively. */
2101 int font_ascent
= font
->ascent
+ boff
;
2102 int font_descent
= font
->descent
- boff
;
2103 /* Bounding box of the overall glyphs. */
2104 int leftmost
, rightmost
, lowest
, highest
;
2105 int i
, width
, ascent
, descent
;
2107 cmp
->font
= (void *) font
;
2109 /* Initialize the bounding box. */
2110 pcm
= x_per_char_metric (font
, &char2b
);
2114 ascent
= pcm
->ascent
;
2115 descent
= pcm
->descent
;
2119 width
= FONT_WIDTH (font
);
2120 ascent
= font
->ascent
;
2121 descent
= font
->descent
;
2125 lowest
= - descent
+ boff
;
2126 highest
= ascent
+ boff
;
2130 && font_info
->default_ascent
2131 && CHAR_TABLE_P (Vuse_default_ascent
)
2132 && !NILP (Faref (Vuse_default_ascent
,
2133 make_number (it
->char_to_display
))))
2134 highest
= font_info
->default_ascent
+ boff
;
2136 /* Draw the first glyph at the normal position. It may be
2137 shifted to right later if some other glyphs are drawn at
2139 cmp
->offsets
[0] = 0;
2140 cmp
->offsets
[1] = boff
;
2142 /* Set cmp->offsets for the remaining glyphs. */
2143 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2145 int left
, right
, btm
, top
;
2146 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2147 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2149 face
= FACE_FROM_ID (it
->f
, face_id
);
2150 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2155 font
= FRAME_FONT (it
->f
);
2156 boff
= it
->f
->output_data
.x
->baseline_offset
;
2162 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2163 boff
= font_info
->baseline_offset
;
2164 if (font_info
->vertical_centering
)
2165 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2168 pcm
= x_per_char_metric (font
, &char2b
);
2172 ascent
= pcm
->ascent
;
2173 descent
= pcm
->descent
;
2177 width
= FONT_WIDTH (font
);
2178 ascent
= font
->ascent
;
2179 descent
= font
->descent
;
2182 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2184 /* Relative composition with or without
2186 left
= (leftmost
+ rightmost
- width
) / 2;
2187 btm
= - descent
+ boff
;
2188 if (font_info
&& font_info
->relative_compose
2189 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2190 || NILP (Faref (Vignore_relative_composition
,
2191 make_number (ch
)))))
2194 if (- descent
>= font_info
->relative_compose
)
2195 /* One extra pixel between two glyphs. */
2197 else if (ascent
<= 0)
2198 /* One extra pixel between two glyphs. */
2199 btm
= lowest
- 1 - ascent
- descent
;
2204 /* A composition rule is specified by an integer
2205 value that encodes global and new reference
2206 points (GREF and NREF). GREF and NREF are
2207 specified by numbers as below:
2215 ---3---4---5--- baseline
2217 6---7---8 -- descent
2219 int rule
= COMPOSITION_RULE (cmp
, i
);
2220 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2222 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2223 grefx
= gref
% 3, nrefx
= nref
% 3;
2224 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2227 + grefx
* (rightmost
- leftmost
) / 2
2228 - nrefx
* width
/ 2);
2229 btm
= ((grefy
== 0 ? highest
2231 : grefy
== 2 ? lowest
2232 : (highest
+ lowest
) / 2)
2233 - (nrefy
== 0 ? ascent
+ descent
2234 : nrefy
== 1 ? descent
- boff
2236 : (ascent
+ descent
) / 2));
2239 cmp
->offsets
[i
* 2] = left
;
2240 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2242 /* Update the bounding box of the overall glyphs. */
2243 right
= left
+ width
;
2244 top
= btm
+ descent
+ ascent
;
2245 if (left
< leftmost
)
2247 if (right
> rightmost
)
2255 /* If there are glyphs whose x-offsets are negative,
2256 shift all glyphs to the right and make all x-offsets
2260 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2261 cmp
->offsets
[i
* 2] -= leftmost
;
2262 rightmost
-= leftmost
;
2265 cmp
->pixel_width
= rightmost
;
2266 cmp
->ascent
= highest
;
2267 cmp
->descent
= - lowest
;
2268 if (cmp
->ascent
< font_ascent
)
2269 cmp
->ascent
= font_ascent
;
2270 if (cmp
->descent
< font_descent
)
2271 cmp
->descent
= font_descent
;
2274 it
->pixel_width
= cmp
->pixel_width
;
2275 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2276 it
->descent
= it
->phys_descent
= cmp
->descent
;
2278 if (face
->box
!= FACE_NO_BOX
)
2280 int thick
= face
->box_line_width
;
2281 it
->ascent
+= thick
;
2282 it
->descent
+= thick
;
2284 if (it
->start_of_box_run_p
)
2285 it
->pixel_width
+= thick
;
2286 if (it
->end_of_box_run_p
)
2287 it
->pixel_width
+= thick
;
2290 /* If face has an overline, add the height of the overline
2291 (1 pixel) and a 1 pixel margin to the character height. */
2292 if (face
->overline_p
)
2295 take_vertical_position_into_account (it
);
2298 x_append_composite_glyph (it
);
2300 else if (it
->what
== IT_IMAGE
)
2301 x_produce_image_glyph (it
);
2302 else if (it
->what
== IT_STRETCH
)
2303 x_produce_stretch_glyph (it
);
2305 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2306 because this isn't true for images with `:ascent 100'. */
2307 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2308 if (it
->area
== TEXT_AREA
)
2309 it
->current_x
+= it
->pixel_width
;
2311 it
->descent
+= it
->extra_line_spacing
;
2313 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2314 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2315 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2316 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2320 /* Estimate the pixel height of the mode or top line on frame F.
2321 FACE_ID specifies what line's height to estimate. */
2324 x_estimate_mode_line_height (f
, face_id
)
2326 enum face_id face_id
;
2330 /* This function is called so early when Emacs starts that the face
2331 cache and mode line face are not yet initialized. */
2332 if (FRAME_FACE_CACHE (f
))
2334 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2336 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2343 /***********************************************************************
2345 ***********************************************************************/
2347 /* A sequence of glyphs to be drawn in the same face.
2349 This data structure is not really completely X specific, so it
2350 could possibly, at least partially, be useful for other systems. It
2351 is currently not part of the external redisplay interface because
2352 it's not clear what other systems will need. */
2356 /* X-origin of the string. */
2359 /* Y-origin and y-position of the base line of this string. */
2362 /* The width of the string, not including a face extension. */
2365 /* The width of the string, including a face extension. */
2366 int background_width
;
2368 /* The height of this string. This is the height of the line this
2369 string is drawn in, and can be different from the height of the
2370 font the string is drawn in. */
2373 /* Number of pixels this string overwrites in front of its x-origin.
2374 This number is zero if the string has an lbearing >= 0; it is
2375 -lbearing, if the string has an lbearing < 0. */
2378 /* Number of pixels this string overwrites past its right-most
2379 nominal x-position, i.e. x + width. Zero if the string's
2380 rbearing is <= its nominal width, rbearing - width otherwise. */
2383 /* The frame on which the glyph string is drawn. */
2386 /* The window on which the glyph string is drawn. */
2389 /* X display and window for convenience. */
2393 /* The glyph row for which this string was built. It determines the
2394 y-origin and height of the string. */
2395 struct glyph_row
*row
;
2397 /* The area within row. */
2398 enum glyph_row_area area
;
2400 /* Characters to be drawn, and number of characters. */
2404 /* A face-override for drawing cursors, mouse face and similar. */
2405 enum draw_glyphs_face hl
;
2407 /* Face in which this string is to be drawn. */
2410 /* Font in which this string is to be drawn. */
2413 /* Font info for this string. */
2414 struct font_info
*font_info
;
2416 /* Non-null means this string describes (part of) a composition.
2417 All characters from char2b are drawn composed. */
2418 struct composition
*cmp
;
2420 /* Index of this glyph string's first character in the glyph
2421 definition of CMP. If this is zero, this glyph string describes
2422 the first character of a composition. */
2425 /* 1 means this glyph strings face has to be drawn to the right end
2426 of the window's drawing area. */
2427 unsigned extends_to_end_of_line_p
: 1;
2429 /* 1 means the background of this string has been drawn. */
2430 unsigned background_filled_p
: 1;
2432 /* 1 means glyph string must be drawn with 16-bit functions. */
2433 unsigned two_byte_p
: 1;
2435 /* 1 means that the original font determined for drawing this glyph
2436 string could not be loaded. The member `font' has been set to
2437 the frame's default font in this case. */
2438 unsigned font_not_found_p
: 1;
2440 /* 1 means that the face in which this glyph string is drawn has a
2442 unsigned stippled_p
: 1;
2444 /* 1 means only the foreground of this glyph string must be drawn,
2445 and we should use the physical height of the line this glyph
2446 string appears in as clip rect. */
2447 unsigned for_overlaps_p
: 1;
2449 /* The GC to use for drawing this glyph string. */
2452 /* A pointer to the first glyph in the string. This glyph
2453 corresponds to char2b[0]. Needed to draw rectangles if
2454 font_not_found_p is 1. */
2455 struct glyph
*first_glyph
;
2457 /* Image, if any. */
2460 struct glyph_string
*next
, *prev
;
2467 x_dump_glyph_string (s
)
2468 struct glyph_string
*s
;
2470 fprintf (stderr
, "glyph string\n");
2471 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2472 s
->x
, s
->y
, s
->width
, s
->height
);
2473 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2474 fprintf (stderr
, " hl = %d\n", s
->hl
);
2475 fprintf (stderr
, " left overhang = %d, right = %d\n",
2476 s
->left_overhang
, s
->right_overhang
);
2477 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2478 fprintf (stderr
, " extends to end of line = %d\n",
2479 s
->extends_to_end_of_line_p
);
2480 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2481 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2484 #endif /* GLYPH_DEBUG */
2488 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2489 struct glyph_string
**,
2490 struct glyph_string
*,
2491 struct glyph_string
*));
2492 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2493 struct glyph_string
**,
2494 struct glyph_string
*,
2495 struct glyph_string
*));
2496 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2497 struct glyph_string
**,
2498 struct glyph_string
*));
2499 static int x_left_overwritten
P_ ((struct glyph_string
*));
2500 static int x_left_overwriting
P_ ((struct glyph_string
*));
2501 static int x_right_overwritten
P_ ((struct glyph_string
*));
2502 static int x_right_overwriting
P_ ((struct glyph_string
*));
2503 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2505 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2506 XChar2b
*, struct window
*,
2508 enum glyph_row_area
, int,
2509 enum draw_glyphs_face
));
2510 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2511 enum glyph_row_area
, int, int,
2512 enum draw_glyphs_face
, int *, int *, int));
2513 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2514 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2515 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2517 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2518 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2519 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2520 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2521 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2522 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2523 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2524 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2525 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2527 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2528 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2529 unsigned long *, double, int));
2530 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2531 double, int, unsigned long));
2532 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2533 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2534 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2535 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2536 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2537 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2538 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2540 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2541 int, int, int, int, XRectangle
*));
2542 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2543 int, int, int, XRectangle
*));
2544 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2545 enum glyph_row_area
));
2546 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2548 enum glyph_row_area
, int, int));
2551 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2555 /* Append the list of glyph strings with head H and tail T to the list
2556 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2559 x_append_glyph_string_lists (head
, tail
, h
, t
)
2560 struct glyph_string
**head
, **tail
;
2561 struct glyph_string
*h
, *t
;
2575 /* Prepend the list of glyph strings with head H and tail T to the
2576 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2580 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2581 struct glyph_string
**head
, **tail
;
2582 struct glyph_string
*h
, *t
;
2596 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2597 Set *HEAD and *TAIL to the resulting list. */
2600 x_append_glyph_string (head
, tail
, s
)
2601 struct glyph_string
**head
, **tail
;
2602 struct glyph_string
*s
;
2604 s
->next
= s
->prev
= NULL
;
2605 x_append_glyph_string_lists (head
, tail
, s
, s
);
2609 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2614 struct glyph_string
*s
;
2616 if (s
->font
== FRAME_FONT (s
->f
)
2617 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2618 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2620 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2623 /* Cursor on non-default face: must merge. */
2627 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2628 xgcv
.foreground
= s
->face
->background
;
2630 /* If the glyph would be invisible, try a different foreground. */
2631 if (xgcv
.foreground
== xgcv
.background
)
2632 xgcv
.foreground
= s
->face
->foreground
;
2633 if (xgcv
.foreground
== xgcv
.background
)
2634 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2635 if (xgcv
.foreground
== xgcv
.background
)
2636 xgcv
.foreground
= s
->face
->foreground
;
2638 /* Make sure the cursor is distinct from text in this face. */
2639 if (xgcv
.background
== s
->face
->background
2640 && xgcv
.foreground
== s
->face
->foreground
)
2642 xgcv
.background
= s
->face
->foreground
;
2643 xgcv
.foreground
= s
->face
->background
;
2646 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2647 xgcv
.font
= s
->font
->fid
;
2648 xgcv
.graphics_exposures
= False
;
2649 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2651 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2652 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2655 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2656 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2658 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2663 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2666 x_set_mouse_face_gc (s
)
2667 struct glyph_string
*s
;
2672 /* What face has to be used for the mouse face? */
2673 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2674 face
= FACE_FROM_ID (s
->f
, face_id
);
2675 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2676 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2678 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2679 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2680 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2682 /* If font in this face is same as S->font, use it. */
2683 if (s
->font
== s
->face
->font
)
2684 s
->gc
= s
->face
->gc
;
2687 /* Otherwise construct scratch_cursor_gc with values from FACE
2692 xgcv
.background
= s
->face
->background
;
2693 xgcv
.foreground
= s
->face
->foreground
;
2694 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2695 xgcv
.font
= s
->font
->fid
;
2696 xgcv
.graphics_exposures
= False
;
2697 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2699 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2700 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2703 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2704 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2706 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2709 xassert (s
->gc
!= 0);
2713 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2714 Faces to use in the mode line have already been computed when the
2715 matrix was built, so there isn't much to do, here. */
2718 x_set_mode_line_face_gc (s
)
2719 struct glyph_string
*s
;
2721 s
->gc
= s
->face
->gc
;
2725 /* Set S->gc of glyph string S for drawing that glyph string. Set
2726 S->stippled_p to a non-zero value if the face of S has a stipple
2730 x_set_glyph_string_gc (s
)
2731 struct glyph_string
*s
;
2733 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2735 if (s
->hl
== DRAW_NORMAL_TEXT
)
2737 s
->gc
= s
->face
->gc
;
2738 s
->stippled_p
= s
->face
->stipple
!= 0;
2740 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2742 x_set_mode_line_face_gc (s
);
2743 s
->stippled_p
= s
->face
->stipple
!= 0;
2745 else if (s
->hl
== DRAW_CURSOR
)
2747 x_set_cursor_gc (s
);
2750 else if (s
->hl
== DRAW_MOUSE_FACE
)
2752 x_set_mouse_face_gc (s
);
2753 s
->stippled_p
= s
->face
->stipple
!= 0;
2755 else if (s
->hl
== DRAW_IMAGE_RAISED
2756 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2758 s
->gc
= s
->face
->gc
;
2759 s
->stippled_p
= s
->face
->stipple
!= 0;
2763 s
->gc
= s
->face
->gc
;
2764 s
->stippled_p
= s
->face
->stipple
!= 0;
2767 /* GC must have been set. */
2768 xassert (s
->gc
!= 0);
2772 /* Return in *R the clipping rectangle for glyph string S. */
2775 x_get_glyph_string_clip_rect (s
, r
)
2776 struct glyph_string
*s
;
2779 if (s
->row
->full_width_p
)
2781 /* Draw full-width. X coordinates are relative to S->w->left. */
2782 int canon_x
= CANON_X_UNIT (s
->f
);
2784 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2785 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2787 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2789 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2790 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2794 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2796 /* Unless displaying a mode or menu bar line, which are always
2797 fully visible, clip to the visible part of the row. */
2798 if (s
->w
->pseudo_window_p
)
2799 r
->height
= s
->row
->visible_height
;
2801 r
->height
= s
->height
;
2805 /* This is a text line that may be partially visible. */
2806 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2807 r
->width
= window_box_width (s
->w
, s
->area
);
2808 r
->height
= s
->row
->visible_height
;
2811 /* Don't use S->y for clipping because it doesn't take partially
2812 visible lines into account. For example, it can be negative for
2813 partially visible lines at the top of a window. */
2814 if (!s
->row
->full_width_p
2815 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2816 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2818 r
->y
= max (0, s
->row
->y
);
2820 /* If drawing a tool-bar window, draw it over the internal border
2821 at the top of the window. */
2822 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2823 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2825 /* If S draws overlapping rows, it's sufficient to use the top and
2826 bottom of the window for clipping because this glyph string
2827 intentionally draws over other lines. */
2828 if (s
->for_overlaps_p
)
2830 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2831 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2834 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2838 /* Set clipping for output of glyph string S. S may be part of a mode
2839 line or menu if we don't have X toolkit support. */
2842 x_set_glyph_string_clipping (s
)
2843 struct glyph_string
*s
;
2846 x_get_glyph_string_clip_rect (s
, &r
);
2847 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2851 /* Compute left and right overhang of glyph string S. If S is a glyph
2852 string for a composition, assume overhangs don't exist. */
2855 x_compute_glyph_string_overhangs (s
)
2856 struct glyph_string
*s
;
2859 && s
->first_glyph
->type
== CHAR_GLYPH
)
2862 int direction
, font_ascent
, font_descent
;
2863 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2864 &font_ascent
, &font_descent
, &cs
);
2865 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2866 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2871 /* Compute overhangs and x-positions for glyph string S and its
2872 predecessors, or successors. X is the starting x-position for S.
2873 BACKWARD_P non-zero means process predecessors. */
2876 x_compute_overhangs_and_x (s
, x
, backward_p
)
2877 struct glyph_string
*s
;
2885 x_compute_glyph_string_overhangs (s
);
2895 x_compute_glyph_string_overhangs (s
);
2904 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2905 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2906 assumed to be zero. */
2909 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2910 struct glyph
*glyph
;
2916 if (glyph
->type
== CHAR_GLYPH
)
2920 struct font_info
*font_info
;
2924 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2926 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2928 && (pcm
= x_per_char_metric (font
, &char2b
)))
2930 if (pcm
->rbearing
> pcm
->width
)
2931 *right
= pcm
->rbearing
- pcm
->width
;
2932 if (pcm
->lbearing
< 0)
2933 *left
= -pcm
->lbearing
;
2939 /* Return the index of the first glyph preceding glyph string S that
2940 is overwritten by S because of S's left overhang. Value is -1
2941 if no glyphs are overwritten. */
2944 x_left_overwritten (s
)
2945 struct glyph_string
*s
;
2949 if (s
->left_overhang
)
2952 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2953 int first
= s
->first_glyph
- glyphs
;
2955 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2956 x
-= glyphs
[i
].pixel_width
;
2967 /* Return the index of the first glyph preceding glyph string S that
2968 is overwriting S because of its right overhang. Value is -1 if no
2969 glyph in front of S overwrites S. */
2972 x_left_overwriting (s
)
2973 struct glyph_string
*s
;
2976 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2977 int first
= s
->first_glyph
- glyphs
;
2981 for (i
= first
- 1; i
>= 0; --i
)
2984 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
2987 x
-= glyphs
[i
].pixel_width
;
2994 /* Return the index of the last glyph following glyph string S that is
2995 not overwritten by S because of S's right overhang. Value is -1 if
2996 no such glyph is found. */
2999 x_right_overwritten (s
)
3000 struct glyph_string
*s
;
3004 if (s
->right_overhang
)
3007 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3008 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3009 int end
= s
->row
->used
[s
->area
];
3011 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3012 x
+= glyphs
[i
].pixel_width
;
3021 /* Return the index of the last glyph following glyph string S that
3022 overwrites S because of its left overhang. Value is negative
3023 if no such glyph is found. */
3026 x_right_overwriting (s
)
3027 struct glyph_string
*s
;
3030 int end
= s
->row
->used
[s
->area
];
3031 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3032 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3036 for (i
= first
; i
< end
; ++i
)
3039 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3042 x
+= glyphs
[i
].pixel_width
;
3049 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3052 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3053 struct glyph_string
*s
;
3057 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3058 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3059 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3060 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3064 /* Draw the background of glyph_string S. If S->background_filled_p
3065 is non-zero don't draw it. FORCE_P non-zero means draw the
3066 background even if it wouldn't be drawn normally. This is used
3067 when a string preceding S draws into the background of S, or S
3068 contains the first component of a composition. */
3071 x_draw_glyph_string_background (s
, force_p
)
3072 struct glyph_string
*s
;
3075 /* Nothing to do if background has already been drawn or if it
3076 shouldn't be drawn in the first place. */
3077 if (!s
->background_filled_p
)
3081 /* Fill background with a stipple pattern. */
3082 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3083 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3084 s
->y
+ s
->face
->box_line_width
,
3085 s
->background_width
,
3086 s
->height
- 2 * s
->face
->box_line_width
);
3087 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3088 s
->background_filled_p
= 1;
3090 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
3091 || s
->font_not_found_p
3092 || s
->extends_to_end_of_line_p
3095 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
3096 s
->background_width
,
3097 s
->height
- 2 * s
->face
->box_line_width
);
3098 s
->background_filled_p
= 1;
3104 /* Draw the foreground of glyph string S. */
3107 x_draw_glyph_string_foreground (s
)
3108 struct glyph_string
*s
;
3112 /* If first glyph of S has a left box line, start drawing the text
3113 of S to the right of that box line. */
3114 if (s
->face
->box
!= FACE_NO_BOX
3115 && s
->first_glyph
->left_box_line_p
)
3116 x
= s
->x
+ s
->face
->box_line_width
;
3120 /* Draw characters of S as rectangles if S's font could not be
3122 if (s
->font_not_found_p
)
3124 for (i
= 0; i
< s
->nchars
; ++i
)
3126 struct glyph
*g
= s
->first_glyph
+ i
;
3127 XDrawRectangle (s
->display
, s
->window
,
3128 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3130 x
+= g
->pixel_width
;
3135 char *char1b
= (char *) s
->char2b
;
3136 int boff
= s
->font_info
->baseline_offset
;
3138 if (s
->font_info
->vertical_centering
)
3139 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3141 /* If we can use 8-bit functions, condense S->char2b. */
3143 for (i
= 0; i
< s
->nchars
; ++i
)
3144 char1b
[i
] = s
->char2b
[i
].byte2
;
3146 /* Draw text with XDrawString if background has already been
3147 filled. Otherwise, use XDrawImageString. (Note that
3148 XDrawImageString is usually faster than XDrawString.) Always
3149 use XDrawImageString when drawing the cursor so that there is
3150 no chance that characters under a box cursor are invisible. */
3151 if (s
->for_overlaps_p
3152 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3154 /* Draw characters with 16-bit or 8-bit functions. */
3156 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3157 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3159 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3160 s
->ybase
- boff
, char1b
, s
->nchars
);
3165 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3166 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3168 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3169 s
->ybase
- boff
, char1b
, s
->nchars
);
3174 /* Draw the foreground of composite glyph string S. */
3177 x_draw_composite_glyph_string_foreground (s
)
3178 struct glyph_string
*s
;
3182 /* If first glyph of S has a left box line, start drawing the text
3183 of S to the right of that box line. */
3184 if (s
->face
->box
!= FACE_NO_BOX
3185 && s
->first_glyph
->left_box_line_p
)
3186 x
= s
->x
+ s
->face
->box_line_width
;
3190 /* S is a glyph string for a composition. S->gidx is the index of
3191 the first character drawn for glyphs of this composition.
3192 S->gidx == 0 means we are drawing the very first character of
3193 this composition. */
3195 /* Draw a rectangle for the composition if the font for the very
3196 first character of the composition could not be loaded. */
3197 if (s
->font_not_found_p
)
3200 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3201 s
->width
- 1, s
->height
- 1);
3205 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3206 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3207 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3208 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3214 #ifdef USE_X_TOOLKIT
3216 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3219 /* Return the frame on which widget WIDGET is used.. Abort if frame
3220 cannot be determined. */
3222 static struct frame
*
3223 x_frame_of_widget (widget
)
3226 struct x_display_info
*dpyinfo
;
3230 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3232 /* Find the top-level shell of the widget. Note that this function
3233 can be called when the widget is not yet realized, so XtWindow
3234 (widget) == 0. That's the reason we can't simply use
3235 x_any_window_to_frame. */
3236 while (!XtIsTopLevelShell (widget
))
3237 widget
= XtParent (widget
);
3239 /* Look for a frame with that top-level widget. Allocate the color
3240 on that frame to get the right gamma correction value. */
3241 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3242 if (GC_FRAMEP (XCAR (tail
))
3243 && (f
= XFRAME (XCAR (tail
)),
3244 (f
->output_data
.nothing
!= 1
3245 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3246 && f
->output_data
.x
->widget
== widget
)
3253 /* Allocate the color COLOR->pixel on the screen and display of
3254 widget WIDGET in colormap CMAP. If an exact match cannot be
3255 allocated, try the nearest color available. Value is non-zero
3256 if successful. This is called from lwlib. */
3259 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3264 struct frame
*f
= x_frame_of_widget (widget
);
3265 return x_alloc_nearest_color (f
, cmap
, color
);
3269 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3270 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3271 If this produces the same color as PIXEL, try a color where all RGB
3272 values have DELTA added. Return the allocated color in *PIXEL.
3273 DISPLAY is the X display, CMAP is the colormap to operate on.
3274 Value is non-zero if successful. */
3277 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3281 unsigned long *pixel
;
3285 struct frame
*f
= x_frame_of_widget (widget
);
3286 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3290 #endif /* USE_X_TOOLKIT */
3293 /* Value is an array of XColor structures for the contents of the
3294 color map of frame F. Set *NCELLS to the size of the array.
3295 Note that this probably shouldn't be called for large color maps,
3296 say a 24-bit TrueColor map. */
3298 static const XColor
*
3299 x_color_cells (f
, ncells
)
3303 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3305 if (dpyinfo
->color_cells
== NULL
)
3307 Display
*display
= FRAME_X_DISPLAY (f
);
3308 Screen
*screen
= FRAME_X_SCREEN (f
);
3311 dpyinfo
->ncolor_cells
3312 = XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3313 dpyinfo
->color_cells
3314 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3315 * sizeof *dpyinfo
->color_cells
);
3317 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3318 dpyinfo
->color_cells
[i
].pixel
= i
;
3320 XQueryColors (display
, FRAME_X_COLORMAP (f
),
3321 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3324 *ncells
= dpyinfo
->ncolor_cells
;
3325 return dpyinfo
->color_cells
;
3329 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3330 colors in COLORS. Use cached information, if available. */
3333 x_query_colors (f
, colors
, ncolors
)
3338 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3340 if (dpyinfo
->color_cells
)
3343 for (i
= 0; i
< ncolors
; ++i
)
3345 unsigned long pixel
= colors
[i
].pixel
;
3346 xassert (pixel
< dpyinfo
->ncolor_cells
);
3347 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3348 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3352 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3356 /* On frame F, translate pixel color to RGB values for the color in
3357 COLOR. Use cached information, if available. */
3360 x_query_color (f
, color
)
3364 x_query_colors (f
, color
, 1);
3368 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3369 CMAP. If an exact match can't be allocated, try the nearest color
3370 available. Value is non-zero if successful. Set *COLOR to the
3374 x_alloc_nearest_color (f
, cmap
, color
)
3379 Display
*display
= FRAME_X_DISPLAY (f
);
3380 Screen
*screen
= FRAME_X_SCREEN (f
);
3383 gamma_correct (f
, color
);
3384 rc
= XAllocColor (display
, cmap
, color
);
3387 /* If we got to this point, the colormap is full, so we're going
3388 to try to get the next closest color. The algorithm used is
3389 a least-squares matching, which is what X uses for closest
3390 color matching with StaticColor visuals. */
3392 unsigned long nearest_delta
= ~0;
3394 const XColor
*cells
= x_color_cells (f
, &ncells
);
3396 for (nearest
= i
= 0; i
< ncells
; ++i
)
3398 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3399 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3400 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3401 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3403 if (delta
< nearest_delta
)
3406 nearest_delta
= delta
;
3410 color
->red
= cells
[nearest
].red
;
3411 color
->green
= cells
[nearest
].green
;
3412 color
->blue
= cells
[nearest
].blue
;
3413 rc
= XAllocColor (display
, cmap
, color
);
3417 /* If allocation succeeded, and the allocated pixel color is not
3418 equal to a cached pixel color recorded earlier, there was a
3419 change in the colormap, so clear the color cache. */
3420 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3421 XColor
*cached_color
;
3423 if (dpyinfo
->color_cells
3424 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3425 (cached_color
->red
!= color
->red
3426 || cached_color
->blue
!= color
->blue
3427 || cached_color
->green
!= color
->green
)))
3429 xfree (dpyinfo
->color_cells
);
3430 dpyinfo
->color_cells
= NULL
;
3431 dpyinfo
->ncolor_cells
= 0;
3435 #ifdef DEBUG_X_COLORS
3437 register_color (color
->pixel
);
3438 #endif /* DEBUG_X_COLORS */
3444 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3445 It's necessary to do this instead of just using PIXEL directly to
3446 get color reference counts right. */
3449 x_copy_color (f
, pixel
)
3451 unsigned long pixel
;
3455 color
.pixel
= pixel
;
3457 x_query_color (f
, &color
);
3458 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3460 #ifdef DEBUG_X_COLORS
3461 register_color (pixel
);
3467 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3468 It's necessary to do this instead of just using PIXEL directly to
3469 get color reference counts right. */
3472 x_copy_dpy_color (dpy
, cmap
, pixel
)
3475 unsigned long pixel
;
3479 color
.pixel
= pixel
;
3481 XQueryColor (dpy
, cmap
, &color
);
3482 XAllocColor (dpy
, cmap
, &color
);
3484 #ifdef DEBUG_X_COLORS
3485 register_color (pixel
);
3491 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3492 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3493 If this produces the same color as PIXEL, try a color where all RGB
3494 values have DELTA added. Return the allocated color in *PIXEL.
3495 DISPLAY is the X display, CMAP is the colormap to operate on.
3496 Value is non-zero if successful. */
3499 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3503 unsigned long *pixel
;
3510 /* Get RGB color values. */
3511 color
.pixel
= *pixel
;
3512 x_query_color (f
, &color
);
3514 /* Change RGB values by specified FACTOR. Avoid overflow! */
3515 xassert (factor
>= 0);
3516 new.red
= min (0xffff, factor
* color
.red
);
3517 new.green
= min (0xffff, factor
* color
.green
);
3518 new.blue
= min (0xffff, factor
* color
.blue
);
3520 /* Try to allocate the color. */
3521 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3524 if (new.pixel
== *pixel
)
3526 /* If we end up with the same color as before, try adding
3527 delta to the RGB values. */
3528 x_free_colors (f
, &new.pixel
, 1);
3530 new.red
= min (0xffff, delta
+ color
.red
);
3531 new.green
= min (0xffff, delta
+ color
.green
);
3532 new.blue
= min (0xffff, delta
+ color
.blue
);
3533 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3544 /* Set up the foreground color for drawing relief lines of glyph
3545 string S. RELIEF is a pointer to a struct relief containing the GC
3546 with which lines will be drawn. Use a color that is FACTOR or
3547 DELTA lighter or darker than the relief's background which is found
3548 in S->f->output_data.x->relief_background. If such a color cannot
3549 be allocated, use DEFAULT_PIXEL, instead. */
3552 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3554 struct relief
*relief
;
3557 unsigned long default_pixel
;
3560 struct x_output
*di
= f
->output_data
.x
;
3561 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3562 unsigned long pixel
;
3563 unsigned long background
= di
->relief_background
;
3564 Colormap cmap
= FRAME_X_COLORMAP (f
);
3565 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3566 Display
*dpy
= FRAME_X_DISPLAY (f
);
3568 xgcv
.graphics_exposures
= False
;
3569 xgcv
.line_width
= 1;
3571 /* Free previously allocated color. The color cell will be reused
3572 when it has been freed as many times as it was allocated, so this
3573 doesn't affect faces using the same colors. */
3575 && relief
->allocated_p
)
3577 x_free_colors (f
, &relief
->pixel
, 1);
3578 relief
->allocated_p
= 0;
3581 /* Allocate new color. */
3582 xgcv
.foreground
= default_pixel
;
3584 if (dpyinfo
->n_planes
!= 1
3585 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3587 relief
->allocated_p
= 1;
3588 xgcv
.foreground
= relief
->pixel
= pixel
;
3591 if (relief
->gc
== 0)
3593 xgcv
.stipple
= dpyinfo
->gray
;
3595 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3598 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3602 /* Set up colors for the relief lines around glyph string S. */
3605 x_setup_relief_colors (s
)
3606 struct glyph_string
*s
;
3608 struct x_output
*di
= s
->f
->output_data
.x
;
3609 unsigned long color
;
3611 if (s
->face
->use_box_color_for_shadows_p
)
3612 color
= s
->face
->box_color
;
3617 /* Get the background color of the face. */
3618 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3619 color
= xgcv
.background
;
3622 if (di
->white_relief
.gc
== 0
3623 || color
!= di
->relief_background
)
3625 di
->relief_background
= color
;
3626 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3627 WHITE_PIX_DEFAULT (s
->f
));
3628 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3629 BLACK_PIX_DEFAULT (s
->f
));
3634 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3635 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3636 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3637 relief. LEFT_P non-zero means draw a relief on the left side of
3638 the rectangle. RIGHT_P non-zero means draw a relief on the right
3639 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3643 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3644 raised_p
, left_p
, right_p
, clip_rect
)
3646 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3647 XRectangle
*clip_rect
;
3653 gc
= f
->output_data
.x
->white_relief
.gc
;
3655 gc
= f
->output_data
.x
->black_relief
.gc
;
3656 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3659 for (i
= 0; i
< width
; ++i
)
3660 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3661 left_x
+ i
* left_p
, top_y
+ i
,
3662 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3666 for (i
= 0; i
< width
; ++i
)
3667 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3668 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
3670 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3672 gc
= f
->output_data
.x
->black_relief
.gc
;
3674 gc
= f
->output_data
.x
->white_relief
.gc
;
3675 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3678 for (i
= 0; i
< width
; ++i
)
3679 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3680 left_x
+ i
* left_p
, bottom_y
- i
,
3681 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3685 for (i
= 0; i
< width
; ++i
)
3686 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3687 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3689 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3693 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3694 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3695 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3696 left side of the rectangle. RIGHT_P non-zero means draw a line
3697 on the right side of the rectangle. CLIP_RECT is the clipping
3698 rectangle to use when drawing. */
3701 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3702 left_p
, right_p
, clip_rect
)
3703 struct glyph_string
*s
;
3704 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3705 XRectangle
*clip_rect
;
3709 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3710 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3711 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3714 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3715 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3719 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3720 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3723 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3724 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3728 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3729 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3731 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3732 XSetClipMask (s
->display
, s
->gc
, None
);
3736 /* Draw a box around glyph string S. */
3739 x_draw_glyph_string_box (s
)
3740 struct glyph_string
*s
;
3742 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3743 int left_p
, right_p
;
3744 struct glyph
*last_glyph
;
3745 XRectangle clip_rect
;
3747 last_x
= window_box_right (s
->w
, s
->area
);
3748 if (s
->row
->full_width_p
3749 && !s
->w
->pseudo_window_p
)
3751 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3752 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3753 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3756 /* The glyph that may have a right box line. */
3757 last_glyph
= (s
->cmp
|| s
->img
3759 : s
->first_glyph
+ s
->nchars
- 1);
3761 width
= s
->face
->box_line_width
;
3762 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3764 right_x
= ((s
->row
->full_width_p
3766 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3768 bottom_y
= top_y
+ s
->height
- 1;
3770 left_p
= (s
->first_glyph
->left_box_line_p
3771 || (s
->hl
== DRAW_MOUSE_FACE
3773 || s
->prev
->hl
!= s
->hl
)));
3774 right_p
= (last_glyph
->right_box_line_p
3775 || (s
->hl
== DRAW_MOUSE_FACE
3777 || s
->next
->hl
!= s
->hl
)));
3779 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3781 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3782 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3783 left_p
, right_p
, &clip_rect
);
3786 x_setup_relief_colors (s
);
3787 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3788 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3793 /* Draw foreground of image glyph string S. */
3796 x_draw_image_foreground (s
)
3797 struct glyph_string
*s
;
3800 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3802 /* If first glyph of S has a left box line, start drawing it to the
3803 right of that line. */
3804 if (s
->face
->box
!= FACE_NO_BOX
3805 && s
->first_glyph
->left_box_line_p
)
3806 x
= s
->x
+ s
->face
->box_line_width
;
3810 /* If there is a margin around the image, adjust x- and y-position
3814 x
+= s
->img
->margin
;
3815 y
+= s
->img
->margin
;
3822 /* We can't set both a clip mask and use XSetClipRectangles
3823 because the latter also sets a clip mask. We also can't
3824 trust on the shape extension to be available
3825 (XShapeCombineRegion). So, compute the rectangle to draw
3827 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3830 XRectangle clip_rect
, image_rect
, r
;
3832 xgcv
.clip_mask
= s
->img
->mask
;
3833 xgcv
.clip_x_origin
= x
;
3834 xgcv
.clip_y_origin
= y
;
3835 xgcv
.function
= GXcopy
;
3836 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3838 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3841 image_rect
.width
= s
->img
->width
;
3842 image_rect
.height
= s
->img
->height
;
3843 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3844 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3845 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3849 unsigned long mask
= GCClipXOrigin
| GCClipYOrigin
| GCFunction
;
3851 XRectangle clip_rect
, image_rect
, r
;
3853 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3856 image_rect
.width
= s
->img
->width
;
3857 image_rect
.height
= s
->img
->height
;
3858 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3859 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3860 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3862 /* When the image has a mask, we can expect that at
3863 least part of a mouse highlight or a block cursor will
3864 be visible. If the image doesn't have a mask, make
3865 a block cursor visible by drawing a rectangle around
3866 the image. I believe it's looking better if we do
3867 nothing here for mouse-face. */
3868 if (s
->hl
== DRAW_CURSOR
)
3869 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3870 s
->img
->width
- 1, s
->img
->height
- 1);
3874 /* Draw a rectangle if image could not be loaded. */
3875 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3876 s
->img
->width
- 1, s
->img
->height
- 1);
3880 /* Draw a relief around the image glyph string S. */
3883 x_draw_image_relief (s
)
3884 struct glyph_string
*s
;
3886 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3889 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3891 /* If first glyph of S has a left box line, start drawing it to the
3892 right of that line. */
3893 if (s
->face
->box
!= FACE_NO_BOX
3894 && s
->first_glyph
->left_box_line_p
)
3895 x
= s
->x
+ s
->face
->box_line_width
;
3899 /* If there is a margin around the image, adjust x- and y-position
3903 x
+= s
->img
->margin
;
3904 y
+= s
->img
->margin
;
3907 if (s
->hl
== DRAW_IMAGE_SUNKEN
3908 || s
->hl
== DRAW_IMAGE_RAISED
)
3910 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3911 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3915 thick
= abs (s
->img
->relief
);
3916 raised_p
= s
->img
->relief
> 0;
3921 x1
= x
+ s
->img
->width
+ thick
- 1;
3922 y1
= y
+ s
->img
->height
+ thick
- 1;
3924 x_setup_relief_colors (s
);
3925 x_get_glyph_string_clip_rect (s
, &r
);
3926 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3930 /* Draw the foreground of image glyph string S to PIXMAP. */
3933 x_draw_image_foreground_1 (s
, pixmap
)
3934 struct glyph_string
*s
;
3938 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3940 /* If first glyph of S has a left box line, start drawing it to the
3941 right of that line. */
3942 if (s
->face
->box
!= FACE_NO_BOX
3943 && s
->first_glyph
->left_box_line_p
)
3944 x
= s
->face
->box_line_width
;
3948 /* If there is a margin around the image, adjust x- and y-position
3952 x
+= s
->img
->margin
;
3953 y
+= s
->img
->margin
;
3960 /* We can't set both a clip mask and use XSetClipRectangles
3961 because the latter also sets a clip mask. We also can't
3962 trust on the shape extension to be available
3963 (XShapeCombineRegion). So, compute the rectangle to draw
3965 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3969 xgcv
.clip_mask
= s
->img
->mask
;
3970 xgcv
.clip_x_origin
= x
;
3971 xgcv
.clip_y_origin
= y
;
3972 xgcv
.function
= GXcopy
;
3973 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3975 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3976 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3977 XSetClipMask (s
->display
, s
->gc
, None
);
3981 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3982 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3984 /* When the image has a mask, we can expect that at
3985 least part of a mouse highlight or a block cursor will
3986 be visible. If the image doesn't have a mask, make
3987 a block cursor visible by drawing a rectangle around
3988 the image. I believe it's looking better if we do
3989 nothing here for mouse-face. */
3990 if (s
->hl
== DRAW_CURSOR
)
3991 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
3992 s
->img
->width
- 1, s
->img
->height
- 1);
3996 /* Draw a rectangle if image could not be loaded. */
3997 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
3998 s
->img
->width
- 1, s
->img
->height
- 1);
4002 /* Draw part of the background of glyph string S. X, Y, W, and H
4003 give the rectangle to draw. */
4006 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4007 struct glyph_string
*s
;
4012 /* Fill background with a stipple pattern. */
4013 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4014 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4015 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4018 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4022 /* Draw image glyph string S.
4025 s->x +-------------------------
4028 | +-------------------------
4031 | | +-------------------
4037 x_draw_image_glyph_string (s
)
4038 struct glyph_string
*s
;
4041 int box_line_width
= s
->face
->box_line_width
;
4042 int margin
= s
->img
->margin
;
4044 Pixmap pixmap
= None
;
4046 height
= s
->height
- 2 * box_line_width
;
4048 /* Fill background with face under the image. Do it only if row is
4049 taller than image or if image has a clip mask to reduce
4051 s
->stippled_p
= s
->face
->stipple
!= 0;
4052 if (height
> s
->img
->height
4055 || s
->img
->pixmap
== 0
4056 || s
->width
!= s
->background_width
)
4058 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
4059 x
= s
->x
+ box_line_width
;
4063 y
= s
->y
+ box_line_width
;
4067 /* Create a pixmap as large as the glyph string. Fill it
4068 with the background color. Copy the image to it, using
4069 its mask. Copy the temporary pixmap to the display. */
4070 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4071 int depth
= DefaultDepthOfScreen (screen
);
4073 /* Create a pixmap as large as the glyph string. */
4074 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4075 s
->background_width
,
4078 /* Don't clip in the following because we're working on the
4080 XSetClipMask (s
->display
, s
->gc
, None
);
4082 /* Fill the pixmap with the background color/stipple. */
4085 /* Fill background with a stipple pattern. */
4086 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4087 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4088 0, 0, s
->background_width
, s
->height
);
4089 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4094 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4096 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4097 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4098 0, 0, s
->background_width
, s
->height
);
4099 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4103 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4105 s
->background_filled_p
= 1;
4108 /* Draw the foreground. */
4111 x_draw_image_foreground_1 (s
, pixmap
);
4112 x_set_glyph_string_clipping (s
);
4113 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4114 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4115 XFreePixmap (s
->display
, pixmap
);
4118 x_draw_image_foreground (s
);
4120 /* If we must draw a relief around the image, do it. */
4122 || s
->hl
== DRAW_IMAGE_RAISED
4123 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4124 x_draw_image_relief (s
);
4128 /* Draw stretch glyph string S. */
4131 x_draw_stretch_glyph_string (s
)
4132 struct glyph_string
*s
;
4134 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4135 s
->stippled_p
= s
->face
->stipple
!= 0;
4137 if (s
->hl
== DRAW_CURSOR
4138 && !x_stretch_cursor_p
)
4140 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4141 as wide as the stretch glyph. */
4142 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4145 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4147 /* Clear rest using the GC of the original non-cursor face. */
4148 if (width
< s
->background_width
)
4150 GC gc
= s
->face
->gc
;
4151 int x
= s
->x
+ width
, y
= s
->y
;
4152 int w
= s
->background_width
- width
, h
= s
->height
;
4155 x_get_glyph_string_clip_rect (s
, &r
);
4156 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4158 if (s
->face
->stipple
)
4160 /* Fill background with a stipple pattern. */
4161 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4162 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4163 XSetFillStyle (s
->display
, gc
, FillSolid
);
4168 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4169 XSetForeground (s
->display
, gc
, xgcv
.background
);
4170 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4171 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4176 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4179 s
->background_filled_p
= 1;
4183 /* Draw glyph string S. */
4186 x_draw_glyph_string (s
)
4187 struct glyph_string
*s
;
4189 /* If S draws into the background of its successor, draw the
4190 background of the successor first so that S can draw into it.
4191 This makes S->next use XDrawString instead of XDrawImageString. */
4192 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4194 xassert (s
->next
->img
== NULL
);
4195 x_set_glyph_string_gc (s
->next
);
4196 x_set_glyph_string_clipping (s
->next
);
4197 x_draw_glyph_string_background (s
->next
, 1);
4200 /* Set up S->gc, set clipping and draw S. */
4201 x_set_glyph_string_gc (s
);
4202 x_set_glyph_string_clipping (s
);
4204 switch (s
->first_glyph
->type
)
4207 x_draw_image_glyph_string (s
);
4211 x_draw_stretch_glyph_string (s
);
4215 if (s
->for_overlaps_p
)
4216 s
->background_filled_p
= 1;
4218 x_draw_glyph_string_background (s
, 0);
4219 x_draw_glyph_string_foreground (s
);
4222 case COMPOSITE_GLYPH
:
4223 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4224 s
->background_filled_p
= 1;
4226 x_draw_glyph_string_background (s
, 1);
4227 x_draw_composite_glyph_string_foreground (s
);
4234 if (!s
->for_overlaps_p
)
4236 /* Draw underline. */
4237 if (s
->face
->underline_p
)
4239 unsigned long tem
, h
;
4242 /* Get the underline thickness. Default is 1 pixel. */
4243 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4246 /* Get the underline position. This is the recommended
4247 vertical offset in pixels from the baseline to the top of
4248 the underline. This is a signed value according to the
4249 specs, and its default is
4251 ROUND ((maximum descent) / 2), with
4252 ROUND(x) = floor (x + 0.5) */
4254 if (XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4255 y
= s
->ybase
+ (long) tem
;
4256 else if (s
->face
->font
)
4257 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4261 if (s
->face
->underline_defaulted_p
)
4262 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4263 s
->x
, y
, s
->width
, h
);
4267 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4268 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4269 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4270 s
->x
, y
, s
->width
, h
);
4271 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4275 /* Draw overline. */
4276 if (s
->face
->overline_p
)
4278 unsigned long dy
= 0, h
= 1;
4280 if (s
->face
->overline_color_defaulted_p
)
4281 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4286 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4287 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4288 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4290 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4294 /* Draw strike-through. */
4295 if (s
->face
->strike_through_p
)
4297 unsigned long h
= 1;
4298 unsigned long dy
= (s
->height
- h
) / 2;
4300 if (s
->face
->strike_through_color_defaulted_p
)
4301 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4306 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4307 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4308 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4310 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4315 if (s
->face
->box
!= FACE_NO_BOX
)
4316 x_draw_glyph_string_box (s
);
4319 /* Reset clipping. */
4320 XSetClipMask (s
->display
, s
->gc
, None
);
4324 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4325 struct face
**, int));
4328 /* Fill glyph string S with composition components specified by S->cmp.
4330 FACES is an array of faces for all components of this composition.
4331 S->gidx is the index of the first component for S.
4332 OVERLAPS_P non-zero means S should draw the foreground only, and
4333 use its physical height for clipping.
4335 Value is the index of a component not in S. */
4338 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4339 struct glyph_string
*s
;
4340 struct face
**faces
;
4347 s
->for_overlaps_p
= overlaps_p
;
4349 s
->face
= faces
[s
->gidx
];
4350 s
->font
= s
->face
->font
;
4351 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4353 /* For all glyphs of this composition, starting at the offset
4354 S->gidx, until we reach the end of the definition or encounter a
4355 glyph that requires the different face, add it to S. */
4357 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4360 /* All glyph strings for the same composition has the same width,
4361 i.e. the width set for the first component of the composition. */
4363 s
->width
= s
->first_glyph
->pixel_width
;
4365 /* If the specified font could not be loaded, use the frame's
4366 default font, but record the fact that we couldn't load it in
4367 the glyph string so that we can draw rectangles for the
4368 characters of the glyph string. */
4369 if (s
->font
== NULL
)
4371 s
->font_not_found_p
= 1;
4372 s
->font
= FRAME_FONT (s
->f
);
4375 /* Adjust base line for subscript/superscript text. */
4376 s
->ybase
+= s
->first_glyph
->voffset
;
4378 xassert (s
->face
&& s
->face
->gc
);
4380 /* This glyph string must always be drawn with 16-bit functions. */
4383 return s
->gidx
+ s
->nchars
;
4387 /* Fill glyph string S from a sequence of character glyphs.
4389 FACE_ID is the face id of the string. START is the index of the
4390 first glyph to consider, END is the index of the last + 1.
4391 OVERLAPS_P non-zero means S should draw the foreground only, and
4392 use its physical height for clipping.
4394 Value is the index of the first glyph not in S. */
4397 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4398 struct glyph_string
*s
;
4400 int start
, end
, overlaps_p
;
4402 struct glyph
*glyph
, *last
;
4404 int glyph_not_available_p
;
4406 xassert (s
->f
== XFRAME (s
->w
->frame
));
4407 xassert (s
->nchars
== 0);
4408 xassert (start
>= 0 && end
> start
);
4410 s
->for_overlaps_p
= overlaps_p
,
4411 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4412 last
= s
->row
->glyphs
[s
->area
] + end
;
4413 voffset
= glyph
->voffset
;
4415 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4418 && glyph
->type
== CHAR_GLYPH
4419 && glyph
->voffset
== voffset
4420 /* Same face id implies same font, nowadays. */
4421 && glyph
->face_id
== face_id
4422 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4426 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4427 s
->char2b
+ s
->nchars
,
4429 s
->two_byte_p
= two_byte_p
;
4431 xassert (s
->nchars
<= end
- start
);
4432 s
->width
+= glyph
->pixel_width
;
4436 s
->font
= s
->face
->font
;
4437 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4439 /* If the specified font could not be loaded, use the frame's font,
4440 but record the fact that we couldn't load it in
4441 S->font_not_found_p so that we can draw rectangles for the
4442 characters of the glyph string. */
4443 if (s
->font
== NULL
|| glyph_not_available_p
)
4445 s
->font_not_found_p
= 1;
4446 s
->font
= FRAME_FONT (s
->f
);
4449 /* Adjust base line for subscript/superscript text. */
4450 s
->ybase
+= voffset
;
4452 xassert (s
->face
&& s
->face
->gc
);
4453 return glyph
- s
->row
->glyphs
[s
->area
];
4457 /* Fill glyph string S from image glyph S->first_glyph. */
4460 x_fill_image_glyph_string (s
)
4461 struct glyph_string
*s
;
4463 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4464 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4466 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4467 s
->font
= s
->face
->font
;
4468 s
->width
= s
->first_glyph
->pixel_width
;
4470 /* Adjust base line for subscript/superscript text. */
4471 s
->ybase
+= s
->first_glyph
->voffset
;
4475 /* Fill glyph string S from a sequence of stretch glyphs.
4477 ROW is the glyph row in which the glyphs are found, AREA is the
4478 area within the row. START is the index of the first glyph to
4479 consider, END is the index of the last + 1.
4481 Value is the index of the first glyph not in S. */
4484 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4485 struct glyph_string
*s
;
4486 struct glyph_row
*row
;
4487 enum glyph_row_area area
;
4490 struct glyph
*glyph
, *last
;
4491 int voffset
, face_id
;
4493 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4495 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4496 last
= s
->row
->glyphs
[s
->area
] + end
;
4497 face_id
= glyph
->face_id
;
4498 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4499 s
->font
= s
->face
->font
;
4500 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4501 s
->width
= glyph
->pixel_width
;
4502 voffset
= glyph
->voffset
;
4506 && glyph
->type
== STRETCH_GLYPH
4507 && glyph
->voffset
== voffset
4508 && glyph
->face_id
== face_id
);
4510 s
->width
+= glyph
->pixel_width
;
4512 /* Adjust base line for subscript/superscript text. */
4513 s
->ybase
+= voffset
;
4515 xassert (s
->face
&& s
->face
->gc
);
4516 return glyph
- s
->row
->glyphs
[s
->area
];
4520 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4521 of XChar2b structures for S; it can't be allocated in
4522 x_init_glyph_string because it must be allocated via `alloca'. W
4523 is the window on which S is drawn. ROW and AREA are the glyph row
4524 and area within the row from which S is constructed. START is the
4525 index of the first glyph structure covered by S. HL is a
4526 face-override for drawing S. */
4529 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4530 struct glyph_string
*s
;
4533 struct glyph_row
*row
;
4534 enum glyph_row_area area
;
4536 enum draw_glyphs_face hl
;
4538 bzero (s
, sizeof *s
);
4540 s
->f
= XFRAME (w
->frame
);
4541 s
->display
= FRAME_X_DISPLAY (s
->f
);
4542 s
->window
= FRAME_X_WINDOW (s
->f
);
4547 s
->first_glyph
= row
->glyphs
[area
] + start
;
4548 s
->height
= row
->height
;
4549 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4551 /* Display the internal border below the tool-bar window. */
4552 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4553 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4555 s
->ybase
= s
->y
+ row
->ascent
;
4559 /* Set background width of glyph string S. START is the index of the
4560 first glyph following S. LAST_X is the right-most x-position + 1
4561 in the drawing area. */
4564 x_set_glyph_string_background_width (s
, start
, last_x
)
4565 struct glyph_string
*s
;
4569 /* If the face of this glyph string has to be drawn to the end of
4570 the drawing area, set S->extends_to_end_of_line_p. */
4571 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4573 if (start
== s
->row
->used
[s
->area
]
4574 && s
->hl
== DRAW_NORMAL_TEXT
4575 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4576 || s
->face
->background
!= default_face
->background
4577 || s
->face
->stipple
!= default_face
->stipple
))
4578 s
->extends_to_end_of_line_p
= 1;
4580 /* If S extends its face to the end of the line, set its
4581 background_width to the distance to the right edge of the drawing
4583 if (s
->extends_to_end_of_line_p
)
4584 s
->background_width
= last_x
- s
->x
+ 1;
4586 s
->background_width
= s
->width
;
4590 /* Add a glyph string for a stretch glyph to the list of strings
4591 between HEAD and TAIL. START is the index of the stretch glyph in
4592 row area AREA of glyph row ROW. END is the index of the last glyph
4593 in that glyph row area. X is the current output position assigned
4594 to the new glyph string constructed. HL overrides that face of the
4595 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4596 is the right-most x-position of the drawing area. */
4598 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4599 and below -- keep them on one line. */
4600 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4603 s = (struct glyph_string *) alloca (sizeof *s); \
4604 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4605 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4606 x_append_glyph_string (&HEAD, &TAIL, s); \
4612 /* Add a glyph string for an image glyph to the list of strings
4613 between HEAD and TAIL. START is the index of the image glyph in
4614 row area AREA of glyph row ROW. END is the index of the last glyph
4615 in that glyph row area. X is the current output position assigned
4616 to the new glyph string constructed. HL overrides that face of the
4617 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4618 is the right-most x-position of the drawing area. */
4620 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4623 s = (struct glyph_string *) alloca (sizeof *s); \
4624 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4625 x_fill_image_glyph_string (s); \
4626 x_append_glyph_string (&HEAD, &TAIL, s); \
4633 /* Add a glyph string for a sequence of character glyphs to the list
4634 of strings between HEAD and TAIL. START is the index of the first
4635 glyph in row area AREA of glyph row ROW that is part of the new
4636 glyph string. END is the index of the last glyph in that glyph row
4637 area. X is the current output position assigned to the new glyph
4638 string constructed. HL overrides that face of the glyph; e.g. it
4639 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4640 right-most x-position of the drawing area. */
4642 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4648 c = (ROW)->glyphs[AREA][START].u.ch; \
4649 face_id = (ROW)->glyphs[AREA][START].face_id; \
4651 s = (struct glyph_string *) alloca (sizeof *s); \
4652 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4653 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4654 x_append_glyph_string (&HEAD, &TAIL, s); \
4656 START = x_fill_glyph_string (s, face_id, START, END, \
4662 /* Add a glyph string for a composite sequence to the list of strings
4663 between HEAD and TAIL. START is the index of the first glyph in
4664 row area AREA of glyph row ROW that is part of the new glyph
4665 string. END is the index of the last glyph in that glyph row area.
4666 X is the current output position assigned to the new glyph string
4667 constructed. HL overrides that face of the glyph; e.g. it is
4668 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4669 x-position of the drawing area. */
4671 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4673 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4674 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4675 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4676 struct composition *cmp = composition_table[cmp_id]; \
4677 int glyph_len = cmp->glyph_len; \
4679 struct face **faces; \
4680 struct glyph_string *first_s = NULL; \
4683 base_face = base_face->ascii_face; \
4684 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4685 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4686 /* At first, fill in `char2b' and `faces'. */ \
4687 for (n = 0; n < glyph_len; n++) \
4689 int c = COMPOSITION_GLYPH (cmp, n); \
4690 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4691 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4692 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4693 this_face_id, char2b + n, 1); \
4696 /* Make glyph_strings for each glyph sequence that is drawable by \
4697 the same face, and append them to HEAD/TAIL. */ \
4698 for (n = 0; n < cmp->glyph_len;) \
4700 s = (struct glyph_string *) alloca (sizeof *s); \
4701 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4702 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4710 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4718 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4719 of AREA of glyph row ROW on window W between indices START and END.
4720 HL overrides the face for drawing glyph strings, e.g. it is
4721 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4722 x-positions of the drawing area.
4724 This is an ugly monster macro construct because we must use alloca
4725 to allocate glyph strings (because x_draw_glyphs can be called
4728 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4731 HEAD = TAIL = NULL; \
4732 while (START < END) \
4734 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4735 switch (first_glyph->type) \
4738 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4739 TAIL, HL, X, LAST_X, \
4743 case COMPOSITE_GLYPH: \
4744 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
4745 HEAD, TAIL, HL, X, LAST_X,\
4749 case STRETCH_GLYPH: \
4750 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
4751 HEAD, TAIL, HL, X, LAST_X); \
4755 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
4756 TAIL, HL, X, LAST_X); \
4763 x_set_glyph_string_background_width (s, START, LAST_X); \
4770 /* Draw glyphs between START and END in AREA of ROW on window W,
4771 starting at x-position X. X is relative to AREA in W. HL is a
4772 face-override with the following meaning:
4774 DRAW_NORMAL_TEXT draw normally
4775 DRAW_CURSOR draw in cursor face
4776 DRAW_MOUSE_FACE draw in mouse face.
4777 DRAW_INVERSE_VIDEO draw in mode line face
4778 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4779 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4781 If REAL_START is non-null, return in *REAL_START the real starting
4782 position for display. This can be different from START in case
4783 overlapping glyphs must be displayed. If REAL_END is non-null,
4784 return in *REAL_END the real end position for display. This can be
4785 different from END in case overlapping glyphs must be displayed.
4787 If OVERLAPS_P is non-zero, draw only the foreground of characters
4788 and clip to the physical height of ROW.
4790 Value is the x-position reached, relative to AREA of W. */
4793 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4797 struct glyph_row
*row
;
4798 enum glyph_row_area area
;
4800 enum draw_glyphs_face hl
;
4801 int *real_start
, *real_end
;
4804 struct glyph_string
*head
, *tail
;
4805 struct glyph_string
*s
;
4806 int last_x
, area_width
;
4810 /* Let's rather be paranoid than getting a SEGV. */
4811 end
= min (end
, row
->used
[area
]);
4812 start
= max (0, start
);
4813 start
= min (end
, start
);
4815 *real_start
= start
;
4819 /* Translate X to frame coordinates. Set last_x to the right
4820 end of the drawing area. */
4821 if (row
->full_width_p
)
4823 /* X is relative to the left edge of W, without scroll bars
4825 struct frame
*f
= XFRAME (w
->frame
);
4826 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4827 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4830 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4831 last_x
= window_left_x
+ area_width
;
4833 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4835 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4836 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4842 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4843 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4847 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4848 area_width
= window_box_width (w
, area
);
4849 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4852 /* Build a doubly-linked list of glyph_string structures between
4853 head and tail from what we have to draw. Note that the macro
4854 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4855 the reason we use a separate variable `i'. */
4857 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4860 x_reached
= tail
->x
+ tail
->background_width
;
4864 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4865 the row, redraw some glyphs in front or following the glyph
4866 strings built above. */
4867 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4870 struct glyph_string
*h
, *t
;
4872 /* Compute overhangs for all glyph strings. */
4873 for (s
= head
; s
; s
= s
->next
)
4874 x_compute_glyph_string_overhangs (s
);
4876 /* Prepend glyph strings for glyphs in front of the first glyph
4877 string that are overwritten because of the first glyph
4878 string's left overhang. The background of all strings
4879 prepended must be drawn because the first glyph string
4881 i
= x_left_overwritten (head
);
4885 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
4886 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4890 *real_start
= start
;
4891 x_compute_overhangs_and_x (t
, head
->x
, 1);
4892 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4895 /* Prepend glyph strings for glyphs in front of the first glyph
4896 string that overwrite that glyph string because of their
4897 right overhang. For these strings, only the foreground must
4898 be drawn, because it draws over the glyph string at `head'.
4899 The background must not be drawn because this would overwrite
4900 right overhangs of preceding glyphs for which no glyph
4902 i
= x_left_overwriting (head
);
4905 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
4906 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4908 for (s
= h
; s
; s
= s
->next
)
4909 s
->background_filled_p
= 1;
4912 x_compute_overhangs_and_x (t
, head
->x
, 1);
4913 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4916 /* Append glyphs strings for glyphs following the last glyph
4917 string tail that are overwritten by tail. The background of
4918 these strings has to be drawn because tail's foreground draws
4920 i
= x_right_overwritten (tail
);
4923 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
4924 DRAW_NORMAL_TEXT
, x
, last_x
,
4926 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4927 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4932 /* Append glyph strings for glyphs following the last glyph
4933 string tail that overwrite tail. The foreground of such
4934 glyphs has to be drawn because it writes into the background
4935 of tail. The background must not be drawn because it could
4936 paint over the foreground of following glyphs. */
4937 i
= x_right_overwriting (tail
);
4940 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
4941 DRAW_NORMAL_TEXT
, x
, last_x
,
4943 for (s
= h
; s
; s
= s
->next
)
4944 s
->background_filled_p
= 1;
4945 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4946 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4952 /* Draw all strings. */
4953 for (s
= head
; s
; s
= s
->next
)
4954 x_draw_glyph_string (s
);
4956 /* Value is the x-position up to which drawn, relative to AREA of W.
4957 This doesn't include parts drawn because of overhangs. */
4958 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4959 if (!row
->full_width_p
)
4961 if (area
> LEFT_MARGIN_AREA
)
4962 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4963 if (area
> TEXT_AREA
)
4964 x_reached
-= window_box_width (w
, TEXT_AREA
);
4971 /* Fix the display of area AREA of overlapping row ROW in window W. */
4974 x_fix_overlapping_area (w
, row
, area
)
4976 struct glyph_row
*row
;
4977 enum glyph_row_area area
;
4983 if (area
== LEFT_MARGIN_AREA
)
4985 else if (area
== TEXT_AREA
)
4986 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4988 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4989 + window_box_width (w
, TEXT_AREA
));
4991 for (i
= 0; i
< row
->used
[area
];)
4993 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4995 int start
= i
, start_x
= x
;
4999 x
+= row
->glyphs
[area
][i
].pixel_width
;
5002 while (i
< row
->used
[area
]
5003 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5005 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5007 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5012 x
+= row
->glyphs
[area
][i
].pixel_width
;
5021 /* Output LEN glyphs starting at START at the nominal cursor position.
5022 Advance the nominal cursor over the text. The global variable
5023 updated_window contains the window being updated, updated_row is
5024 the glyph row being updated, and updated_area is the area of that
5025 row being updated. */
5028 x_write_glyphs (start
, len
)
5029 struct glyph
*start
;
5032 int x
, hpos
, real_start
, real_end
;
5034 xassert (updated_window
&& updated_row
);
5039 hpos
= start
- updated_row
->glyphs
[updated_area
];
5040 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5041 updated_row
, updated_area
,
5043 (updated_row
->inverse_p
5044 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5045 &real_start
, &real_end
, 0);
5047 /* If we drew over the cursor, note that it is not visible any more. */
5048 note_overwritten_text_cursor (updated_window
, real_start
,
5049 real_end
- real_start
);
5053 /* Advance the output cursor. */
5054 output_cursor
.hpos
+= len
;
5055 output_cursor
.x
= x
;
5059 /* Insert LEN glyphs from START at the nominal cursor position. */
5062 x_insert_glyphs (start
, len
)
5063 struct glyph
*start
;
5068 int line_height
, shift_by_width
, shifted_region_width
;
5069 struct glyph_row
*row
;
5070 struct glyph
*glyph
;
5071 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5073 xassert (updated_window
&& updated_row
);
5076 f
= XFRAME (WINDOW_FRAME (w
));
5078 /* Get the height of the line we are in. */
5080 line_height
= row
->height
;
5082 /* Get the width of the glyphs to insert. */
5084 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5085 shift_by_width
+= glyph
->pixel_width
;
5087 /* Get the width of the region to shift right. */
5088 shifted_region_width
= (window_box_width (w
, updated_area
)
5093 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
5094 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5095 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5096 f
->output_data
.x
->normal_gc
,
5098 shifted_region_width
, line_height
,
5099 frame_x
+ shift_by_width
, frame_y
);
5101 /* Write the glyphs. */
5102 hpos
= start
- row
->glyphs
[updated_area
];
5103 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5104 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5105 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5107 /* Advance the output cursor. */
5108 output_cursor
.hpos
+= len
;
5109 output_cursor
.x
+= shift_by_width
;
5114 /* Delete N glyphs at the nominal cursor position. Not implemented
5125 /* Erase the current text line from the nominal cursor position
5126 (inclusive) to pixel column TO_X (exclusive). The idea is that
5127 everything from TO_X onward is already erased.
5129 TO_X is a pixel position relative to updated_area of
5130 updated_window. TO_X == -1 means clear to the end of this area. */
5133 x_clear_end_of_line (to_x
)
5137 struct window
*w
= updated_window
;
5138 int max_x
, min_y
, max_y
;
5139 int from_x
, from_y
, to_y
;
5141 xassert (updated_window
&& updated_row
);
5142 f
= XFRAME (w
->frame
);
5144 if (updated_row
->full_width_p
)
5146 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5147 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5148 && !w
->pseudo_window_p
)
5149 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5152 max_x
= window_box_width (w
, updated_area
);
5153 max_y
= window_text_bottom_y (w
);
5155 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5156 of window. For TO_X > 0, truncate to end of drawing area. */
5162 to_x
= min (to_x
, max_x
);
5164 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5166 /* Notice if the cursor will be cleared by this operation. */
5167 if (!updated_row
->full_width_p
)
5168 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5170 from_x
= output_cursor
.x
;
5172 /* Translate to frame coordinates. */
5173 if (updated_row
->full_width_p
)
5175 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5176 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5180 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5181 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5184 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5185 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5186 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5188 /* Prevent inadvertently clearing to end of the X window. */
5189 if (to_x
> from_x
&& to_y
> from_y
)
5192 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5193 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5200 /* Clear entire frame. If updating_frame is non-null, clear that
5201 frame. Otherwise clear the selected frame. */
5211 f
= SELECTED_FRAME ();
5213 /* Clearing the frame will erase any cursor, so mark them all as no
5215 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5216 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5217 output_cursor
.x
= -1;
5219 /* We don't set the output cursor here because there will always
5220 follow an explicit cursor_to. */
5222 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5224 /* We have to clear the scroll bars, too. If we have changed
5225 colors or something like that, then they should be notified. */
5226 x_scroll_bar_clear (f
);
5228 XFlush (FRAME_X_DISPLAY (f
));
5234 /* Invert the middle quarter of the frame for .15 sec. */
5236 /* We use the select system call to do the waiting, so we have to make
5237 sure it's available. If it isn't, we just won't do visual bells. */
5239 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5242 /* Subtract the `struct timeval' values X and Y, storing the result in
5243 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5246 timeval_subtract (result
, x
, y
)
5247 struct timeval
*result
, x
, y
;
5249 /* Perform the carry for the later subtraction by updating y. This
5250 is safer because on some systems the tv_sec member is unsigned. */
5251 if (x
.tv_usec
< y
.tv_usec
)
5253 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5254 y
.tv_usec
-= 1000000 * nsec
;
5258 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5260 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5261 y
.tv_usec
+= 1000000 * nsec
;
5265 /* Compute the time remaining to wait. tv_usec is certainly
5267 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5268 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5270 /* Return indication of whether the result should be considered
5272 return x
.tv_sec
< y
.tv_sec
;
5284 /* Create a GC that will use the GXxor function to flip foreground
5285 pixels into background pixels. */
5289 values
.function
= GXxor
;
5290 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5291 ^ f
->output_data
.x
->background_pixel
);
5293 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5294 GCFunction
| GCForeground
, &values
);
5298 /* Get the height not including a menu bar widget. */
5299 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5300 /* Height of each line to flash. */
5301 int flash_height
= FRAME_LINE_HEIGHT (f
);
5302 /* These will be the left and right margins of the rectangles. */
5303 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5304 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5308 /* Don't flash the area between a scroll bar and the frame
5309 edge it is next to. */
5310 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5312 case vertical_scroll_bar_left
:
5313 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5316 case vertical_scroll_bar_right
:
5317 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5324 width
= flash_right
- flash_left
;
5326 /* If window is tall, flash top and bottom line. */
5327 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5329 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5331 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5332 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5333 width
, flash_height
);
5334 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5336 (height
- flash_height
5337 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5338 width
, flash_height
);
5341 /* If it is short, flash it all. */
5342 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5343 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5344 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5349 struct timeval wakeup
;
5351 EMACS_GET_TIME (wakeup
);
5353 /* Compute time to wait until, propagating carry from usecs. */
5354 wakeup
.tv_usec
+= 150000;
5355 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5356 wakeup
.tv_usec
%= 1000000;
5358 /* Keep waiting until past the time wakeup. */
5361 struct timeval timeout
;
5363 EMACS_GET_TIME (timeout
);
5365 /* In effect, timeout = wakeup - timeout.
5366 Break if result would be negative. */
5367 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5370 /* Try to wait that long--but we might wake up sooner. */
5371 select (0, NULL
, NULL
, NULL
, &timeout
);
5375 /* If window is tall, flash top and bottom line. */
5376 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5378 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5380 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5381 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5382 width
, flash_height
);
5383 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5385 (height
- flash_height
5386 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5387 width
, flash_height
);
5390 /* If it is short, flash it all. */
5391 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5392 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5393 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5395 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5403 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5406 /* Make audible bell. */
5411 struct frame
*f
= SELECTED_FRAME ();
5413 if (FRAME_X_DISPLAY (f
))
5415 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5422 XBell (FRAME_X_DISPLAY (f
), 0);
5423 XFlush (FRAME_X_DISPLAY (f
));
5430 /* Specify how many text lines, from the top of the window,
5431 should be affected by insert-lines and delete-lines operations.
5432 This, and those operations, are used only within an update
5433 that is bounded by calls to x_update_begin and x_update_end. */
5436 XTset_terminal_window (n
)
5439 /* This function intentionally left blank. */
5444 /***********************************************************************
5446 ***********************************************************************/
5448 /* Perform an insert-lines or delete-lines operation, inserting N
5449 lines or deleting -N lines at vertical position VPOS. */
5452 x_ins_del_lines (vpos
, n
)
5459 /* Scroll part of the display as described by RUN. */
5462 x_scroll_run (w
, run
)
5466 struct frame
*f
= XFRAME (w
->frame
);
5467 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5469 /* Get frame-relative bounding box of the text display area of W,
5470 without mode lines. Include in this box the flags areas to the
5471 left and right of W. */
5472 window_box (w
, -1, &x
, &y
, &width
, &height
);
5473 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5474 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5476 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5477 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5478 bottom_y
= y
+ height
;
5482 /* Scrolling up. Make sure we don't copy part of the mode
5483 line at the bottom. */
5484 if (from_y
+ run
->height
> bottom_y
)
5485 height
= bottom_y
- from_y
;
5487 height
= run
->height
;
5491 /* Scolling down. Make sure we don't copy over the mode line.
5493 if (to_y
+ run
->height
> bottom_y
)
5494 height
= bottom_y
- to_y
;
5496 height
= run
->height
;
5501 /* Cursor off. Will be switched on again in x_update_window_end. */
5505 XCopyArea (FRAME_X_DISPLAY (f
),
5506 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5507 f
->output_data
.x
->normal_gc
,
5517 /***********************************************************************
5519 ***********************************************************************/
5521 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5522 corner of the exposed rectangle. W and H are width and height of
5523 the exposed area. All are pixel values. W or H zero means redraw
5524 the entire frame. */
5527 expose_frame (f
, x
, y
, w
, h
)
5533 TRACE ((stderr
, "expose_frame "));
5535 /* No need to redraw if frame will be redrawn soon. */
5536 if (FRAME_GARBAGED_P (f
))
5538 TRACE ((stderr
, " garbaged\n"));
5542 /* If basic faces haven't been realized yet, there is no point in
5543 trying to redraw anything. This can happen when we get an expose
5544 event while Emacs is starting, e.g. by moving another window. */
5545 if (FRAME_FACE_CACHE (f
) == NULL
5546 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5548 TRACE ((stderr
, " no faces\n"));
5552 if (w
== 0 || h
== 0)
5555 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5556 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5566 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5567 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5569 if (WINDOWP (f
->tool_bar_window
))
5571 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5572 XRectangle window_rect
;
5573 XRectangle intersection_rect
;
5574 int window_x
, window_y
, window_width
, window_height
;
5577 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5578 window_rect
.x
= window_x
;
5579 window_rect
.y
= window_y
;
5580 window_rect
.width
= window_width
;
5581 window_rect
.height
= window_height
;
5583 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5584 expose_window (w
, &intersection_rect
);
5587 #ifndef USE_X_TOOLKIT
5588 if (WINDOWP (f
->menu_bar_window
))
5590 struct window
*w
= XWINDOW (f
->menu_bar_window
);
5591 XRectangle window_rect
;
5592 XRectangle intersection_rect
;
5593 int window_x
, window_y
, window_width
, window_height
;
5596 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5597 window_rect
.x
= window_x
;
5598 window_rect
.y
= window_y
;
5599 window_rect
.width
= window_width
;
5600 window_rect
.height
= window_height
;
5602 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5603 expose_window (w
, &intersection_rect
);
5605 #endif /* not USE_X_TOOLKIT */
5609 /* Redraw (parts) of all windows in the window tree rooted at W that
5610 intersect R. R contains frame pixel coordinates. */
5613 expose_window_tree (w
, r
)
5619 if (!NILP (w
->hchild
))
5620 expose_window_tree (XWINDOW (w
->hchild
), r
);
5621 else if (!NILP (w
->vchild
))
5622 expose_window_tree (XWINDOW (w
->vchild
), r
);
5625 XRectangle window_rect
;
5626 XRectangle intersection_rect
;
5627 struct frame
*f
= XFRAME (w
->frame
);
5628 int window_x
, window_y
, window_width
, window_height
;
5630 /* Frame-relative pixel rectangle of W. */
5631 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5635 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5636 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5637 window_rect
.y
= window_y
;
5640 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5641 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5643 = window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5645 if (x_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
5646 expose_window (w
, &intersection_rect
);
5649 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5654 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5655 which intersects rectangle R. R is in window-relative coordinates. */
5658 expose_area (w
, row
, r
, area
)
5660 struct glyph_row
*row
;
5662 enum glyph_row_area area
;
5665 struct glyph
*first
= row
->glyphs
[area
];
5666 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5670 /* Set x to the window-relative start position for drawing glyphs of
5671 AREA. The first glyph of the text area can be partially visible.
5672 The first glyphs of other areas cannot. */
5673 if (area
== LEFT_MARGIN_AREA
)
5675 else if (area
== TEXT_AREA
)
5676 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5678 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5679 + window_box_width (w
, TEXT_AREA
));
5681 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5682 /* If row extends face to end of line write the whole line. */
5683 x_draw_glyphs (w
, x
, row
, area
,
5685 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5689 /* Find the first glyph that must be redrawn. */
5691 && x
+ first
->pixel_width
< r
->x
)
5693 x
+= first
->pixel_width
;
5697 /* Find the last one. */
5701 && x
< r
->x
+ r
->width
)
5703 x
+= last
->pixel_width
;
5709 x_draw_glyphs (w
, first_x
, row
, area
,
5710 first
- row
->glyphs
[area
],
5711 last
- row
->glyphs
[area
],
5712 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5718 /* Redraw the parts of the glyph row ROW on window W intersecting
5719 rectangle R. R is in window-relative coordinates. */
5722 expose_line (w
, row
, r
)
5724 struct glyph_row
*row
;
5727 xassert (row
->enabled_p
);
5729 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5730 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5731 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5735 if (row
->used
[LEFT_MARGIN_AREA
])
5736 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5737 if (row
->used
[TEXT_AREA
])
5738 expose_area (w
, row
, r
, TEXT_AREA
);
5739 if (row
->used
[RIGHT_MARGIN_AREA
])
5740 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5741 x_draw_row_bitmaps (w
, row
);
5746 /* Return non-zero if W's cursor intersects rectangle R. */
5749 x_phys_cursor_in_rect_p (w
, r
)
5753 XRectangle cr
, result
;
5754 struct glyph
*cursor_glyph
;
5756 cursor_glyph
= get_phys_cursor_glyph (w
);
5759 cr
.x
= w
->phys_cursor
.x
;
5760 cr
.y
= w
->phys_cursor
.y
;
5761 cr
.width
= cursor_glyph
->pixel_width
;
5762 cr
.height
= w
->phys_cursor_height
;
5763 return x_intersect_rectangles (&cr
, r
, &result
);
5770 /* Redraw a rectangle of window W. R is a rectangle in window
5771 relative coordinates. Call this function with input blocked. */
5774 expose_window (w
, r
)
5778 struct glyph_row
*row
;
5780 int yb
= window_text_bottom_y (w
);
5781 int cursor_cleared_p
;
5783 /* If window is not yet fully initialized, do nothing. This can
5784 happen when toolkit scroll bars are used and a window is split.
5785 Reconfiguring the scroll bar will generate an expose for a newly
5787 if (w
->current_matrix
== NULL
)
5790 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5791 r
->x
, r
->y
, r
->width
, r
->height
));
5793 /* Convert to window coordinates. */
5794 r
->x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->x
);
5795 r
->y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->y
);
5797 /* Turn off the cursor. */
5798 if (!w
->pseudo_window_p
5799 && x_phys_cursor_in_rect_p (w
, r
))
5802 cursor_cleared_p
= 1;
5805 cursor_cleared_p
= 0;
5807 /* Find the first row intersecting the rectangle R. */
5808 row
= w
->current_matrix
->rows
;
5810 while (row
->enabled_p
5812 && y
+ row
->height
< r
->y
)
5818 /* Display the text in the rectangle, one text line at a time. */
5819 while (row
->enabled_p
5821 && y
< r
->y
+ r
->height
)
5823 expose_line (w
, row
, r
);
5828 /* Display the mode line if there is one. */
5829 if (WINDOW_WANTS_MODELINE_P (w
)
5830 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5832 && row
->y
< r
->y
+ r
->height
)
5833 expose_line (w
, row
, r
);
5835 if (!w
->pseudo_window_p
)
5837 /* Draw border between windows. */
5838 x_draw_vertical_border (w
);
5840 /* Turn the cursor on again. */
5841 if (cursor_cleared_p
)
5842 x_update_window_cursor (w
, 1);
5847 /* Determine the intersection of two rectangles R1 and R2. Return
5848 the intersection in *RESULT. Value is non-zero if RESULT is not
5852 x_intersect_rectangles (r1
, r2
, result
)
5853 XRectangle
*r1
, *r2
, *result
;
5855 XRectangle
*left
, *right
;
5856 XRectangle
*upper
, *lower
;
5857 int intersection_p
= 0;
5859 /* Rearrange so that R1 is the left-most rectangle. */
5861 left
= r1
, right
= r2
;
5863 left
= r2
, right
= r1
;
5865 /* X0 of the intersection is right.x0, if this is inside R1,
5866 otherwise there is no intersection. */
5867 if (right
->x
<= left
->x
+ left
->width
)
5869 result
->x
= right
->x
;
5871 /* The right end of the intersection is the minimum of the
5872 the right ends of left and right. */
5873 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
5876 /* Same game for Y. */
5878 upper
= r1
, lower
= r2
;
5880 upper
= r2
, lower
= r1
;
5882 /* The upper end of the intersection is lower.y0, if this is inside
5883 of upper. Otherwise, there is no intersection. */
5884 if (lower
->y
<= upper
->y
+ upper
->height
)
5886 result
->y
= lower
->y
;
5888 /* The lower end of the intersection is the minimum of the lower
5889 ends of upper and lower. */
5890 result
->height
= (min (lower
->y
+ lower
->height
,
5891 upper
->y
+ upper
->height
)
5897 return intersection_p
;
5908 /* We used to only do this if Vx_no_window_manager was non-nil, but
5909 the ICCCM (section 4.1.6) says that the window's border pixmap
5910 and border pixel are window attributes which are "private to the
5911 client", so we can always change it to whatever we want. */
5913 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5914 f
->output_data
.x
->border_pixel
);
5916 x_update_cursor (f
, 1);
5920 frame_unhighlight (f
)
5923 /* We used to only do this if Vx_no_window_manager was non-nil, but
5924 the ICCCM (section 4.1.6) says that the window's border pixmap
5925 and border pixel are window attributes which are "private to the
5926 client", so we can always change it to whatever we want. */
5928 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5929 f
->output_data
.x
->border_tile
);
5931 x_update_cursor (f
, 1);
5934 /* The focus has changed. Update the frames as necessary to reflect
5935 the new situation. Note that we can't change the selected frame
5936 here, because the Lisp code we are interrupting might become confused.
5937 Each event gets marked with the frame in which it occurred, so the
5938 Lisp code can tell when the switch took place by examining the events. */
5941 x_new_focus_frame (dpyinfo
, frame
)
5942 struct x_display_info
*dpyinfo
;
5943 struct frame
*frame
;
5945 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
5947 if (frame
!= dpyinfo
->x_focus_frame
)
5949 /* Set this before calling other routines, so that they see
5950 the correct value of x_focus_frame. */
5951 dpyinfo
->x_focus_frame
= frame
;
5953 if (old_focus
&& old_focus
->auto_lower
)
5954 x_lower_frame (old_focus
);
5957 selected_frame
= frame
;
5958 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
5960 Fselect_window (selected_frame
->selected_window
);
5961 choose_minibuf_frame ();
5964 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
5965 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
5967 pending_autoraise_frame
= 0;
5970 x_frame_rehighlight (dpyinfo
);
5973 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5976 x_mouse_leave (dpyinfo
)
5977 struct x_display_info
*dpyinfo
;
5979 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
5982 /* The focus has changed, or we have redirected a frame's focus to
5983 another frame (this happens when a frame uses a surrogate
5984 mini-buffer frame). Shift the highlight as appropriate.
5986 The FRAME argument doesn't necessarily have anything to do with which
5987 frame is being highlighted or un-highlighted; we only use it to find
5988 the appropriate X display info. */
5991 XTframe_rehighlight (frame
)
5992 struct frame
*frame
;
5994 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
5998 x_frame_rehighlight (dpyinfo
)
5999 struct x_display_info
*dpyinfo
;
6001 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6003 if (dpyinfo
->x_focus_frame
)
6005 dpyinfo
->x_highlight_frame
6006 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6007 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6008 : dpyinfo
->x_focus_frame
);
6009 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6011 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6012 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6016 dpyinfo
->x_highlight_frame
= 0;
6018 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6021 frame_unhighlight (old_highlight
);
6022 if (dpyinfo
->x_highlight_frame
)
6023 frame_highlight (dpyinfo
->x_highlight_frame
);
6029 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6031 /* Initialize mode_switch_bit and modifier_meaning. */
6033 x_find_modifier_meanings (dpyinfo
)
6034 struct x_display_info
*dpyinfo
;
6036 int min_code
, max_code
;
6039 XModifierKeymap
*mods
;
6041 dpyinfo
->meta_mod_mask
= 0;
6042 dpyinfo
->shift_lock_mask
= 0;
6043 dpyinfo
->alt_mod_mask
= 0;
6044 dpyinfo
->super_mod_mask
= 0;
6045 dpyinfo
->hyper_mod_mask
= 0;
6048 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6050 min_code
= dpyinfo
->display
->min_keycode
;
6051 max_code
= dpyinfo
->display
->max_keycode
;
6054 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6055 min_code
, max_code
- min_code
+ 1,
6057 mods
= XGetModifierMapping (dpyinfo
->display
);
6059 /* Scan the modifier table to see which modifier bits the Meta and
6060 Alt keysyms are on. */
6062 int row
, col
; /* The row and column in the modifier table. */
6064 for (row
= 3; row
< 8; row
++)
6065 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6068 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6070 /* Zeroes are used for filler. Skip them. */
6074 /* Are any of this keycode's keysyms a meta key? */
6078 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6080 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6086 dpyinfo
->meta_mod_mask
|= (1 << row
);
6091 dpyinfo
->alt_mod_mask
|= (1 << row
);
6096 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6101 dpyinfo
->super_mod_mask
|= (1 << row
);
6105 /* Ignore this if it's not on the lock modifier. */
6106 if ((1 << row
) == LockMask
)
6107 dpyinfo
->shift_lock_mask
= LockMask
;
6115 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6116 if (! dpyinfo
->meta_mod_mask
)
6118 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6119 dpyinfo
->alt_mod_mask
= 0;
6122 /* If some keys are both alt and meta,
6123 make them just meta, not alt. */
6124 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6126 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6129 XFree ((char *) syms
);
6130 XFreeModifiermap (mods
);
6133 /* Convert between the modifier bits X uses and the modifier bits
6137 x_x_to_emacs_modifiers (dpyinfo
, state
)
6138 struct x_display_info
*dpyinfo
;
6141 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6142 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6143 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6144 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6145 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6146 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6150 x_emacs_to_x_modifiers (dpyinfo
, state
)
6151 struct x_display_info
*dpyinfo
;
6154 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6155 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6156 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6157 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6158 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6159 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6162 /* Convert a keysym to its name. */
6165 x_get_keysym_name (keysym
)
6171 value
= XKeysymToString (keysym
);
6179 /* Mouse clicks and mouse movement. Rah. */
6181 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6182 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6183 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6184 not force the value into range. */
6187 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6189 register int pix_x
, pix_y
;
6190 register int *x
, *y
;
6194 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6195 even for negative values. */
6197 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6199 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6201 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6202 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6206 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6207 bounds
->height
= f
->output_data
.x
->line_height
;
6208 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6209 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6216 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6217 pix_x
= FRAME_WINDOW_WIDTH (f
);
6221 else if (pix_y
> f
->height
)
6230 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6231 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6232 can't tell the positions because W's display is not up to date,
6236 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6239 int *frame_x
, *frame_y
;
6243 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6244 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6246 if (display_completed
)
6248 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6249 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6250 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6256 *frame_x
+= glyph
->pixel_width
;
6264 *frame_y
= *frame_x
= 0;
6268 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6269 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6274 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6276 If the event is a button press, then note that we have grabbed
6280 construct_mouse_click (result
, event
, f
)
6281 struct input_event
*result
;
6282 XButtonEvent
*event
;
6285 /* Make the event type no_event; we'll change that when we decide
6287 result
->kind
= mouse_click
;
6288 result
->code
= event
->button
- Button1
;
6289 result
->timestamp
= event
->time
;
6290 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6292 | (event
->type
== ButtonRelease
6296 XSETINT (result
->x
, event
->x
);
6297 XSETINT (result
->y
, event
->y
);
6298 XSETFRAME (result
->frame_or_window
, f
);
6304 /* Function to report a mouse movement to the mainstream Emacs code.
6305 The input handler calls this.
6307 We have received a mouse movement event, which is given in *event.
6308 If the mouse is over a different glyph than it was last time, tell
6309 the mainstream emacs code by setting mouse_moved. If not, ask for
6310 another motion event, so we can check again the next time it moves. */
6312 static XMotionEvent last_mouse_motion_event
;
6313 static Lisp_Object last_mouse_motion_frame
;
6316 note_mouse_movement (frame
, event
)
6318 XMotionEvent
*event
;
6320 last_mouse_movement_time
= event
->time
;
6321 last_mouse_motion_event
= *event
;
6322 XSETFRAME (last_mouse_motion_frame
, frame
);
6324 if (event
->window
!= FRAME_X_WINDOW (frame
))
6326 frame
->mouse_moved
= 1;
6327 last_mouse_scroll_bar
= Qnil
;
6328 note_mouse_highlight (frame
, -1, -1);
6331 /* Has the mouse moved off the glyph it was on at the last sighting? */
6332 else if (event
->x
< last_mouse_glyph
.x
6333 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6334 || event
->y
< last_mouse_glyph
.y
6335 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6337 frame
->mouse_moved
= 1;
6338 last_mouse_scroll_bar
= Qnil
;
6339 note_mouse_highlight (frame
, event
->x
, event
->y
);
6343 /* This is used for debugging, to turn off note_mouse_highlight. */
6345 int disable_mouse_highlight
;
6349 /************************************************************************
6351 ************************************************************************/
6353 /* Find the glyph under window-relative coordinates X/Y in window W.
6354 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6355 strings. Return in *HPOS and *VPOS the row and column number of
6356 the glyph found. Return in *AREA the glyph area containing X.
6357 Value is a pointer to the glyph found or null if X/Y is not on
6358 text, or we can't tell because W's current matrix is not up to
6361 static struct glyph
*
6362 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6365 int *hpos
, *vpos
, *area
;
6367 struct glyph
*glyph
, *end
;
6368 struct glyph_row
*row
= NULL
;
6369 int x0
, i
, left_area_width
;
6371 /* Find row containing Y. Give up if some row is not enabled. */
6372 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6374 row
= MATRIX_ROW (w
->current_matrix
, i
);
6375 if (!row
->enabled_p
)
6377 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6384 /* Give up if Y is not in the window. */
6385 if (i
== w
->current_matrix
->nrows
)
6388 /* Get the glyph area containing X. */
6389 if (w
->pseudo_window_p
)
6396 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6397 if (x
< left_area_width
)
6399 *area
= LEFT_MARGIN_AREA
;
6402 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6405 x0
= row
->x
+ left_area_width
;
6409 *area
= RIGHT_MARGIN_AREA
;
6410 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6414 /* Find glyph containing X. */
6415 glyph
= row
->glyphs
[*area
];
6416 end
= glyph
+ row
->used
[*area
];
6419 if (x
< x0
+ glyph
->pixel_width
)
6421 if (w
->pseudo_window_p
)
6423 else if (BUFFERP (glyph
->object
))
6427 x0
+= glyph
->pixel_width
;
6434 *hpos
= glyph
- row
->glyphs
[*area
];
6439 /* Convert frame-relative x/y to coordinates relative to window W.
6440 Takes pseudo-windows into account. */
6443 frame_to_window_pixel_xy (w
, x
, y
)
6447 if (w
->pseudo_window_p
)
6449 /* A pseudo-window is always full-width, and starts at the
6450 left edge of the frame, plus a frame border. */
6451 struct frame
*f
= XFRAME (w
->frame
);
6452 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6453 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6457 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6458 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6463 /* Take proper action when mouse has moved to the mode or top line of
6464 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6465 mode line. X is relative to the start of the text display area of
6466 W, so the width of bitmap areas and scroll bars must be subtracted
6467 to get a position relative to the start of the mode line. */
6470 note_mode_line_highlight (w
, x
, mode_line_p
)
6474 struct frame
*f
= XFRAME (w
->frame
);
6475 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6476 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6477 struct glyph_row
*row
;
6480 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6482 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6486 struct glyph
*glyph
, *end
;
6487 Lisp_Object help
, map
;
6490 /* Find the glyph under X. */
6491 glyph
= row
->glyphs
[TEXT_AREA
];
6492 end
= glyph
+ row
->used
[TEXT_AREA
];
6493 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6494 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6496 && x
>= x0
+ glyph
->pixel_width
)
6498 x0
+= glyph
->pixel_width
;
6503 && STRINGP (glyph
->object
)
6504 && XSTRING (glyph
->object
)->intervals
6505 && glyph
->charpos
>= 0
6506 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6508 /* If we're on a string with `help-echo' text property,
6509 arrange for the help to be displayed. This is done by
6510 setting the global variable help_echo to the help string. */
6511 help
= Fget_text_property (make_number (glyph
->charpos
),
6512 Qhelp_echo
, glyph
->object
);
6516 XSETWINDOW (help_echo_window
, w
);
6517 help_echo_object
= glyph
->object
;
6518 help_echo_pos
= glyph
->charpos
;
6521 /* Change the mouse pointer according to what is under X/Y. */
6522 map
= Fget_text_property (make_number (glyph
->charpos
),
6523 Qlocal_map
, glyph
->object
);
6525 cursor
= f
->output_data
.x
->nontext_cursor
;
6528 map
= Fget_text_property (make_number (glyph
->charpos
),
6529 Qkeymap
, glyph
->object
);
6531 cursor
= f
->output_data
.x
->nontext_cursor
;
6536 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6540 /* Take proper action when the mouse has moved to position X, Y on
6541 frame F as regards highlighting characters that have mouse-face
6542 properties. Also de-highlighting chars where the mouse was before.
6543 X and Y can be negative or out of range. */
6546 note_mouse_highlight (f
, x
, y
)
6550 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6555 /* When a menu is active, don't highlight because this looks odd. */
6556 #ifdef USE_X_TOOLKIT
6557 if (popup_activated ())
6561 if (disable_mouse_highlight
6562 || !f
->glyphs_initialized_p
)
6565 dpyinfo
->mouse_face_mouse_x
= x
;
6566 dpyinfo
->mouse_face_mouse_y
= y
;
6567 dpyinfo
->mouse_face_mouse_frame
= f
;
6569 if (dpyinfo
->mouse_face_defer
)
6574 dpyinfo
->mouse_face_deferred_gc
= 1;
6578 /* Which window is that in? */
6579 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6581 /* If we were displaying active text in another window, clear that. */
6582 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6583 clear_mouse_face (dpyinfo
);
6585 /* Not on a window -> return. */
6586 if (!WINDOWP (window
))
6589 /* Convert to window-relative pixel coordinates. */
6590 w
= XWINDOW (window
);
6591 frame_to_window_pixel_xy (w
, &x
, &y
);
6593 /* Handle tool-bar window differently since it doesn't display a
6595 if (EQ (window
, f
->tool_bar_window
))
6597 note_tool_bar_highlight (f
, x
, y
);
6601 if (portion
== 1 || portion
== 3)
6603 /* Mouse is on the mode or top line. */
6604 note_mode_line_highlight (w
, x
, portion
== 1);
6608 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6609 f
->output_data
.x
->text_cursor
);
6611 /* Are we in a window whose display is up to date?
6612 And verify the buffer's text has not changed. */
6613 if (/* Within text portion of the window. */
6615 && EQ (w
->window_end_valid
, w
->buffer
)
6616 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6617 && (XFASTINT (w
->last_overlay_modified
)
6618 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6620 int hpos
, vpos
, pos
, i
, area
;
6621 struct glyph
*glyph
;
6623 /* Find the glyph under X/Y. */
6624 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6626 /* Clear mouse face if X/Y not over text. */
6628 || area
!= TEXT_AREA
6629 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6631 clear_mouse_face (dpyinfo
);
6635 pos
= glyph
->charpos
;
6636 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6638 /* Check for mouse-face and help-echo. */
6640 Lisp_Object mouse_face
, overlay
, position
;
6641 Lisp_Object
*overlay_vec
;
6643 struct buffer
*obuf
;
6646 /* If we get an out-of-range value, return now; avoid an error. */
6647 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6650 /* Make the window's buffer temporarily current for
6651 overlays_at and compute_char_face. */
6652 obuf
= current_buffer
;
6653 current_buffer
= XBUFFER (w
->buffer
);
6659 /* Is this char mouse-active or does it have help-echo? */
6660 XSETINT (position
, pos
);
6662 /* Put all the overlays we want in a vector in overlay_vec.
6663 Store the length in len. If there are more than 10, make
6664 enough space for all, and try again. */
6666 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6667 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6668 if (noverlays
> len
)
6671 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6672 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6675 /* Sort overlays into increasing priority order. */
6676 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6678 /* Check mouse-face highlighting. */
6679 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6680 && vpos
>= dpyinfo
->mouse_face_beg_row
6681 && vpos
<= dpyinfo
->mouse_face_end_row
6682 && (vpos
> dpyinfo
->mouse_face_beg_row
6683 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6684 && (vpos
< dpyinfo
->mouse_face_end_row
6685 || hpos
< dpyinfo
->mouse_face_end_col
6686 || dpyinfo
->mouse_face_past_end
)))
6688 /* Clear the display of the old active region, if any. */
6689 clear_mouse_face (dpyinfo
);
6691 /* Find the highest priority overlay that has a mouse-face prop. */
6693 for (i
= noverlays
- 1; i
>= 0; --i
)
6695 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6696 if (!NILP (mouse_face
))
6698 overlay
= overlay_vec
[i
];
6703 /* If no overlay applies, get a text property. */
6705 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6707 /* Handle the overlay case. */
6708 if (! NILP (overlay
))
6710 /* Find the range of text around this char that
6711 should be active. */
6712 Lisp_Object before
, after
;
6715 before
= Foverlay_start (overlay
);
6716 after
= Foverlay_end (overlay
);
6717 /* Record this as the current active region. */
6718 fast_find_position (w
, XFASTINT (before
),
6719 &dpyinfo
->mouse_face_beg_col
,
6720 &dpyinfo
->mouse_face_beg_row
,
6721 &dpyinfo
->mouse_face_beg_x
,
6722 &dpyinfo
->mouse_face_beg_y
);
6723 dpyinfo
->mouse_face_past_end
6724 = !fast_find_position (w
, XFASTINT (after
),
6725 &dpyinfo
->mouse_face_end_col
,
6726 &dpyinfo
->mouse_face_end_row
,
6727 &dpyinfo
->mouse_face_end_x
,
6728 &dpyinfo
->mouse_face_end_y
);
6729 dpyinfo
->mouse_face_window
= window
;
6730 dpyinfo
->mouse_face_face_id
6731 = face_at_buffer_position (w
, pos
, 0, 0,
6732 &ignore
, pos
+ 1, 1);
6734 /* Display it as active. */
6735 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6737 /* Handle the text property case. */
6738 else if (! NILP (mouse_face
))
6740 /* Find the range of text around this char that
6741 should be active. */
6742 Lisp_Object before
, after
, beginning
, end
;
6745 beginning
= Fmarker_position (w
->start
);
6746 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6747 - XFASTINT (w
->window_end_pos
)));
6749 = Fprevious_single_property_change (make_number (pos
+ 1),
6751 w
->buffer
, beginning
);
6753 = Fnext_single_property_change (position
, Qmouse_face
,
6755 /* Record this as the current active region. */
6756 fast_find_position (w
, XFASTINT (before
),
6757 &dpyinfo
->mouse_face_beg_col
,
6758 &dpyinfo
->mouse_face_beg_row
,
6759 &dpyinfo
->mouse_face_beg_x
,
6760 &dpyinfo
->mouse_face_beg_y
);
6761 dpyinfo
->mouse_face_past_end
6762 = !fast_find_position (w
, XFASTINT (after
),
6763 &dpyinfo
->mouse_face_end_col
,
6764 &dpyinfo
->mouse_face_end_row
,
6765 &dpyinfo
->mouse_face_end_x
,
6766 &dpyinfo
->mouse_face_end_y
);
6767 dpyinfo
->mouse_face_window
= window
;
6768 dpyinfo
->mouse_face_face_id
6769 = face_at_buffer_position (w
, pos
, 0, 0,
6770 &ignore
, pos
+ 1, 1);
6772 /* Display it as active. */
6773 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6777 /* Look for a `help-echo' property. */
6779 Lisp_Object help
, overlay
;
6781 /* Check overlays first. */
6782 help
= overlay
= Qnil
;
6783 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6785 overlay
= overlay_vec
[i
];
6786 help
= Foverlay_get (overlay
, Qhelp_echo
);
6792 help_echo_window
= window
;
6793 help_echo_object
= overlay
;
6794 help_echo_pos
= pos
;
6798 /* Try text properties. */
6799 if ((STRINGP (glyph
->object
)
6800 && glyph
->charpos
>= 0
6801 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6802 || (BUFFERP (glyph
->object
)
6803 && glyph
->charpos
>= BEGV
6804 && glyph
->charpos
< ZV
))
6805 help
= Fget_text_property (make_number (glyph
->charpos
),
6806 Qhelp_echo
, glyph
->object
);
6811 help_echo_window
= window
;
6812 help_echo_object
= glyph
->object
;
6813 help_echo_pos
= glyph
->charpos
;
6820 current_buffer
= obuf
;
6826 redo_mouse_highlight ()
6828 if (!NILP (last_mouse_motion_frame
)
6829 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6830 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6831 last_mouse_motion_event
.x
,
6832 last_mouse_motion_event
.y
);
6837 /***********************************************************************
6839 ***********************************************************************/
6841 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6842 struct glyph
**, int *, int *, int *));
6844 /* Tool-bar item index of the item on which a mouse button was pressed
6847 static int last_tool_bar_item
;
6850 /* Get information about the tool-bar item at position X/Y on frame F.
6851 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6852 the current matrix of the tool-bar window of F, or NULL if not
6853 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6854 item in F->current_tool_bar_items. Value is
6856 -1 if X/Y is not on a tool-bar item
6857 0 if X/Y is on the same item that was highlighted before.
6861 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6864 struct glyph
**glyph
;
6865 int *hpos
, *vpos
, *prop_idx
;
6867 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6868 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6871 /* Find the glyph under X/Y. */
6872 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6876 /* Get the start of this tool-bar item's properties in
6877 f->current_tool_bar_items. */
6878 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6881 /* Is mouse on the highlighted item? */
6882 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6883 && *vpos
>= dpyinfo
->mouse_face_beg_row
6884 && *vpos
<= dpyinfo
->mouse_face_end_row
6885 && (*vpos
> dpyinfo
->mouse_face_beg_row
6886 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6887 && (*vpos
< dpyinfo
->mouse_face_end_row
6888 || *hpos
< dpyinfo
->mouse_face_end_col
6889 || dpyinfo
->mouse_face_past_end
))
6896 /* Handle mouse button event on the tool-bar of frame F, at
6897 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6901 x_handle_tool_bar_click (f
, button_event
)
6903 XButtonEvent
*button_event
;
6905 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6906 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6907 int hpos
, vpos
, prop_idx
;
6908 struct glyph
*glyph
;
6909 Lisp_Object enabled_p
;
6910 int x
= button_event
->x
;
6911 int y
= button_event
->y
;
6913 /* If not on the highlighted tool-bar item, return. */
6914 frame_to_window_pixel_xy (w
, &x
, &y
);
6915 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6918 /* If item is disabled, do nothing. */
6919 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6920 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6921 if (NILP (enabled_p
))
6924 if (button_event
->type
== ButtonPress
)
6926 /* Show item in pressed state. */
6927 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6928 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6929 last_tool_bar_item
= prop_idx
;
6933 Lisp_Object key
, frame
;
6934 struct input_event event
;
6936 /* Show item in released state. */
6937 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6938 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6940 key
= (XVECTOR (f
->current_tool_bar_items
)
6941 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6943 XSETFRAME (frame
, f
);
6944 event
.kind
= TOOL_BAR_EVENT
;
6945 event
.frame_or_window
= frame
;
6947 kbd_buffer_store_event (&event
);
6949 event
.kind
= TOOL_BAR_EVENT
;
6950 event
.frame_or_window
= frame
;
6952 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6953 button_event
->state
);
6954 kbd_buffer_store_event (&event
);
6955 last_tool_bar_item
= -1;
6960 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6961 tool-bar window-relative coordinates X/Y. Called from
6962 note_mouse_highlight. */
6965 note_tool_bar_highlight (f
, x
, y
)
6969 Lisp_Object window
= f
->tool_bar_window
;
6970 struct window
*w
= XWINDOW (window
);
6971 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6973 struct glyph
*glyph
;
6974 struct glyph_row
*row
;
6976 Lisp_Object enabled_p
;
6978 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6979 int mouse_down_p
, rc
;
6981 /* Function note_mouse_highlight is called with negative x(y
6982 values when mouse moves outside of the frame. */
6983 if (x
<= 0 || y
<= 0)
6985 clear_mouse_face (dpyinfo
);
6989 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6992 /* Not on tool-bar item. */
6993 clear_mouse_face (dpyinfo
);
6997 /* On same tool-bar item as before. */
7000 clear_mouse_face (dpyinfo
);
7002 /* Mouse is down, but on different tool-bar item? */
7003 mouse_down_p
= (dpyinfo
->grabbed
7004 && f
== last_mouse_frame
7005 && FRAME_LIVE_P (f
));
7007 && last_tool_bar_item
!= prop_idx
)
7010 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7011 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7013 /* If tool-bar item is not enabled, don't highlight it. */
7014 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
7015 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
7016 if (!NILP (enabled_p
))
7018 /* Compute the x-position of the glyph. In front and past the
7019 image is a space. We include this is the highlighted area. */
7020 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7021 for (i
= x
= 0; i
< hpos
; ++i
)
7022 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7024 /* Record this as the current active region. */
7025 dpyinfo
->mouse_face_beg_col
= hpos
;
7026 dpyinfo
->mouse_face_beg_row
= vpos
;
7027 dpyinfo
->mouse_face_beg_x
= x
;
7028 dpyinfo
->mouse_face_beg_y
= row
->y
;
7029 dpyinfo
->mouse_face_past_end
= 0;
7031 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7032 dpyinfo
->mouse_face_end_row
= vpos
;
7033 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7034 dpyinfo
->mouse_face_end_y
= row
->y
;
7035 dpyinfo
->mouse_face_window
= window
;
7036 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7038 /* Display it as active. */
7039 show_mouse_face (dpyinfo
, draw
);
7040 dpyinfo
->mouse_face_image_state
= draw
;
7045 /* Set help_echo to a help string.to display for this tool-bar item.
7046 XTread_socket does the rest. */
7047 help_echo_object
= help_echo_window
= Qnil
;
7049 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
7050 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
7051 if (NILP (help_echo
))
7052 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
7053 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
7058 /* Find the glyph matrix position of buffer position POS in window W.
7059 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7060 current glyphs must be up to date. If POS is above window start
7061 return (0, 0, 0, 0). If POS is after end of W, return end of
7065 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
7068 int *hpos
, *vpos
, *x
, *y
;
7072 int maybe_next_line_p
= 0;
7073 int line_start_position
;
7074 int yb
= window_text_bottom_y (w
);
7075 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
7076 struct glyph_row
*best_row
= row
;
7077 int row_vpos
= 0, best_row_vpos
= 0;
7082 if (row
->used
[TEXT_AREA
])
7083 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7085 line_start_position
= 0;
7087 if (line_start_position
> pos
)
7089 /* If the position sought is the end of the buffer,
7090 don't include the blank lines at the bottom of the window. */
7091 else if (line_start_position
== pos
7092 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7094 maybe_next_line_p
= 1;
7097 else if (line_start_position
> 0)
7100 best_row_vpos
= row_vpos
;
7103 if (row
->y
+ row
->height
>= yb
)
7110 /* Find the right column within BEST_ROW. */
7112 current_x
= best_row
->x
;
7113 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7115 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7118 charpos
= glyph
->charpos
;
7122 *vpos
= best_row_vpos
;
7127 else if (charpos
> pos
)
7129 else if (charpos
> 0)
7132 current_x
+= glyph
->pixel_width
;
7135 /* If we're looking for the end of the buffer,
7136 and we didn't find it in the line we scanned,
7137 use the start of the following line. */
7138 if (maybe_next_line_p
)
7143 current_x
= best_row
->x
;
7146 *vpos
= best_row_vpos
;
7147 *hpos
= lastcol
+ 1;
7154 /* Display the active region described by mouse_face_*
7155 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7158 show_mouse_face (dpyinfo
, draw
)
7159 struct x_display_info
*dpyinfo
;
7160 enum draw_glyphs_face draw
;
7162 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7163 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7165 int cursor_off_p
= 0;
7166 struct cursor_pos saved_cursor
;
7168 saved_cursor
= output_cursor
;
7170 /* If window is in the process of being destroyed, don't bother
7172 if (w
->current_matrix
== NULL
)
7175 /* Recognize when we are called to operate on rows that don't exist
7176 anymore. This can happen when a window is split. */
7177 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7180 set_output_cursor (&w
->phys_cursor
);
7182 /* Note that mouse_face_beg_row etc. are window relative. */
7183 for (i
= dpyinfo
->mouse_face_beg_row
;
7184 i
<= dpyinfo
->mouse_face_end_row
;
7187 int start_hpos
, end_hpos
, start_x
;
7188 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7190 /* Don't do anything if row doesn't have valid contents. */
7191 if (!row
->enabled_p
)
7194 /* For all but the first row, the highlight starts at column 0. */
7195 if (i
== dpyinfo
->mouse_face_beg_row
)
7197 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7198 start_x
= dpyinfo
->mouse_face_beg_x
;
7206 if (i
== dpyinfo
->mouse_face_end_row
)
7207 end_hpos
= dpyinfo
->mouse_face_end_col
;
7209 end_hpos
= row
->used
[TEXT_AREA
];
7211 /* If the cursor's in the text we are about to rewrite, turn the
7213 if (!w
->pseudo_window_p
7214 && i
== output_cursor
.vpos
7215 && output_cursor
.hpos
>= start_hpos
- 1
7216 && output_cursor
.hpos
<= end_hpos
)
7218 x_update_window_cursor (w
, 0);
7222 if (end_hpos
> start_hpos
)
7224 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
7225 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7226 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7230 /* If we turned the cursor off, turn it back on. */
7232 x_display_cursor (w
, 1,
7233 output_cursor
.hpos
, output_cursor
.vpos
,
7234 output_cursor
.x
, output_cursor
.y
);
7236 output_cursor
= saved_cursor
;
7240 /* Change the mouse cursor. */
7241 if (draw
== DRAW_NORMAL_TEXT
)
7242 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7243 f
->output_data
.x
->text_cursor
);
7244 else if (draw
== DRAW_MOUSE_FACE
)
7245 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7246 f
->output_data
.x
->cross_cursor
);
7248 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7249 f
->output_data
.x
->nontext_cursor
);
7252 /* Clear out the mouse-highlighted active region.
7253 Redraw it un-highlighted first. */
7256 clear_mouse_face (dpyinfo
)
7257 struct x_display_info
*dpyinfo
;
7262 if (! NILP (dpyinfo
->mouse_face_window
))
7263 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7265 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7266 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7267 dpyinfo
->mouse_face_window
= Qnil
;
7271 /* Clear any mouse-face on window W. This function is part of the
7272 redisplay interface, and is called from try_window_id and similar
7273 functions to ensure the mouse-highlight is off. */
7276 x_clear_mouse_face (w
)
7279 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7283 XSETWINDOW (window
, w
);
7284 if (EQ (window
, dpyinfo
->mouse_face_window
))
7285 clear_mouse_face (dpyinfo
);
7290 /* Just discard the mouse face information for frame F, if any.
7291 This is used when the size of F is changed. */
7294 cancel_mouse_face (f
)
7298 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7300 window
= dpyinfo
->mouse_face_window
;
7301 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7303 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7304 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7305 dpyinfo
->mouse_face_window
= Qnil
;
7309 static struct scroll_bar
*x_window_to_scroll_bar ();
7310 static void x_scroll_bar_report_motion ();
7312 /* Return the current position of the mouse.
7313 *fp should be a frame which indicates which display to ask about.
7315 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7316 and *part to the frame, window, and scroll bar part that the mouse
7317 is over. Set *x and *y to the portion and whole of the mouse's
7318 position on the scroll bar.
7320 If the mouse movement started elsewhere, set *fp to the frame the
7321 mouse is on, *bar_window to nil, and *x and *y to the character cell
7324 Set *time to the server time-stamp for the time at which the mouse
7325 was at this position.
7327 Don't store anything if we don't have a valid set of values to report.
7329 This clears the mouse_moved flag, so we can wait for the next mouse
7333 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7336 Lisp_Object
*bar_window
;
7337 enum scroll_bar_part
*part
;
7339 unsigned long *time
;
7345 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7346 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7352 Window dummy_window
;
7355 Lisp_Object frame
, tail
;
7357 /* Clear the mouse-moved flag for every frame on this display. */
7358 FOR_EACH_FRAME (tail
, frame
)
7359 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7360 XFRAME (frame
)->mouse_moved
= 0;
7362 last_mouse_scroll_bar
= Qnil
;
7364 /* Figure out which root window we're on. */
7365 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7366 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7368 /* The root window which contains the pointer. */
7371 /* Trash which we can't trust if the pointer is on
7372 a different screen. */
7375 /* The position on that root window. */
7378 /* More trash we can't trust. */
7381 /* Modifier keys and pointer buttons, about which
7383 (unsigned int *) &dummy
);
7385 /* Now we have a position on the root; find the innermost window
7386 containing the pointer. */
7390 int parent_x
= 0, parent_y
= 0;
7395 /* XTranslateCoordinates can get errors if the window
7396 structure is changing at the same time this function
7397 is running. So at least we must not crash from them. */
7399 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
7401 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7402 && FRAME_LIVE_P (last_mouse_frame
))
7404 /* If mouse was grabbed on a frame, give coords for that frame
7405 even if the mouse is now outside it. */
7406 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7408 /* From-window, to-window. */
7409 root
, FRAME_X_WINDOW (last_mouse_frame
),
7411 /* From-position, to-position. */
7412 root_x
, root_y
, &win_x
, &win_y
,
7416 f1
= last_mouse_frame
;
7422 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7424 /* From-window, to-window. */
7427 /* From-position, to-position. */
7428 root_x
, root_y
, &win_x
, &win_y
,
7433 if (child
== None
|| child
== win
)
7441 /* Now we know that:
7442 win is the innermost window containing the pointer
7443 (XTC says it has no child containing the pointer),
7444 win_x and win_y are the pointer's position in it
7445 (XTC did this the last time through), and
7446 parent_x and parent_y are the pointer's position in win's parent.
7447 (They are what win_x and win_y were when win was child.
7448 If win is the root window, it has no parent, and
7449 parent_{x,y} are invalid, but that's okay, because we'll
7450 never use them in that case.) */
7452 /* Is win one of our frames? */
7453 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
7456 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
7459 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
7461 /* If not, is it one of our scroll bars? */
7464 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
7468 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7474 if (f1
== 0 && insist
> 0)
7475 f1
= SELECTED_FRAME ();
7479 /* Ok, we found a frame. Store all the values.
7480 last_mouse_glyph is a rectangle used to reduce the
7481 generation of mouse events. To not miss any motion
7482 events, we must divide the frame into rectangles of the
7483 size of the smallest character that could be displayed
7484 on it, i.e. into the same rectangles that matrices on
7485 the frame are divided into. */
7487 #if OLD_REDISPLAY_CODE
7488 int ignore1
, ignore2
;
7489 pixel_to_glyph_coords (f1
, win_x
, win_y
, &ignore1
, &ignore2
,
7491 FRAME_X_DISPLAY_INFO (f1
)->grabbed
7495 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7496 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7500 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7501 round down even for negative values. */
7507 last_mouse_glyph
.width
= width
;
7508 last_mouse_glyph
.height
= height
;
7509 last_mouse_glyph
.x
= (x
+ width
- 1) / width
* width
;
7510 last_mouse_glyph
.y
= (y
+ height
- 1) / height
* height
;
7517 XSETINT (*x
, win_x
);
7518 XSETINT (*y
, win_y
);
7519 *time
= last_mouse_movement_time
;
7528 #ifdef USE_X_TOOLKIT
7530 /* Atimer callback function for TIMER. Called every 0.1s to process
7531 Xt timeouts, if needed. We must avoid calling XtAppPending as
7532 much as possible because that function does an implicit XFlush
7533 that slows us down. */
7536 x_process_timeouts (timer
)
7537 struct atimer
*timer
;
7539 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
7542 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
7543 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
7548 #endif /* USE_X_TOOLKIT */
7551 /* Scroll bar support. */
7553 /* Given an X window ID, find the struct scroll_bar which manages it.
7554 This can be called in GC, so we have to make sure to strip off mark
7557 static struct scroll_bar
*
7558 x_window_to_scroll_bar (window_id
)
7563 for (tail
= Vframe_list
;
7564 XGCTYPE (tail
) == Lisp_Cons
;
7567 Lisp_Object frame
, bar
, condemned
;
7569 frame
= XCAR (tail
);
7570 /* All elements of Vframe_list should be frames. */
7571 if (! GC_FRAMEP (frame
))
7574 /* Scan this frame's scroll bar list for a scroll bar with the
7576 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7577 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7578 /* This trick allows us to search both the ordinary and
7579 condemned scroll bar lists with one loop. */
7580 ! GC_NILP (bar
) || (bar
= condemned
,
7583 bar
= XSCROLL_BAR (bar
)->next
)
7584 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7585 return XSCROLL_BAR (bar
);
7593 /************************************************************************
7595 ************************************************************************/
7597 #if USE_TOOLKIT_SCROLL_BARS
7599 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
7600 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
7601 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
7602 struct scroll_bar
*));
7603 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
7607 /* Id of action hook installed for scroll bars. */
7609 static XtActionHookId action_hook_id
;
7611 /* Lisp window being scrolled. Set when starting to interact with
7612 a toolkit scroll bar, reset to nil when ending the interaction. */
7614 static Lisp_Object window_being_scrolled
;
7616 /* Last scroll bar part sent in xm_scroll_callback. */
7618 static int last_scroll_bar_part
;
7620 /* Whether this is an Xaw with arrow-scrollbars. This should imply
7621 that movements of 1/20 of the screen size are mapped to up/down. */
7623 static Boolean xaw3d_arrow_scroll
;
7625 /* Whether the drag scrolling maintains the mouse at the top of the
7626 thumb. If not, resizing the thumb needs to be done more carefully
7627 to avoid jerkyness. */
7629 static Boolean xaw3d_pick_top
;
7632 /* Action hook installed via XtAppAddActionHook when toolkit scroll
7633 bars are used.. The hook is responsible for detecting when
7634 the user ends an interaction with the scroll bar, and generates
7635 a `end-scroll' scroll_bar_click' event if so. */
7638 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
7641 XtPointer client_data
;
7645 Cardinal
*num_params
;
7651 scroll_bar_p
= XmIsScrollBar (widget
);
7652 end_action
= "Release";
7653 #else /* !USE_MOTIF i.e. use Xaw */
7654 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
7655 end_action
= "EndScroll";
7656 #endif /* USE_MOTIF */
7659 && strcmp (action_name
, end_action
) == 0
7660 && WINDOWP (window_being_scrolled
))
7664 x_send_scroll_bar_event (window_being_scrolled
,
7665 scroll_bar_end_scroll
, 0, 0);
7666 w
= XWINDOW (window_being_scrolled
);
7667 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
7668 window_being_scrolled
= Qnil
;
7669 last_scroll_bar_part
= -1;
7671 /* Xt timeouts no longer needed. */
7672 toolkit_scroll_bar_interaction
= 0;
7677 /* Send a client message with message type Xatom_Scrollbar for a
7678 scroll action to the frame of WINDOW. PART is a value identifying
7679 the part of the scroll bar that was clicked on. PORTION is the
7680 amount to scroll of a whole of WHOLE. */
7683 x_send_scroll_bar_event (window
, part
, portion
, whole
)
7685 int part
, portion
, whole
;
7688 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
7689 struct frame
*f
= XFRAME (XWINDOW (window
)->frame
);
7691 /* Construct a ClientMessage event to send to the frame. */
7692 ev
->type
= ClientMessage
;
7693 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
7694 ev
->display
= FRAME_X_DISPLAY (f
);
7695 ev
->window
= FRAME_X_WINDOW (f
);
7697 ev
->data
.l
[0] = (long) XFASTINT (window
);
7698 ev
->data
.l
[1] = (long) part
;
7699 ev
->data
.l
[2] = (long) 0;
7700 ev
->data
.l
[3] = (long) portion
;
7701 ev
->data
.l
[4] = (long) whole
;
7703 /* Make Xt timeouts work while the scroll bar is active. */
7704 toolkit_scroll_bar_interaction
= 1;
7706 /* Setting the event mask to zero means that the message will
7707 be sent to the client that created the window, and if that
7708 window no longer exists, no event will be sent. */
7710 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
7715 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
7719 x_scroll_bar_to_input_event (event
, ievent
)
7721 struct input_event
*ievent
;
7723 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
7727 XSETFASTINT (window
, ev
->data
.l
[0]);
7728 f
= XFRAME (XWINDOW (window
)->frame
);
7730 ievent
->kind
= scroll_bar_click
;
7731 ievent
->frame_or_window
= window
;
7733 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
7734 ievent
->part
= ev
->data
.l
[1];
7735 ievent
->code
= ev
->data
.l
[2];
7736 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
7737 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
7738 ievent
->modifiers
= 0;
7744 /* Minimum and maximum values used for Motif scroll bars. */
7747 #define XM_SB_MAX 10000000
7748 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
7751 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
7752 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
7753 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
7756 xm_scroll_callback (widget
, client_data
, call_data
)
7758 XtPointer client_data
, call_data
;
7760 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7761 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
7763 int part
= -1, whole
= 0, portion
= 0;
7767 case XmCR_DECREMENT
:
7768 bar
->dragging
= Qnil
;
7769 part
= scroll_bar_up_arrow
;
7772 case XmCR_INCREMENT
:
7773 bar
->dragging
= Qnil
;
7774 part
= scroll_bar_down_arrow
;
7777 case XmCR_PAGE_DECREMENT
:
7778 bar
->dragging
= Qnil
;
7779 part
= scroll_bar_above_handle
;
7782 case XmCR_PAGE_INCREMENT
:
7783 bar
->dragging
= Qnil
;
7784 part
= scroll_bar_below_handle
;
7788 bar
->dragging
= Qnil
;
7789 part
= scroll_bar_to_top
;
7792 case XmCR_TO_BOTTOM
:
7793 bar
->dragging
= Qnil
;
7794 part
= scroll_bar_to_bottom
;
7800 int dragging_down_p
= (INTEGERP (bar
->dragging
)
7801 && XINT (bar
->dragging
) <= cs
->value
);
7803 /* Get the slider size. */
7805 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
7808 /* At the max position of the scroll bar, do a line-wise
7809 movement. Without doing anything, the LessTif scroll bar
7810 calls us with the same cs->value again and again. If we
7811 want to make sure that we can reach the end of the buffer,
7812 we have to do something.
7814 Implementation note: setting bar->dragging always to
7815 cs->value gives a smoother movement at the max position.
7816 Setting it to nil when doing line-wise movement gives
7817 a better slider behavior. */
7819 if (cs
->value
+ slider_size
== XM_SB_MAX
7821 && last_scroll_bar_part
== scroll_bar_down_arrow
))
7823 part
= scroll_bar_down_arrow
;
7824 bar
->dragging
= Qnil
;
7828 whole
= XM_SB_RANGE
;
7829 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
7830 part
= scroll_bar_handle
;
7831 bar
->dragging
= make_number (cs
->value
);
7836 case XmCR_VALUE_CHANGED
:
7842 window_being_scrolled
= bar
->window
;
7843 last_scroll_bar_part
= part
;
7844 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
7849 #else /* !USE_MOTIF, i.e. Xaw. */
7852 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
7853 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
7854 scroll bar struct. CALL_DATA is a pointer to a float saying where
7858 xaw_jump_callback (widget
, client_data
, call_data
)
7860 XtPointer client_data
, call_data
;
7862 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7863 float top
= *(float *) call_data
;
7865 int whole
, portion
, height
;
7868 /* Get the size of the thumb, a value between 0 and 1. */
7870 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
7874 portion
= shown
< 1 ? top
* whole
: 0;
7876 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
7877 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
7878 the bottom, so we force the scrolling whenever we see that we're
7879 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
7880 we try to ensure that we always stay two pixels away from the
7882 part
= scroll_bar_down_arrow
;
7884 part
= scroll_bar_handle
;
7886 window_being_scrolled
= bar
->window
;
7887 bar
->dragging
= make_number (portion
);
7888 last_scroll_bar_part
= part
;
7889 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
7893 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
7894 i.e. line or page up or down. WIDGET is the Xaw scroll bar
7895 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
7896 the scroll bar. CALL_DATA is an integer specifying the action that
7897 has taken place. It's magnitude is in the range 0..height of the
7898 scroll bar. Negative values mean scroll towards buffer start.
7899 Values < height of scroll bar mean line-wise movement. */
7902 xaw_scroll_callback (widget
, client_data
, call_data
)
7904 XtPointer client_data
, call_data
;
7906 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7907 int position
= (int) call_data
;
7911 /* Get the height of the scroll bar. */
7913 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
7916 if (abs (position
) >= height
)
7917 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
7919 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
7920 it maps line-movement to call_data = max(5, height/20). */
7921 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
7922 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
7924 part
= scroll_bar_move_ratio
;
7926 window_being_scrolled
= bar
->window
;
7927 bar
->dragging
= Qnil
;
7928 last_scroll_bar_part
= part
;
7929 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
7933 #endif /* not USE_MOTIF */
7936 /* Create the widget for scroll bar BAR on frame F. Record the widget
7937 and X window of the scroll bar in BAR. */
7940 x_create_toolkit_scroll_bar (f
, bar
)
7942 struct scroll_bar
*bar
;
7948 char *scroll_bar_name
= "verticalScrollBar";
7949 unsigned long pixel
;
7954 /* LessTif 0.85, problems:
7956 1. When the mouse if over the scroll bar, the scroll bar will
7957 get keyboard events. I didn't find a way to turn this off.
7959 2. Do we have to explicitly set the cursor to get an arrow
7960 cursor (see below)? */
7962 /* Set resources. Create the widget. */
7963 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
7964 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
7965 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
7966 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
7967 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
7968 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
7969 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
7971 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
7974 XtSetArg (av
[ac
], XmNforeground
, pixel
);
7978 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
7981 XtSetArg (av
[ac
], XmNbackground
, pixel
);
7985 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
7986 scroll_bar_name
, av
, ac
);
7988 /* Add one callback for everything that can happen. */
7989 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
7991 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
7993 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
7995 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
7997 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
7999 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8001 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8004 /* Realize the widget. Only after that is the X window created. */
8005 XtRealizeWidget (widget
);
8007 /* Set the cursor to an arrow. I didn't find a resource to do that.
8008 And I'm wondering why it hasn't an arrow cursor by default. */
8009 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8010 f
->output_data
.x
->nontext_cursor
);
8012 #else /* !USE_MOTIF i.e. use Xaw */
8014 /* Set resources. Create the widget. The background of the
8015 Xaw3d scroll bar widget is a little bit light for my taste.
8016 We don't alter it here to let users change it according
8017 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8018 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8019 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8020 /* For smoother scrolling with Xaw3d -sm */
8021 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8022 /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
8024 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8027 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8031 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8034 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8038 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8039 f
->output_data
.x
->edit_widget
, av
, ac
);
8043 char *val
= initial
;
8044 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8045 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8047 { /* ARROW_SCROLL */
8048 xaw3d_arrow_scroll
= True
;
8049 /* Isn't that just a personal preference ? -sm */
8050 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8054 /* Define callbacks. */
8055 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8056 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8059 /* Realize the widget. Only after that is the X window created. */
8060 XtRealizeWidget (widget
);
8062 #endif /* !USE_MOTIF */
8064 /* Install an action hook that let's us detect when the user
8065 finishes interacting with a scroll bar. */
8066 if (action_hook_id
== 0)
8067 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8069 /* Remember X window and widget in the scroll bar vector. */
8070 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8071 xwindow
= XtWindow (widget
);
8072 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8078 /* Set the thumb size and position of scroll bar BAR. We are currently
8079 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8082 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8083 struct scroll_bar
*bar
;
8084 int portion
, position
, whole
;
8087 Widget widget
= SCROLL_BAR_X_WIDGET (bar
);
8093 top
= (float) position
/ whole
;
8094 shown
= (float) portion
/ whole
;
8102 Boolean arrow1_selected
, arrow2_selected
;
8103 unsigned char flags
;
8104 XmScrollBarWidget sb
;
8106 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8107 is the scroll bar's maximum and MIN is the scroll bar's minimum
8109 size
= shown
* XM_SB_RANGE
;
8110 size
= min (size
, XM_SB_RANGE
);
8111 size
= max (size
, 1);
8113 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8114 value
= top
* XM_SB_RANGE
;
8115 value
= min (value
, XM_SB_MAX
- size
);
8116 value
= max (value
, XM_SB_MIN
);
8118 /* LessTif: Calling XmScrollBarSetValues after an increment or
8119 decrement turns off auto-repeat LessTif-internally. This can
8120 be seen in ScrollBar.c which resets Arrow1Selected and
8121 Arrow2Selected. It also sets internal flags so that LessTif
8122 believes the mouse is in the slider. We either have to change
8123 our code, or work around that by accessing private data. */
8125 sb
= (XmScrollBarWidget
) widget
;
8126 arrow1_selected
= sb
->scrollBar
.arrow1_selected
;
8127 arrow2_selected
= sb
->scrollBar
.arrow2_selected
;
8128 flags
= sb
->scrollBar
.flags
;
8130 if (NILP (bar
->dragging
))
8131 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8132 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8133 /* This has the negative side effect that the slider value is
8134 not what it would be if we scrolled here using line-wise or
8135 page-wise movement. */
8136 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8139 /* If currently dragging, only update the slider size.
8140 This reduces flicker effects. */
8141 int old_value
, old_size
, increment
, page_increment
;
8143 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8144 &increment
, &page_increment
);
8145 XmScrollBarSetValues (widget
, old_value
,
8146 min (size
, XM_SB_RANGE
- old_value
),
8150 sb
->scrollBar
.arrow1_selected
= arrow1_selected
;
8151 sb
->scrollBar
.arrow2_selected
= arrow2_selected
;
8152 sb
->scrollBar
.flags
= flags
;
8154 #else /* !USE_MOTIF i.e. use Xaw */
8156 float old_top
, old_shown
;
8158 XtVaGetValues (widget
,
8159 XtNtopOfThumb
, &old_top
,
8160 XtNshown
, &old_shown
,
8164 /* Massage the top+shown values. */
8165 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8166 top
= max (0, min (1, top
));
8169 /* Keep two pixels available for moving the thumb down. */
8170 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8172 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8173 check that your system's configuration file contains a define
8174 for `NARROWPROTO'. See s/freebsd.h for an example. */
8175 if (top
!= old_top
|| shown
!= old_shown
)
8177 if (NILP (bar
->dragging
))
8178 XawScrollbarSetThumb (widget
, top
, shown
);
8182 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8183 int scroll_mode
= 0;
8185 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8186 if (xaw3d_arrow_scroll
)
8188 /* Xaw3d stupidly ignores resize requests while dragging
8189 so we have to make it believe it's not in dragging mode. */
8190 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8191 if (scroll_mode
== 2)
8192 sb
->scrollbar
.scroll_mode
= 0;
8195 /* Try to make the scrolling a tad smoother. */
8196 if (!xaw3d_pick_top
)
8197 shown
= min (shown
, old_shown
);
8199 XawScrollbarSetThumb (widget
, top
, shown
);
8202 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8203 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8208 #endif /* !USE_MOTIF */
8213 #endif /* USE_TOOLKIT_SCROLL_BARS */
8217 /************************************************************************
8218 Scroll bars, general
8219 ************************************************************************/
8221 /* Create a scroll bar and return the scroll bar vector for it. W is
8222 the Emacs window on which to create the scroll bar. TOP, LEFT,
8223 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8226 static struct scroll_bar
*
8227 x_scroll_bar_create (w
, top
, left
, width
, height
)
8229 int top
, left
, width
, height
;
8231 struct frame
*f
= XFRAME (w
->frame
);
8232 struct scroll_bar
*bar
8233 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8237 #if USE_TOOLKIT_SCROLL_BARS
8238 x_create_toolkit_scroll_bar (f
, bar
);
8239 #else /* not USE_TOOLKIT_SCROLL_BARS */
8241 XSetWindowAttributes a
;
8245 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8246 if (a
.background_pixel
== -1)
8247 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8249 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8250 | ButtonMotionMask
| PointerMotionHintMask
8252 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8254 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8256 /* Clear the area of W that will serve as a scroll bar. This is
8257 for the case that a window has been split horizontally. In
8258 this case, no clear_frame is generated to reduce flickering. */
8259 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8261 window_box_height (w
), False
);
8263 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8264 /* Position and size of scroll bar. */
8265 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8267 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8269 /* Border width, depth, class, and visual. */
8276 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8278 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8280 XSETWINDOW (bar
->window
, w
);
8281 XSETINT (bar
->top
, top
);
8282 XSETINT (bar
->left
, left
);
8283 XSETINT (bar
->width
, width
);
8284 XSETINT (bar
->height
, height
);
8285 XSETINT (bar
->start
, 0);
8286 XSETINT (bar
->end
, 0);
8287 bar
->dragging
= Qnil
;
8289 /* Add bar to its frame's list of scroll bars. */
8290 bar
->next
= FRAME_SCROLL_BARS (f
);
8292 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8293 if (!NILP (bar
->next
))
8294 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8296 /* Map the window/widget. */
8297 #if USE_TOOLKIT_SCROLL_BARS
8298 XtMapWidget (SCROLL_BAR_X_WIDGET (bar
));
8299 XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar
),
8300 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8302 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8304 #else /* not USE_TOOLKIT_SCROLL_BARS */
8305 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8306 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8313 /* Draw BAR's handle in the proper position.
8315 If the handle is already drawn from START to END, don't bother
8316 redrawing it, unless REBUILD is non-zero; in that case, always
8317 redraw it. (REBUILD is handy for drawing the handle after expose
8320 Normally, we want to constrain the start and end of the handle to
8321 fit inside its rectangle, but if the user is dragging the scroll
8322 bar handle, we want to let them drag it down all the way, so that
8323 the bar's top is as far down as it goes; otherwise, there's no way
8324 to move to the very end of the buffer. */
8326 #ifndef USE_TOOLKIT_SCROLL_BARS
8329 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8330 struct scroll_bar
*bar
;
8334 int dragging
= ! NILP (bar
->dragging
);
8335 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8336 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8337 GC gc
= f
->output_data
.x
->normal_gc
;
8339 /* If the display is already accurate, do nothing. */
8341 && start
== XINT (bar
->start
)
8342 && end
== XINT (bar
->end
))
8348 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
8349 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8350 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8352 /* Make sure the values are reasonable, and try to preserve
8353 the distance between start and end. */
8355 int length
= end
- start
;
8359 else if (start
> top_range
)
8361 end
= start
+ length
;
8365 else if (end
> top_range
&& ! dragging
)
8369 /* Store the adjusted setting in the scroll bar. */
8370 XSETINT (bar
->start
, start
);
8371 XSETINT (bar
->end
, end
);
8373 /* Clip the end position, just for display. */
8374 if (end
> top_range
)
8377 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
8378 below top positions, to make sure the handle is always at least
8379 that many pixels tall. */
8380 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8382 /* Draw the empty space above the handle. Note that we can't clear
8383 zero-height areas; that means "clear to end of window." */
8385 XClearArea (FRAME_X_DISPLAY (f
), w
,
8387 /* x, y, width, height, and exposures. */
8388 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8389 VERTICAL_SCROLL_BAR_TOP_BORDER
,
8390 inside_width
, start
,
8393 /* Change to proper foreground color if one is specified. */
8394 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8395 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8396 f
->output_data
.x
->scroll_bar_foreground_pixel
);
8398 /* Draw the handle itself. */
8399 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8401 /* x, y, width, height */
8402 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8403 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
8404 inside_width
, end
- start
);
8406 /* Restore the foreground color of the GC if we changed it above. */
8407 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8408 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8409 f
->output_data
.x
->foreground_pixel
);
8411 /* Draw the empty space below the handle. Note that we can't
8412 clear zero-height areas; that means "clear to end of window." */
8413 if (end
< inside_height
)
8414 XClearArea (FRAME_X_DISPLAY (f
), w
,
8416 /* x, y, width, height, and exposures. */
8417 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8418 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
8419 inside_width
, inside_height
- end
,
8427 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8429 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8433 x_scroll_bar_remove (bar
)
8434 struct scroll_bar
*bar
;
8438 #if USE_TOOLKIT_SCROLL_BARS
8439 XtDestroyWidget (SCROLL_BAR_X_WIDGET (bar
));
8440 #else /* not USE_TOOLKIT_SCROLL_BARS */
8442 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8443 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8445 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8447 /* Disassociate this scroll bar from its window. */
8448 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8454 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8455 that we are displaying PORTION characters out of a total of WHOLE
8456 characters, starting at POSITION. If WINDOW has no scroll bar,
8460 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8462 int portion
, whole
, position
;
8464 struct frame
*f
= XFRAME (w
->frame
);
8465 struct scroll_bar
*bar
;
8466 int top
, height
, left
, sb_left
, width
, sb_width
;
8467 int window_x
, window_y
, window_width
, window_height
;
8469 /* Get window dimensions. */
8470 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8472 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8473 height
= window_height
;
8475 /* Compute the left edge of the scroll bar area. */
8476 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8477 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8479 left
= XFASTINT (w
->left
);
8480 left
*= CANON_X_UNIT (f
);
8481 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8483 /* Compute the width of the scroll bar which might be less than
8484 the width of the area reserved for the scroll bar. */
8485 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8486 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8490 /* Compute the left edge of the scroll bar. */
8491 #ifdef USE_TOOLKIT_SCROLL_BARS
8492 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8493 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8495 sb_left
= left
+ (width
- sb_width
) / 2;
8497 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8498 sb_left
= left
+ width
- sb_width
;
8503 /* Does the scroll bar exist yet? */
8504 if (NILP (w
->vertical_scroll_bar
))
8507 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8508 left
, top
, width
, height
, False
);
8510 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8514 /* It may just need to be moved and resized. */
8515 unsigned int mask
= 0;
8517 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8521 if (sb_left
!= XINT (bar
->left
))
8523 if (top
!= XINT (bar
->top
))
8525 if (sb_width
!= XINT (bar
->width
))
8527 if (height
!= XINT (bar
->height
))
8530 #ifdef USE_TOOLKIT_SCROLL_BARS
8532 /* Since toolkit scroll bars are smaller than the space reserved
8533 for them on the frame, we have to clear "under" them. */
8534 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8535 left
, top
, width
, height
, False
);
8537 /* Move/size the scroll bar widget. */
8539 XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar
),
8540 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8542 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8545 #else /* not USE_TOOLKIT_SCROLL_BARS */
8547 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
8549 /* Clear areas not covered by the scroll bar. This makes sure a
8550 previous mode line display is cleared after C-x 2 C-x 1, for
8551 example. Non-toolkit scroll bars are as wide as the area
8552 reserved for scroll bars - trim at both sides. */
8553 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8554 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8556 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8557 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8558 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8562 /* Move/size the scroll bar window. */
8567 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
8569 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
8571 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
8575 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8577 /* Remember new settings. */
8578 XSETINT (bar
->left
, sb_left
);
8579 XSETINT (bar
->top
, top
);
8580 XSETINT (bar
->width
, sb_width
);
8581 XSETINT (bar
->height
, height
);
8586 #if USE_TOOLKIT_SCROLL_BARS
8587 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
8588 #else /* not USE_TOOLKIT_SCROLL_BARS */
8589 /* Set the scroll bar's current state, unless we're currently being
8591 if (NILP (bar
->dragging
))
8593 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8596 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8599 int start
= ((double) position
* top_range
) / whole
;
8600 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8601 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8604 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8606 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8610 /* The following three hooks are used when we're doing a thorough
8611 redisplay of the frame. We don't explicitly know which scroll bars
8612 are going to be deleted, because keeping track of when windows go
8613 away is a real pain - "Can you say set-window-configuration, boys
8614 and girls?" Instead, we just assert at the beginning of redisplay
8615 that *all* scroll bars are to be removed, and then save a scroll bar
8616 from the fiery pit when we actually redisplay its window. */
8618 /* Arrange for all scroll bars on FRAME to be removed at the next call
8619 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8620 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8623 XTcondemn_scroll_bars (frame
)
8626 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8627 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8630 bar
= FRAME_SCROLL_BARS (frame
);
8631 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8632 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8633 XSCROLL_BAR (bar
)->prev
= Qnil
;
8634 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8635 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8636 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8640 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8641 Note that WINDOW isn't necessarily condemned at all. */
8643 XTredeem_scroll_bar (window
)
8644 struct window
*window
;
8646 struct scroll_bar
*bar
;
8648 /* We can't redeem this window's scroll bar if it doesn't have one. */
8649 if (NILP (window
->vertical_scroll_bar
))
8652 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8654 /* Unlink it from the condemned list. */
8656 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8658 if (NILP (bar
->prev
))
8660 /* If the prev pointer is nil, it must be the first in one of
8662 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8663 /* It's not condemned. Everything's fine. */
8665 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8666 window
->vertical_scroll_bar
))
8667 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8669 /* If its prev pointer is nil, it must be at the front of
8670 one or the other! */
8674 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8676 if (! NILP (bar
->next
))
8677 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8679 bar
->next
= FRAME_SCROLL_BARS (f
);
8681 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8682 if (! NILP (bar
->next
))
8683 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8687 /* Remove all scroll bars on FRAME that haven't been saved since the
8688 last call to `*condemn_scroll_bars_hook'. */
8691 XTjudge_scroll_bars (f
)
8694 Lisp_Object bar
, next
;
8696 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8698 /* Clear out the condemned list now so we won't try to process any
8699 more events on the hapless scroll bars. */
8700 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8702 for (; ! NILP (bar
); bar
= next
)
8704 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8706 x_scroll_bar_remove (b
);
8709 b
->next
= b
->prev
= Qnil
;
8712 /* Now there should be no references to the condemned scroll bars,
8713 and they should get garbage-collected. */
8717 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
8718 is a no-op when using toolkit scroll bars.
8720 This may be called from a signal handler, so we have to ignore GC
8724 x_scroll_bar_expose (bar
, event
)
8725 struct scroll_bar
*bar
;
8728 #ifndef USE_TOOLKIT_SCROLL_BARS
8730 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8731 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8732 GC gc
= f
->output_data
.x
->normal_gc
;
8733 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
8737 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
8739 /* Draw a one-pixel border just inside the edges of the scroll bar. */
8740 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8742 /* x, y, width, height */
8744 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
8745 XINT (bar
->height
) - 1);
8749 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8752 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8753 is set to something other than no_event, it is enqueued.
8755 This may be called from a signal handler, so we have to ignore GC
8758 #ifndef USE_TOOLKIT_SCROLL_BARS
8761 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
8762 struct scroll_bar
*bar
;
8764 struct input_event
*emacs_event
;
8766 if (! GC_WINDOWP (bar
->window
))
8769 emacs_event
->kind
= scroll_bar_click
;
8770 emacs_event
->code
= event
->xbutton
.button
- Button1
;
8771 emacs_event
->modifiers
8772 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
8773 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
8774 event
->xbutton
.state
)
8775 | (event
->type
== ButtonRelease
8778 emacs_event
->frame_or_window
= bar
->window
;
8779 emacs_event
->arg
= Qnil
;
8780 emacs_event
->timestamp
= event
->xbutton
.time
;
8783 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8785 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8788 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8789 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
8792 if (y
> top_range
) y
= top_range
;
8794 if (y
< XINT (bar
->start
))
8795 emacs_event
->part
= scroll_bar_above_handle
;
8796 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8797 emacs_event
->part
= scroll_bar_handle
;
8799 emacs_event
->part
= scroll_bar_below_handle
;
8801 /* Just because the user has clicked on the handle doesn't mean
8802 they want to drag it. Lisp code needs to be able to decide
8803 whether or not we're dragging. */
8805 /* If the user has just clicked on the handle, record where they're
8807 if (event
->type
== ButtonPress
8808 && emacs_event
->part
== scroll_bar_handle
)
8809 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
8812 /* If the user has released the handle, set it to its final position. */
8813 if (event
->type
== ButtonRelease
8814 && ! NILP (bar
->dragging
))
8816 int new_start
= y
- XINT (bar
->dragging
);
8817 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8819 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8820 bar
->dragging
= Qnil
;
8823 /* Same deal here as the other #if 0. */
8825 /* Clicks on the handle are always reported as occurring at the top of
8827 if (emacs_event
->part
== scroll_bar_handle
)
8828 emacs_event
->x
= bar
->start
;
8830 XSETINT (emacs_event
->x
, y
);
8832 XSETINT (emacs_event
->x
, y
);
8835 XSETINT (emacs_event
->y
, top_range
);
8839 /* Handle some mouse motion while someone is dragging the scroll bar.
8841 This may be called from a signal handler, so we have to ignore GC
8845 x_scroll_bar_note_movement (bar
, event
)
8846 struct scroll_bar
*bar
;
8849 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8851 last_mouse_movement_time
= event
->xmotion
.time
;
8854 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8856 /* If we're dragging the bar, display it. */
8857 if (! GC_NILP (bar
->dragging
))
8859 /* Where should the handle be now? */
8860 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
8862 if (new_start
!= XINT (bar
->start
))
8864 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8866 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8871 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8873 /* Return information to the user about the current position of the mouse
8874 on the scroll bar. */
8877 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8879 Lisp_Object
*bar_window
;
8880 enum scroll_bar_part
*part
;
8882 unsigned long *time
;
8884 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8885 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8886 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8888 Window dummy_window
;
8890 unsigned int dummy_mask
;
8894 /* Get the mouse's position relative to the scroll bar window, and
8896 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
8898 /* Root, child, root x and root y. */
8899 &dummy_window
, &dummy_window
,
8900 &dummy_coord
, &dummy_coord
,
8902 /* Position relative to scroll bar. */
8905 /* Mouse buttons and modifier keys. */
8912 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8915 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8917 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8919 if (! NILP (bar
->dragging
))
8920 win_y
-= XINT (bar
->dragging
);
8924 if (win_y
> top_range
)
8928 *bar_window
= bar
->window
;
8930 if (! NILP (bar
->dragging
))
8931 *part
= scroll_bar_handle
;
8932 else if (win_y
< XINT (bar
->start
))
8933 *part
= scroll_bar_above_handle
;
8934 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8935 *part
= scroll_bar_handle
;
8937 *part
= scroll_bar_below_handle
;
8939 XSETINT (*x
, win_y
);
8940 XSETINT (*y
, top_range
);
8943 last_mouse_scroll_bar
= Qnil
;
8946 *time
= last_mouse_movement_time
;
8952 /* The screen has been cleared so we may have changed foreground or
8953 background colors, and the scroll bars may need to be redrawn.
8954 Clear out the scroll bars, and ask for expose events, so we can
8958 x_scroll_bar_clear (f
)
8961 #ifndef USE_TOOLKIT_SCROLL_BARS
8964 /* We can have scroll bars even if this is 0,
8965 if we just turned off scroll bar mode.
8966 But in that case we should not clear them. */
8967 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8968 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8969 bar
= XSCROLL_BAR (bar
)->next
)
8970 XClearArea (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
8972 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8975 /* This processes Expose events from the menu-bar specific X event
8976 loop in xmenu.c. This allows to redisplay the frame if necessary
8977 when handling menu-bar or pop-up items. */
8980 process_expose_from_menu (event
)
8984 struct x_display_info
*dpyinfo
;
8985 int frame_exposed_p
= 0;
8989 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
8990 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
8993 if (f
->async_visible
== 0)
8995 f
->async_visible
= 1;
8996 f
->async_iconified
= 0;
8997 f
->output_data
.x
->has_been_visible
= 1;
8998 SET_FRAME_GARBAGED (f
);
9002 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9003 event
.xexpose
.x
, event
.xexpose
.y
,
9004 event
.xexpose
.width
, event
.xexpose
.height
);
9005 frame_exposed_p
= 1;
9010 struct scroll_bar
*bar
9011 = x_window_to_scroll_bar (event
.xexpose
.window
);
9014 x_scroll_bar_expose (bar
, &event
);
9018 return frame_exposed_p
;
9021 /* Define a queue to save up SelectionRequest events for later handling. */
9023 struct selection_event_queue
9026 struct selection_event_queue
*next
;
9029 static struct selection_event_queue
*queue
;
9031 /* Nonzero means queue up certain events--don't process them yet. */
9033 static int x_queue_selection_requests
;
9035 /* Queue up an X event *EVENT, to be processed later. */
9038 x_queue_event (f
, event
)
9042 struct selection_event_queue
*queue_tmp
9043 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9045 if (queue_tmp
!= NULL
)
9047 queue_tmp
->event
= *event
;
9048 queue_tmp
->next
= queue
;
9053 /* Take all the queued events and put them back
9054 so that they get processed afresh. */
9057 x_unqueue_events (display
)
9060 while (queue
!= NULL
)
9062 struct selection_event_queue
*queue_tmp
= queue
;
9063 XPutBackEvent (display
, &queue_tmp
->event
);
9064 queue
= queue_tmp
->next
;
9065 xfree ((char *)queue_tmp
);
9069 /* Start queuing SelectionRequest events. */
9072 x_start_queuing_selection_requests (display
)
9075 x_queue_selection_requests
++;
9078 /* Stop queuing SelectionRequest events. */
9081 x_stop_queuing_selection_requests (display
)
9084 x_queue_selection_requests
--;
9085 x_unqueue_events (display
);
9088 /* The main X event-reading loop - XTread_socket. */
9090 /* Time stamp of enter window event. This is only used by XTread_socket,
9091 but we have to put it out here, since static variables within functions
9092 sometimes don't work. */
9094 static Time enter_timestamp
;
9096 /* This holds the state XLookupString needs to implement dead keys
9097 and other tricks known as "compose processing". _X Window System_
9098 says that a portable program can't use this, but Stephen Gildea assures
9099 me that letting the compiler initialize it to zeros will work okay.
9101 This must be defined outside of XTread_socket, for the same reasons
9102 given for enter_time stamp, above. */
9104 static XComposeStatus compose_status
;
9106 /* Record the last 100 characters stored
9107 to help debug the loss-of-chars-during-GC problem. */
9109 static int temp_index
;
9110 static short temp_buffer
[100];
9112 /* Set this to nonzero to fake an "X I/O error"
9113 on a particular display. */
9115 struct x_display_info
*XTread_socket_fake_io_error
;
9117 /* When we find no input here, we occasionally do a no-op command
9118 to verify that the X server is still running and we can still talk with it.
9119 We try all the open displays, one by one.
9120 This variable is used for cycling thru the displays. */
9122 static struct x_display_info
*next_noop_dpyinfo
;
9124 #define SET_SAVED_MENU_EVENT(size) \
9127 if (f->output_data.x->saved_menu_event == 0) \
9128 f->output_data.x->saved_menu_event \
9129 = (XEvent *) xmalloc (sizeof (XEvent)); \
9130 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9131 if (numchars >= 1) \
9133 bufp->kind = menu_bar_activate_event; \
9134 XSETFRAME (bufp->frame_or_window, f); \
9143 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9144 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9146 /* Read events coming from the X server.
9147 This routine is called by the SIGIO handler.
9148 We return as soon as there are no more events to be read.
9150 Events representing keys are stored in buffer BUFP,
9151 which can hold up to NUMCHARS characters.
9152 We return the number of characters stored into the buffer,
9153 thus pretending to be `read'.
9155 EXPECTED is nonzero if the caller knows input is available. */
9158 XTread_socket (sd
, bufp
, numchars
, expected
)
9160 /* register */ struct input_event
*bufp
;
9161 /* register */ int numchars
;
9168 int event_found
= 0;
9169 struct x_display_info
*dpyinfo
;
9170 struct coding_system coding
;
9172 if (interrupt_input_blocked
)
9174 interrupt_input_pending
= 1;
9178 interrupt_input_pending
= 0;
9181 /* So people can tell when we have read the available input. */
9182 input_signal_count
++;
9185 abort (); /* Don't think this happens. */
9189 /* The input should be decoded if it is from XIM. Currently the
9190 locale of XIM is the same as that of the system. So, we can use
9191 Vlocale_coding_system which is initialized properly at Emacs
9193 setup_coding_system (Vlocale_coding_system
, &coding
);
9194 coding
.src_multibyte
= 0;
9195 coding
.dst_multibyte
= 1;
9196 /* The input is converted to events, thus we can't handle
9197 composition. Anyway, there's no XIM that gives us composition
9199 coding
.composing
= COMPOSITION_DISABLED
;
9201 /* Find the display we are supposed to read input for.
9202 It's the one communicating on descriptor SD. */
9203 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9205 #if 0 /* This ought to be unnecessary; let's verify it. */
9207 /* If available, Xlib uses FIOSNBIO to make the socket
9208 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9209 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9210 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9211 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9212 #endif /* ! defined (FIOSNBIO) */
9215 #if 0 /* This code can't be made to work, with multiple displays,
9216 and appears not to be used on any system any more.
9217 Also keyboard.c doesn't turn O_NDELAY on and off
9218 for X connections. */
9221 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9223 extern int read_alarm_should_throw
;
9224 read_alarm_should_throw
= 1;
9225 XPeekEvent (dpyinfo
->display
, &event
);
9226 read_alarm_should_throw
= 0;
9228 #endif /* HAVE_SELECT */
9232 /* For debugging, this gives a way to fake an I/O error. */
9233 if (dpyinfo
== XTread_socket_fake_io_error
)
9235 XTread_socket_fake_io_error
= 0;
9236 x_io_error_quitter (dpyinfo
->display
);
9239 while (XPending (dpyinfo
->display
))
9241 XNextEvent (dpyinfo
->display
, &event
);
9245 /* Filter events for the current X input method.
9246 XFilterEvent returns non-zero if the input method has
9247 consumed the event. We pass the frame's X window to
9248 XFilterEvent because that's the one for which the IC
9250 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9251 event
.xclient
.window
);
9252 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9262 if (event
.xclient
.message_type
9263 == dpyinfo
->Xatom_wm_protocols
9264 && event
.xclient
.format
== 32)
9266 if (event
.xclient
.data
.l
[0]
9267 == dpyinfo
->Xatom_wm_take_focus
)
9269 /* Use x_any_window_to_frame because this
9270 could be the shell widget window
9271 if the frame has no title bar. */
9272 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9274 /* Not quite sure this is needed -pd */
9275 if (f
&& FRAME_XIC (f
))
9276 XSetICFocus (FRAME_XIC (f
));
9278 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
9279 instructs the WM to set the input focus automatically for
9280 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
9281 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
9282 it has set the focus. So, XSetInputFocus below is not
9285 The call to XSetInputFocus below has also caused trouble. In
9286 cases where the XSetInputFocus done by the WM and the one
9287 below are temporally close (on a fast machine), the call
9288 below can generate additional FocusIn events which confuse
9291 /* Since we set WM_TAKE_FOCUS, we must call
9292 XSetInputFocus explicitly. But not if f is null,
9293 since that might be an event for a deleted frame. */
9296 Display
*d
= event
.xclient
.display
;
9297 /* Catch and ignore errors, in case window has been
9298 iconified by a window manager such as GWM. */
9299 int count
= x_catch_errors (d
);
9300 XSetInputFocus (d
, event
.xclient
.window
,
9301 /* The ICCCM says this is
9302 the only valid choice. */
9304 event
.xclient
.data
.l
[1]);
9305 /* This is needed to detect the error
9306 if there is an error. */
9308 x_uncatch_errors (d
, count
);
9310 /* Not certain about handling scroll bars here */
9313 else if (event
.xclient
.data
.l
[0]
9314 == dpyinfo
->Xatom_wm_save_yourself
)
9316 /* Save state modify the WM_COMMAND property to
9317 something which can reinstate us. This notifies
9318 the session manager, who's looking for such a
9319 PropertyNotify. Can restart processing when
9320 a keyboard or mouse event arrives. */
9323 f
= x_top_window_to_frame (dpyinfo
,
9324 event
.xclient
.window
);
9326 /* This is just so we only give real data once
9327 for a single Emacs process. */
9328 if (f
== SELECTED_FRAME ())
9329 XSetCommand (FRAME_X_DISPLAY (f
),
9330 event
.xclient
.window
,
9331 initial_argv
, initial_argc
);
9333 XSetCommand (FRAME_X_DISPLAY (f
),
9334 event
.xclient
.window
,
9338 else if (event
.xclient
.data
.l
[0]
9339 == dpyinfo
->Xatom_wm_delete_window
)
9342 = x_any_window_to_frame (dpyinfo
,
9343 event
.xclient
.window
);
9350 bufp
->kind
= delete_window_event
;
9351 XSETFRAME (bufp
->frame_or_window
, f
);
9360 else if (event
.xclient
.message_type
9361 == dpyinfo
->Xatom_wm_configure_denied
)
9364 else if (event
.xclient
.message_type
9365 == dpyinfo
->Xatom_wm_window_moved
)
9369 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9371 new_x
= event
.xclient
.data
.s
[0];
9372 new_y
= event
.xclient
.data
.s
[1];
9376 f
->output_data
.x
->left_pos
= new_x
;
9377 f
->output_data
.x
->top_pos
= new_y
;
9381 else if (event
.xclient
.message_type
9382 == dpyinfo
->Xatom_editres
)
9385 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9386 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
9389 #endif /* HACK_EDITRES */
9390 else if ((event
.xclient
.message_type
9391 == dpyinfo
->Xatom_DONE
)
9392 || (event
.xclient
.message_type
9393 == dpyinfo
->Xatom_PAGE
))
9395 /* Ghostview job completed. Kill it. We could
9396 reply with "Next" if we received "Page", but we
9397 currently never do because we are interested in
9398 images, only, which should have 1 page. */
9399 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
9401 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9402 x_kill_gs_process (pixmap
, f
);
9403 expose_frame (f
, 0, 0, 0, 0);
9405 #ifdef USE_TOOLKIT_SCROLL_BARS
9406 /* Scroll bar callbacks send a ClientMessage from which
9407 we construct an input_event. */
9408 else if (event
.xclient
.message_type
9409 == dpyinfo
->Xatom_Scrollbar
)
9411 x_scroll_bar_to_input_event (&event
, bufp
);
9412 ++bufp
, ++count
, --numchars
;
9415 #endif /* USE_TOOLKIT_SCROLL_BARS */
9421 case SelectionNotify
:
9422 #ifdef USE_X_TOOLKIT
9423 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
9425 #endif /* not USE_X_TOOLKIT */
9426 x_handle_selection_notify (&event
.xselection
);
9429 case SelectionClear
: /* Someone has grabbed ownership. */
9430 #ifdef USE_X_TOOLKIT
9431 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
9433 #endif /* USE_X_TOOLKIT */
9435 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
9440 bufp
->kind
= selection_clear_event
;
9441 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9442 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9443 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9444 bufp
->frame_or_window
= Qnil
;
9453 case SelectionRequest
: /* Someone wants our selection. */
9454 #ifdef USE_X_TOOLKIT
9455 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
9457 #endif /* USE_X_TOOLKIT */
9458 if (x_queue_selection_requests
)
9459 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
9463 XSelectionRequestEvent
*eventp
= (XSelectionRequestEvent
*) &event
;
9468 bufp
->kind
= selection_request_event
;
9469 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9470 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
9471 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9472 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
9473 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
9474 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9475 bufp
->frame_or_window
= Qnil
;
9484 case PropertyNotify
:
9485 #ifdef USE_X_TOOLKIT
9486 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
9488 #endif /* not USE_X_TOOLKIT */
9489 x_handle_property_notify (&event
.xproperty
);
9492 case ReparentNotify
:
9493 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
9497 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
9498 x_real_positions (f
, &x
, &y
);
9499 f
->output_data
.x
->left_pos
= x
;
9500 f
->output_data
.x
->top_pos
= y
;
9505 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9508 if (f
->async_visible
== 0)
9510 f
->async_visible
= 1;
9511 f
->async_iconified
= 0;
9512 f
->output_data
.x
->has_been_visible
= 1;
9513 SET_FRAME_GARBAGED (f
);
9516 expose_frame (x_window_to_frame (dpyinfo
,
9517 event
.xexpose
.window
),
9518 event
.xexpose
.x
, event
.xexpose
.y
,
9519 event
.xexpose
.width
, event
.xexpose
.height
);
9523 #ifdef USE_TOOLKIT_SCROLL_BARS
9524 /* Dispatch event to the widget. */
9526 #else /* not USE_TOOLKIT_SCROLL_BARS */
9527 struct scroll_bar
*bar
9528 = x_window_to_scroll_bar (event
.xexpose
.window
);
9531 x_scroll_bar_expose (bar
, &event
);
9532 #ifdef USE_X_TOOLKIT
9535 #endif /* USE_X_TOOLKIT */
9536 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9540 case GraphicsExpose
: /* This occurs when an XCopyArea's
9541 source area was obscured or not
9543 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
9547 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
9548 event
.xgraphicsexpose
.width
,
9549 event
.xgraphicsexpose
.height
);
9551 #ifdef USE_X_TOOLKIT
9554 #endif /* USE_X_TOOLKIT */
9557 case NoExpose
: /* This occurs when an XCopyArea's
9558 source area was completely
9563 /* Redo the mouse-highlight after the tooltip has gone. */
9564 if (event
.xmap
.window
== tip_window
)
9567 redo_mouse_highlight ();
9570 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
9571 if (f
) /* F may no longer exist if
9572 the frame was deleted. */
9574 /* While a frame is unmapped, display generation is
9575 disabled; you don't want to spend time updating a
9576 display that won't ever be seen. */
9577 f
->async_visible
= 0;
9578 /* We can't distinguish, from the event, whether the window
9579 has become iconified or invisible. So assume, if it
9580 was previously visible, than now it is iconified.
9581 But x_make_frame_invisible clears both
9582 the visible flag and the iconified flag;
9583 and that way, we know the window is not iconified now. */
9584 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
9586 f
->async_iconified
= 1;
9588 bufp
->kind
= iconify_event
;
9589 XSETFRAME (bufp
->frame_or_window
, f
);
9599 if (event
.xmap
.window
== tip_window
)
9600 /* The tooltip has been drawn already. Avoid
9601 the SET_FRAME_GARBAGED below. */
9604 /* We use x_top_window_to_frame because map events can
9605 come for sub-windows and they don't mean that the
9606 frame is visible. */
9607 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
9610 f
->async_visible
= 1;
9611 f
->async_iconified
= 0;
9612 f
->output_data
.x
->has_been_visible
= 1;
9614 /* wait_reading_process_input will notice this and update
9615 the frame's display structures. */
9616 SET_FRAME_GARBAGED (f
);
9620 bufp
->kind
= deiconify_event
;
9621 XSETFRAME (bufp
->frame_or_window
, f
);
9627 else if (! NILP (Vframe_list
)
9628 && ! NILP (XCDR (Vframe_list
)))
9629 /* Force a redisplay sooner or later
9630 to update the frame titles
9631 in case this is the second frame. */
9632 record_asynch_buffer_change ();
9637 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
9640 /* I couldn't find a way to prevent LessTif scroll bars
9641 from consuming key events. */
9644 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
9646 if (widget
&& XmIsScrollBar (widget
))
9648 widget
= XtParent (widget
);
9649 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
9652 #endif /* USE_MOTIF */
9656 KeySym keysym
, orig_keysym
;
9657 /* al%imercury@uunet.uu.net says that making this 81
9658 instead of 80 fixed a bug whereby meta chars made
9661 It seems that some version of XmbLookupString has
9662 a bug of not returning XBufferOverflow in
9663 status_return even if the input is too long to
9664 fit in 81 bytes. So, we must prepare sufficient
9665 bytes for copy_buffer. 513 bytes (256 chars for
9666 two-byte character set) seems to be a faily good
9667 approximation. -- 2000.8.10 handa@etl.go.jp */
9668 unsigned char copy_buffer
[513];
9669 unsigned char *copy_bufptr
= copy_buffer
;
9670 int copy_bufsiz
= sizeof (copy_buffer
);
9674 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
9675 extra_keyboard_modifiers
);
9676 modifiers
= event
.xkey
.state
;
9678 /* This will have to go some day... */
9680 /* make_lispy_event turns chars into control chars.
9681 Don't do it here because XLookupString is too eager. */
9682 event
.xkey
.state
&= ~ControlMask
;
9683 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
9684 | dpyinfo
->super_mod_mask
9685 | dpyinfo
->hyper_mod_mask
9686 | dpyinfo
->alt_mod_mask
);
9688 /* In case Meta is ComposeCharacter,
9689 clear its status. According to Markus Ehrnsperger
9690 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
9691 this enables ComposeCharacter to work whether or
9692 not it is combined with Meta. */
9693 if (modifiers
& dpyinfo
->meta_mod_mask
)
9694 bzero (&compose_status
, sizeof (compose_status
));
9699 Status status_return
;
9701 nbytes
= XmbLookupString (FRAME_XIC (f
),
9702 &event
.xkey
, copy_bufptr
,
9703 copy_bufsiz
, &keysym
,
9705 if (status_return
== XBufferOverflow
)
9707 copy_bufsiz
= nbytes
+ 1;
9708 copy_bufptr
= (char *) alloca (copy_bufsiz
);
9709 nbytes
= XmbLookupString (FRAME_XIC (f
),
9710 &event
.xkey
, copy_bufptr
,
9711 copy_bufsiz
, &keysym
,
9715 if (status_return
== XLookupNone
)
9717 else if (status_return
== XLookupChars
)
9722 else if (status_return
!= XLookupKeySym
9723 && status_return
!= XLookupBoth
)
9727 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
9728 copy_bufsiz
, &keysym
,
9731 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
9732 copy_bufsiz
, &keysym
,
9736 orig_keysym
= keysym
;
9740 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
9741 || keysym
== XK_Delete
9742 #ifdef XK_ISO_Left_Tab
9743 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
9745 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
9746 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
9747 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
9749 /* This recognizes the "extended function keys".
9750 It seems there's no cleaner way.
9751 Test IsModifierKey to avoid handling mode_switch
9753 || ((unsigned) (keysym
) >= XK_Select
9754 && (unsigned)(keysym
) < XK_KP_Space
)
9756 #ifdef XK_dead_circumflex
9757 || orig_keysym
== XK_dead_circumflex
9759 #ifdef XK_dead_grave
9760 || orig_keysym
== XK_dead_grave
9762 #ifdef XK_dead_tilde
9763 || orig_keysym
== XK_dead_tilde
9765 #ifdef XK_dead_diaeresis
9766 || orig_keysym
== XK_dead_diaeresis
9768 #ifdef XK_dead_macron
9769 || orig_keysym
== XK_dead_macron
9771 #ifdef XK_dead_degree
9772 || orig_keysym
== XK_dead_degree
9774 #ifdef XK_dead_acute
9775 || orig_keysym
== XK_dead_acute
9777 #ifdef XK_dead_cedilla
9778 || orig_keysym
== XK_dead_cedilla
9780 #ifdef XK_dead_breve
9781 || orig_keysym
== XK_dead_breve
9783 #ifdef XK_dead_ogonek
9784 || orig_keysym
== XK_dead_ogonek
9786 #ifdef XK_dead_caron
9787 || orig_keysym
== XK_dead_caron
9789 #ifdef XK_dead_doubleacute
9790 || orig_keysym
== XK_dead_doubleacute
9792 #ifdef XK_dead_abovedot
9793 || orig_keysym
== XK_dead_abovedot
9795 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
9796 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
9797 /* Any "vendor-specific" key is ok. */
9798 || (orig_keysym
& (1 << 28)))
9799 && ! (IsModifierKey (orig_keysym
)
9801 #ifdef XK_Mode_switch
9802 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
9805 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
9807 #endif /* not HAVE_X11R5 */
9810 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
9812 temp_buffer
[temp_index
++] = keysym
;
9813 bufp
->kind
= non_ascii_keystroke
;
9814 bufp
->code
= keysym
;
9815 XSETFRAME (bufp
->frame_or_window
, f
);
9818 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
9820 bufp
->timestamp
= event
.xkey
.time
;
9825 else if (numchars
> nbytes
)
9829 unsigned char *p
, *pend
;
9832 for (i
= 0; i
< nbytes
; i
++)
9834 if (temp_index
== (sizeof temp_buffer
9837 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
9840 if (/* If the event is not from XIM, */
9841 event
.xkey
.keycode
!= 0
9842 /* or the current locale doesn't request
9843 decoding of the intup data, ... */
9844 || coding
.type
== coding_type_raw_text
9845 || coding
.type
== coding_type_no_conversion
)
9847 /* ... we can use the input data as is. */
9852 /* We have to decode the input data. */
9856 require
= decoding_buffer_size (&coding
, nbytes
);
9857 p
= (unsigned char *) alloca (require
);
9858 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
9859 decode_coding (&coding
, copy_bufptr
, p
,
9861 nbytes
= coding
.produced
;
9862 nchars
= coding
.produced_char
;
9866 /* Convert the input data to a sequence of
9867 character events. */
9868 for (i
= 0; i
< nbytes
; i
+= len
)
9870 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
9872 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
9874 : multibyte_char_keystroke
);
9876 XSETFRAME (bufp
->frame_or_window
, f
);
9879 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
9881 bufp
->timestamp
= event
.xkey
.time
;
9888 if (keysym
== NoSymbol
)
9898 /* Don't dispatch this event since XtDispatchEvent calls
9899 XFilterEvent, and two calls in a row may freeze the
9908 /* Don't dispatch this event since XtDispatchEvent calls
9909 XFilterEvent, and two calls in a row may freeze the
9916 /* Here's a possible interpretation of the whole
9917 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
9918 you get a FocusIn event, you have to get a FocusOut
9919 event before you relinquish the focus. If you
9920 haven't received a FocusIn event, then a mere
9921 LeaveNotify is enough to free you. */
9925 int from_menu_bar_p
= 0;
9927 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
9929 #ifdef LESSTIF_VERSION
9930 /* When clicking outside of a menu bar popup to close
9931 it, we get a FocusIn/ EnterNotify sequence of
9932 events. The flag event.xcrossing.focus is not set
9933 in the EnterNotify event of that sequence because
9934 the focus is in the menu bar,
9935 event.xcrossing.window is the frame's X window.
9936 Unconditionally setting the focus frame to null in
9937 this case is not the right thing, because no event
9938 follows that could set the focus frame to the right
9941 This could be a LessTif bug, but I wasn't able to
9942 reproduce the behavior in a simple test program.
9944 (gerd, LessTif 0.88.1). */
9946 if (!event
.xcrossing
.focus
9948 && f
->output_data
.x
->menubar_widget
)
9953 XGetInputFocus (FRAME_X_DISPLAY (f
), &focus
, &revert
);
9954 if (focus
== XtWindow (f
->output_data
.x
->menubar_widget
))
9955 from_menu_bar_p
= 1;
9957 #endif /* LESSTIF_VERSION */
9959 if (event
.xcrossing
.focus
|| from_menu_bar_p
)
9961 /* Avoid nasty pop/raise loops. */
9962 if (f
&& (!(f
->auto_raise
)
9964 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
9966 x_new_focus_frame (dpyinfo
, f
);
9967 enter_timestamp
= event
.xcrossing
.time
;
9970 else if (f
== dpyinfo
->x_focus_frame
)
9971 x_new_focus_frame (dpyinfo
, 0);
9973 /* EnterNotify counts as mouse movement,
9974 so update things that depend on mouse position. */
9975 if (f
&& !f
->output_data
.x
->busy_p
)
9976 note_mouse_movement (f
, &event
.xmotion
);
9981 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
9982 if (event
.xfocus
.detail
!= NotifyPointer
)
9983 dpyinfo
->x_focus_event_frame
= f
;
9986 x_new_focus_frame (dpyinfo
, f
);
9988 /* Don't stop displaying the initial startup message
9989 for a switch-frame event we don't need. */
9990 if (GC_NILP (Vterminal_frame
)
9991 && GC_CONSP (Vframe_list
)
9992 && !GC_NILP (XCDR (Vframe_list
)))
9994 bufp
->kind
= FOCUS_IN_EVENT
;
9995 XSETFRAME (bufp
->frame_or_window
, f
);
9997 ++bufp
, ++count
, --numchars
;
10002 if (f
&& FRAME_XIC (f
))
10003 XSetICFocus (FRAME_XIC (f
));
10009 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10013 int from_menu_bar_p
= 0;
10015 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10017 /* If we move outside the frame, then we're
10018 certainly no longer on any text in the frame. */
10019 clear_mouse_face (dpyinfo
);
10020 dpyinfo
->mouse_face_mouse_frame
= 0;
10023 /* Generate a nil HELP_EVENT to cancel a help-echo.
10024 Do it only if there's something to cancel.
10025 Otherwise, the startup message is cleared when
10026 the mouse leaves the frame. */
10027 if (any_help_event_p
)
10032 XSETFRAME (frame
, f
);
10033 n
= gen_help_event (bufp
, numchars
,
10034 Qnil
, frame
, Qnil
, Qnil
, 0);
10035 bufp
+= n
, count
+= n
, numchars
-= n
;
10038 #ifdef LESSTIF_VERSION
10039 /* Please see the comment at the start of the
10040 EnterNotify case. */
10041 if (!event
.xcrossing
.focus
10042 && f
->output_data
.x
->menubar_widget
)
10046 XGetInputFocus (FRAME_X_DISPLAY (f
), &focus
, &revert
);
10047 if (focus
== XtWindow (f
->output_data
.x
->menubar_widget
))
10048 from_menu_bar_p
= 1;
10050 #endif /* LESSTIF_VERSION */
10052 if (event
.xcrossing
.focus
|| from_menu_bar_p
)
10053 x_mouse_leave (dpyinfo
);
10056 if (f
== dpyinfo
->x_focus_event_frame
)
10057 dpyinfo
->x_focus_event_frame
= 0;
10058 if (f
== dpyinfo
->x_focus_frame
)
10059 x_new_focus_frame (dpyinfo
, 0);
10065 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10066 if (event
.xfocus
.detail
!= NotifyPointer
10067 && f
== dpyinfo
->x_focus_event_frame
)
10068 dpyinfo
->x_focus_event_frame
= 0;
10069 if (f
&& f
== dpyinfo
->x_focus_frame
)
10070 x_new_focus_frame (dpyinfo
, 0);
10073 if (f
&& FRAME_XIC (f
))
10074 XUnsetICFocus (FRAME_XIC (f
));
10081 previous_help_echo
= help_echo
;
10082 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10083 help_echo_pos
= -1;
10085 if (dpyinfo
->grabbed
&& last_mouse_frame
10086 && FRAME_LIVE_P (last_mouse_frame
))
10087 f
= last_mouse_frame
;
10089 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10092 note_mouse_movement (f
, &event
.xmotion
);
10095 #ifndef USE_TOOLKIT_SCROLL_BARS
10096 struct scroll_bar
*bar
10097 = x_window_to_scroll_bar (event
.xmotion
.window
);
10100 x_scroll_bar_note_movement (bar
, &event
);
10101 #endif /* USE_TOOLKIT_SCROLL_BARS */
10103 /* If we move outside the frame, then we're
10104 certainly no longer on any text in the frame. */
10105 clear_mouse_face (dpyinfo
);
10108 /* If the contents of the global variable help_echo
10109 has changed, generate a HELP_EVENT. */
10110 if (!NILP (help_echo
)
10111 || !NILP (previous_help_echo
))
10117 XSETFRAME (frame
, f
);
10121 any_help_event_p
= 1;
10122 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10123 help_echo_window
, help_echo_object
,
10125 bufp
+= n
, count
+= n
, numchars
-= n
;
10131 case ConfigureNotify
:
10132 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10135 #ifndef USE_X_TOOLKIT
10136 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10137 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10139 /* In the toolkit version, change_frame_size
10140 is called by the code that handles resizing
10141 of the EmacsFrame widget. */
10143 /* Even if the number of character rows and columns has
10144 not changed, the font size may have changed, so we need
10145 to check the pixel dimensions as well. */
10146 if (columns
!= f
->width
10147 || rows
!= f
->height
10148 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10149 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10151 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10152 SET_FRAME_GARBAGED (f
);
10153 cancel_mouse_face (f
);
10157 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10158 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10160 /* What we have now is the position of Emacs's own window.
10161 Convert that to the position of the window manager window. */
10162 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10163 &f
->output_data
.x
->top_pos
);
10166 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10167 xic_set_statusarea (f
);
10170 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10172 /* Since the WM decorations come below top_pos now,
10173 we must put them below top_pos in the future. */
10174 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10175 x_wm_set_size_hint (f
, (long) 0, 0);
10178 /* Some window managers pass (0,0) as the location of
10179 the window, and the Motif event handler stores it
10180 in the emacs widget, which messes up Motif menus. */
10181 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10183 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10184 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10186 #endif /* USE_MOTIF */
10191 case ButtonRelease
:
10193 /* If we decide we want to generate an event to be seen
10194 by the rest of Emacs, we put it here. */
10195 struct input_event emacs_event
;
10196 int tool_bar_p
= 0;
10198 emacs_event
.kind
= no_event
;
10199 bzero (&compose_status
, sizeof (compose_status
));
10201 if (dpyinfo
->grabbed
10202 && last_mouse_frame
10203 && FRAME_LIVE_P (last_mouse_frame
))
10204 f
= last_mouse_frame
;
10206 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10210 /* Is this in the tool-bar? */
10211 if (WINDOWP (f
->tool_bar_window
)
10212 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10214 Lisp_Object window
;
10217 x
= event
.xbutton
.x
;
10218 y
= event
.xbutton
.y
;
10221 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10222 if (EQ (window
, f
->tool_bar_window
))
10224 x_handle_tool_bar_click (f
, &event
.xbutton
);
10230 if (!dpyinfo
->x_focus_frame
10231 || f
== dpyinfo
->x_focus_frame
)
10232 construct_mouse_click (&emacs_event
, &event
, f
);
10236 #ifndef USE_TOOLKIT_SCROLL_BARS
10237 struct scroll_bar
*bar
10238 = x_window_to_scroll_bar (event
.xbutton
.window
);
10241 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10242 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10245 if (event
.type
== ButtonPress
)
10247 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10248 last_mouse_frame
= f
;
10249 /* Ignore any mouse motion that happened
10250 before this event; any subsequent mouse-movement
10251 Emacs events should reflect only motion after
10252 the ButtonPress. */
10254 f
->mouse_moved
= 0;
10257 last_tool_bar_item
= -1;
10261 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10264 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10266 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10272 #ifdef USE_X_TOOLKIT
10273 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10274 /* For a down-event in the menu bar,
10275 don't pass it to Xt right now.
10276 Instead, save it away
10277 and we will pass it to Xt from kbd_buffer_get_event.
10278 That way, we can run some Lisp code first. */
10279 if (f
&& event
.type
== ButtonPress
10280 /* Verify the event is really within the menu bar
10281 and not just sent to it due to grabbing. */
10282 && event
.xbutton
.x
>= 0
10283 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10284 && event
.xbutton
.y
>= 0
10285 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10286 && event
.xbutton
.same_screen
)
10288 SET_SAVED_BUTTON_EVENT
;
10289 XSETFRAME (last_mouse_press_frame
, f
);
10291 else if (event
.type
== ButtonPress
)
10293 last_mouse_press_frame
= Qnil
;
10297 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10298 but I am trying to be cautious. */
10299 else if (event
.type
== ButtonRelease
)
10301 if (!NILP (last_mouse_press_frame
))
10303 f
= XFRAME (last_mouse_press_frame
);
10304 if (f
->output_data
.x
)
10305 SET_SAVED_BUTTON_EVENT
;
10310 #endif /* USE_MOTIF */
10313 #endif /* USE_X_TOOLKIT */
10317 case CirculateNotify
:
10320 case CirculateRequest
:
10323 case VisibilityNotify
:
10326 case MappingNotify
:
10327 /* Someone has changed the keyboard mapping - update the
10329 switch (event
.xmapping
.request
)
10331 case MappingModifier
:
10332 x_find_modifier_meanings (dpyinfo
);
10333 /* This is meant to fall through. */
10334 case MappingKeyboard
:
10335 XRefreshKeyboardMapping (&event
.xmapping
);
10341 #ifdef USE_X_TOOLKIT
10343 XtDispatchEvent (&event
);
10345 #endif /* USE_X_TOOLKIT */
10353 /* On some systems, an X bug causes Emacs to get no more events
10354 when the window is destroyed. Detect that. (1994.) */
10357 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
10358 One XNOOP in 100 loops will make Emacs terminate.
10359 B. Bretthauer, 1994 */
10361 if (x_noop_count
>= 100)
10365 if (next_noop_dpyinfo
== 0)
10366 next_noop_dpyinfo
= x_display_list
;
10368 XNoOp (next_noop_dpyinfo
->display
);
10370 /* Each time we get here, cycle through the displays now open. */
10371 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
10375 /* If the focus was just given to an auto-raising frame,
10377 /* ??? This ought to be able to handle more than one such frame. */
10378 if (pending_autoraise_frame
)
10380 x_raise_frame (pending_autoraise_frame
);
10381 pending_autoraise_frame
= 0;
10392 /***********************************************************************
10394 ***********************************************************************/
10396 /* Note if the text cursor of window W has been overwritten by a
10397 drawing operation that outputs N glyphs starting at HPOS in the
10398 line given by output_cursor.vpos. N < 0 means all the rest of the
10399 line after HPOS has been written. */
10402 note_overwritten_text_cursor (w
, hpos
, n
)
10406 if (updated_area
== TEXT_AREA
10407 && output_cursor
.vpos
== w
->phys_cursor
.vpos
10408 && hpos
<= w
->phys_cursor
.hpos
10410 || hpos
+ n
> w
->phys_cursor
.hpos
))
10411 w
->phys_cursor_on_p
= 0;
10415 /* Set clipping for output in glyph row ROW. W is the window in which
10416 we operate. GC is the graphics context to set clipping in.
10417 WHOLE_LINE_P non-zero means include the areas used for truncation
10418 mark display and alike in the clipping rectangle.
10420 ROW may be a text row or, e.g., a mode line. Text rows must be
10421 clipped to the interior of the window dedicated to text display,
10422 mode lines must be clipped to the whole window. */
10425 x_clip_to_row (w
, row
, gc
, whole_line_p
)
10427 struct glyph_row
*row
;
10431 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10432 XRectangle clip_rect
;
10433 int window_x
, window_y
, window_width
, window_height
;
10435 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
10437 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
10438 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
10439 clip_rect
.y
= max (clip_rect
.y
, window_y
);
10440 clip_rect
.width
= window_width
;
10441 clip_rect
.height
= row
->visible_height
;
10443 /* If clipping to the whole line, including trunc marks, extend
10444 the rectangle to the left and increase its width. */
10447 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
10448 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
10451 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
10455 /* Draw a hollow box cursor on window W in glyph row ROW. */
10458 x_draw_hollow_cursor (w
, row
)
10460 struct glyph_row
*row
;
10462 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10463 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10464 Display
*dpy
= FRAME_X_DISPLAY (f
);
10467 struct glyph
*cursor_glyph
;
10470 /* Compute frame-relative coordinates from window-relative
10472 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10473 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
10474 + row
->ascent
- w
->phys_cursor_ascent
);
10475 h
= row
->height
- 1;
10477 /* Get the glyph the cursor is on. If we can't tell because
10478 the current matrix is invalid or such, give up. */
10479 cursor_glyph
= get_phys_cursor_glyph (w
);
10480 if (cursor_glyph
== NULL
)
10483 /* Compute the width of the rectangle to draw. If on a stretch
10484 glyph, and `x-stretch-block-cursor' is nil, don't draw a
10485 rectangle as wide as the glyph, but use a canonical character
10487 wd
= cursor_glyph
->pixel_width
- 1;
10488 if (cursor_glyph
->type
== STRETCH_GLYPH
10489 && !x_stretch_cursor_p
)
10490 wd
= min (CANON_X_UNIT (f
), wd
);
10492 /* The foreground of cursor_gc is typically the same as the normal
10493 background color, which can cause the cursor box to be invisible. */
10494 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10495 if (dpyinfo
->scratch_cursor_gc
)
10496 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
10498 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
10499 GCForeground
, &xgcv
);
10500 gc
= dpyinfo
->scratch_cursor_gc
;
10502 /* Set clipping, draw the rectangle, and reset clipping again. */
10503 x_clip_to_row (w
, row
, gc
, 0);
10504 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
10505 XSetClipMask (dpy
, gc
, None
);
10509 /* Draw a bar cursor on window W in glyph row ROW.
10511 Implementation note: One would like to draw a bar cursor with an
10512 angle equal to the one given by the font property XA_ITALIC_ANGLE.
10513 Unfortunately, I didn't find a font yet that has this property set.
10517 x_draw_bar_cursor (w
, row
, width
)
10519 struct glyph_row
*row
;
10522 struct frame
*f
= XFRAME (w
->frame
);
10523 struct glyph
*cursor_glyph
;
10526 unsigned long mask
;
10531 /* If cursor is out of bounds, don't draw garbage. This can happen
10532 in mini-buffer windows when switching between echo area glyphs
10533 and mini-buffer. */
10534 cursor_glyph
= get_phys_cursor_glyph (w
);
10535 if (cursor_glyph
== NULL
)
10538 /* If on an image, draw like a normal cursor. That's usually better
10539 visible than drawing a bar, esp. if the image is large so that
10540 the bar might not be in the window. */
10541 if (cursor_glyph
->type
== IMAGE_GLYPH
)
10543 struct glyph_row
*row
;
10544 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
10545 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
10549 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
10550 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10551 xgcv
.graphics_exposures
= 0;
10552 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
10553 dpy
= FRAME_X_DISPLAY (f
);
10554 window
= FRAME_X_WINDOW (f
);
10555 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
10558 XChangeGC (dpy
, gc
, mask
, &xgcv
);
10561 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
10562 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
10566 width
= f
->output_data
.x
->cursor_width
;
10568 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10569 x_clip_to_row (w
, row
, gc
, 0);
10570 XFillRectangle (dpy
, window
, gc
,
10572 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
10573 min (cursor_glyph
->pixel_width
, width
),
10575 XSetClipMask (dpy
, gc
, None
);
10580 /* Clear the cursor of window W to background color, and mark the
10581 cursor as not shown. This is used when the text where the cursor
10582 is is about to be rewritten. */
10588 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
10589 x_update_window_cursor (w
, 0);
10593 /* Draw the cursor glyph of window W in glyph row ROW. See the
10594 comment of x_draw_glyphs for the meaning of HL. */
10597 x_draw_phys_cursor_glyph (w
, row
, hl
)
10599 struct glyph_row
*row
;
10600 enum draw_glyphs_face hl
;
10602 /* If cursor hpos is out of bounds, don't draw garbage. This can
10603 happen in mini-buffer windows when switching between echo area
10604 glyphs and mini-buffer. */
10605 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
10607 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
10608 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
10611 /* When we erase the cursor, and ROW is overlapped by other
10612 rows, make sure that these overlapping parts of other rows
10614 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
10616 if (row
> w
->current_matrix
->rows
10617 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
10618 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
10620 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
10621 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
10622 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
10628 /* Erase the image of a cursor of window W from the screen. */
10631 x_erase_phys_cursor (w
)
10634 struct frame
*f
= XFRAME (w
->frame
);
10635 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10636 int hpos
= w
->phys_cursor
.hpos
;
10637 int vpos
= w
->phys_cursor
.vpos
;
10638 int mouse_face_here_p
= 0;
10639 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
10640 struct glyph_row
*cursor_row
;
10641 struct glyph
*cursor_glyph
;
10642 enum draw_glyphs_face hl
;
10644 /* No cursor displayed or row invalidated => nothing to do on the
10646 if (w
->phys_cursor_type
== NO_CURSOR
)
10647 goto mark_cursor_off
;
10649 /* VPOS >= active_glyphs->nrows means that window has been resized.
10650 Don't bother to erase the cursor. */
10651 if (vpos
>= active_glyphs
->nrows
)
10652 goto mark_cursor_off
;
10654 /* If row containing cursor is marked invalid, there is nothing we
10656 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
10657 if (!cursor_row
->enabled_p
)
10658 goto mark_cursor_off
;
10660 /* This can happen when the new row is shorter than the old one.
10661 In this case, either x_draw_glyphs or clear_end_of_line
10662 should have cleared the cursor. Note that we wouldn't be
10663 able to erase the cursor in this case because we don't have a
10664 cursor glyph at hand. */
10665 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
10666 goto mark_cursor_off
;
10668 /* If the cursor is in the mouse face area, redisplay that when
10669 we clear the cursor. */
10670 if (! NILP (dpyinfo
->mouse_face_window
)
10671 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
10672 && (vpos
> dpyinfo
->mouse_face_beg_row
10673 || (vpos
== dpyinfo
->mouse_face_beg_row
10674 && hpos
>= dpyinfo
->mouse_face_beg_col
))
10675 && (vpos
< dpyinfo
->mouse_face_end_row
10676 || (vpos
== dpyinfo
->mouse_face_end_row
10677 && hpos
< dpyinfo
->mouse_face_end_col
))
10678 /* Don't redraw the cursor's spot in mouse face if it is at the
10679 end of a line (on a newline). The cursor appears there, but
10680 mouse highlighting does not. */
10681 && cursor_row
->used
[TEXT_AREA
] > hpos
)
10682 mouse_face_here_p
= 1;
10684 /* Maybe clear the display under the cursor. */
10685 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
10688 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10690 cursor_glyph
= get_phys_cursor_glyph (w
);
10691 if (cursor_glyph
== NULL
)
10692 goto mark_cursor_off
;
10694 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
10696 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10698 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
10700 cursor_glyph
->pixel_width
,
10701 cursor_row
->visible_height
,
10705 /* Erase the cursor by redrawing the character underneath it. */
10706 if (mouse_face_here_p
)
10707 hl
= DRAW_MOUSE_FACE
;
10708 else if (cursor_row
->inverse_p
)
10709 hl
= DRAW_INVERSE_VIDEO
;
10711 hl
= DRAW_NORMAL_TEXT
;
10712 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
10715 w
->phys_cursor_on_p
= 0;
10716 w
->phys_cursor_type
= NO_CURSOR
;
10720 /* Display or clear cursor of window W. If ON is zero, clear the
10721 cursor. If it is non-zero, display the cursor. If ON is nonzero,
10722 where to put the cursor is specified by HPOS, VPOS, X and Y. */
10725 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
10727 int on
, hpos
, vpos
, x
, y
;
10729 struct frame
*f
= XFRAME (w
->frame
);
10730 int new_cursor_type
;
10731 int new_cursor_width
;
10732 struct glyph_matrix
*current_glyphs
;
10733 struct glyph_row
*glyph_row
;
10734 struct glyph
*glyph
;
10736 /* This is pointless on invisible frames, and dangerous on garbaged
10737 windows and frames; in the latter case, the frame or window may
10738 be in the midst of changing its size, and x and y may be off the
10740 if (! FRAME_VISIBLE_P (f
)
10741 || FRAME_GARBAGED_P (f
)
10742 || vpos
>= w
->current_matrix
->nrows
10743 || hpos
>= w
->current_matrix
->matrix_w
)
10746 /* If cursor is off and we want it off, return quickly. */
10747 if (!on
&& !w
->phys_cursor_on_p
)
10750 current_glyphs
= w
->current_matrix
;
10751 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
10752 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
10754 /* If cursor row is not enabled, we don't really know where to
10755 display the cursor. */
10756 if (!glyph_row
->enabled_p
)
10758 w
->phys_cursor_on_p
= 0;
10762 xassert (interrupt_input_blocked
);
10764 /* Set new_cursor_type to the cursor we want to be displayed. In a
10765 mini-buffer window, we want the cursor only to appear if we are
10766 reading input from this window. For the selected window, we want
10767 the cursor type given by the frame parameter. If explicitly
10768 marked off, draw no cursor. In all other cases, we want a hollow
10770 new_cursor_width
= -1;
10771 if (cursor_in_echo_area
10772 && FRAME_HAS_MINIBUF_P (f
)
10773 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
10775 if (w
== XWINDOW (echo_area_window
))
10776 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
10778 new_cursor_type
= HOLLOW_BOX_CURSOR
;
10782 if (w
!= XWINDOW (selected_window
)
10783 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
)
10785 extern int cursor_in_non_selected_windows
;
10787 if (MINI_WINDOW_P (w
)
10788 || !cursor_in_non_selected_windows
10789 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
10790 new_cursor_type
= NO_CURSOR
;
10792 new_cursor_type
= HOLLOW_BOX_CURSOR
;
10794 else if (w
->cursor_off_p
)
10795 new_cursor_type
= NO_CURSOR
;
10798 struct buffer
*b
= XBUFFER (w
->buffer
);
10800 if (EQ (b
->cursor_type
, Qt
))
10801 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
10803 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
10804 &new_cursor_width
);
10808 /* If cursor is currently being shown and we don't want it to be or
10809 it is in the wrong place, or the cursor type is not what we want,
10811 if (w
->phys_cursor_on_p
10813 || w
->phys_cursor
.x
!= x
10814 || w
->phys_cursor
.y
!= y
10815 || new_cursor_type
!= w
->phys_cursor_type
))
10816 x_erase_phys_cursor (w
);
10818 /* If the cursor is now invisible and we want it to be visible,
10820 if (on
&& !w
->phys_cursor_on_p
)
10822 w
->phys_cursor_ascent
= glyph_row
->ascent
;
10823 w
->phys_cursor_height
= glyph_row
->height
;
10825 /* Set phys_cursor_.* before x_draw_.* is called because some
10826 of them may need the information. */
10827 w
->phys_cursor
.x
= x
;
10828 w
->phys_cursor
.y
= glyph_row
->y
;
10829 w
->phys_cursor
.hpos
= hpos
;
10830 w
->phys_cursor
.vpos
= vpos
;
10831 w
->phys_cursor_type
= new_cursor_type
;
10832 w
->phys_cursor_on_p
= 1;
10834 switch (new_cursor_type
)
10836 case HOLLOW_BOX_CURSOR
:
10837 x_draw_hollow_cursor (w
, glyph_row
);
10840 case FILLED_BOX_CURSOR
:
10841 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
10845 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
10856 if (w
== XWINDOW (f
->selected_window
))
10857 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
10858 xic_set_preeditarea (w
, x
, y
);
10863 if (updating_frame
!= f
)
10864 XFlush (FRAME_X_DISPLAY (f
));
10869 /* Display the cursor on window W, or clear it. X and Y are window
10870 relative pixel coordinates. HPOS and VPOS are glyph matrix
10871 positions. If W is not the selected window, display a hollow
10872 cursor. ON non-zero means display the cursor at X, Y which
10873 correspond to HPOS, VPOS, otherwise it is cleared. */
10876 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
10878 int on
, hpos
, vpos
, x
, y
;
10881 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
10886 /* Display the cursor on window W, or clear it, according to ON_P.
10887 Don't change the cursor's position. */
10890 x_update_cursor (f
, on_p
)
10893 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
10897 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
10898 in the window tree rooted at W. */
10901 x_update_cursor_in_window_tree (w
, on_p
)
10907 if (!NILP (w
->hchild
))
10908 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
10909 else if (!NILP (w
->vchild
))
10910 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
10912 x_update_window_cursor (w
, on_p
);
10914 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
10919 /* Switch the display of W's cursor on or off, according to the value
10923 x_update_window_cursor (w
, on
)
10927 /* Don't update cursor in windows whose frame is in the process
10928 of being deleted. */
10929 if (w
->current_matrix
)
10932 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
10933 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
10943 /* Refresh bitmap kitchen sink icon for frame F
10944 when we get an expose event for it. */
10950 /* Normally, the window manager handles this function. */
10953 /* Make the x-window of frame F use the gnu icon bitmap. */
10956 x_bitmap_icon (f
, file
)
10962 if (FRAME_X_WINDOW (f
) == 0)
10965 /* Free up our existing icon bitmap if any. */
10966 if (f
->output_data
.x
->icon_bitmap
> 0)
10967 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
10968 f
->output_data
.x
->icon_bitmap
= 0;
10970 if (STRINGP (file
))
10971 bitmap_id
= x_create_bitmap_from_file (f
, file
);
10974 /* Create the GNU bitmap if necessary. */
10975 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
10976 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
10977 = x_create_bitmap_from_data (f
, gnu_bits
,
10978 gnu_width
, gnu_height
);
10980 /* The first time we create the GNU bitmap,
10981 this increments the ref-count one extra time.
10982 As a result, the GNU bitmap is never freed.
10983 That way, we don't have to worry about allocating it again. */
10984 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
10986 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
10989 x_wm_set_icon_pixmap (f
, bitmap_id
);
10990 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
10996 /* Make the x-window of frame F use a rectangle with text.
10997 Use ICON_NAME as the text. */
11000 x_text_icon (f
, icon_name
)
11004 if (FRAME_X_WINDOW (f
) == 0)
11009 XTextProperty text
;
11010 text
.value
= (unsigned char *) icon_name
;
11011 text
.encoding
= XA_STRING
;
11013 text
.nitems
= strlen (icon_name
);
11014 #ifdef USE_X_TOOLKIT
11015 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11017 #else /* not USE_X_TOOLKIT */
11018 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11019 #endif /* not USE_X_TOOLKIT */
11021 #else /* not HAVE_X11R4 */
11022 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11023 #endif /* not HAVE_X11R4 */
11025 if (f
->output_data
.x
->icon_bitmap
> 0)
11026 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11027 f
->output_data
.x
->icon_bitmap
= 0;
11028 x_wm_set_icon_pixmap (f
, 0);
11033 #define X_ERROR_MESSAGE_SIZE 200
11035 /* If non-nil, this should be a string.
11036 It means catch X errors and store the error message in this string. */
11038 static Lisp_Object x_error_message_string
;
11040 /* An X error handler which stores the error message in
11041 x_error_message_string. This is called from x_error_handler if
11042 x_catch_errors is in effect. */
11045 x_error_catcher (display
, error
)
11047 XErrorEvent
*error
;
11049 XGetErrorText (display
, error
->error_code
,
11050 XSTRING (x_error_message_string
)->data
,
11051 X_ERROR_MESSAGE_SIZE
);
11054 /* Begin trapping X errors for display DPY. Actually we trap X errors
11055 for all displays, but DPY should be the display you are actually
11058 After calling this function, X protocol errors no longer cause
11059 Emacs to exit; instead, they are recorded in the string
11060 stored in x_error_message_string.
11062 Calling x_check_errors signals an Emacs error if an X error has
11063 occurred since the last call to x_catch_errors or x_check_errors.
11065 Calling x_uncatch_errors resumes the normal error handling. */
11067 void x_check_errors ();
11068 static Lisp_Object
x_catch_errors_unwind ();
11071 x_catch_errors (dpy
)
11074 int count
= specpdl_ptr
- specpdl
;
11076 /* Make sure any errors from previous requests have been dealt with. */
11077 XSync (dpy
, False
);
11079 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11081 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11082 XSTRING (x_error_message_string
)->data
[0] = 0;
11087 /* Unbind the binding that we made to check for X errors. */
11090 x_catch_errors_unwind (old_val
)
11091 Lisp_Object old_val
;
11093 x_error_message_string
= old_val
;
11097 /* If any X protocol errors have arrived since the last call to
11098 x_catch_errors or x_check_errors, signal an Emacs error using
11099 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11102 x_check_errors (dpy
, format
)
11106 /* Make sure to catch any errors incurred so far. */
11107 XSync (dpy
, False
);
11109 if (XSTRING (x_error_message_string
)->data
[0])
11110 error (format
, XSTRING (x_error_message_string
)->data
);
11113 /* Nonzero if we had any X protocol errors
11114 since we did x_catch_errors on DPY. */
11117 x_had_errors_p (dpy
)
11120 /* Make sure to catch any errors incurred so far. */
11121 XSync (dpy
, False
);
11123 return XSTRING (x_error_message_string
)->data
[0] != 0;
11126 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11129 x_clear_errors (dpy
)
11132 XSTRING (x_error_message_string
)->data
[0] = 0;
11135 /* Stop catching X protocol errors and let them make Emacs die.
11136 DPY should be the display that was passed to x_catch_errors.
11137 COUNT should be the value that was returned by
11138 the corresponding call to x_catch_errors. */
11141 x_uncatch_errors (dpy
, count
)
11145 unbind_to (count
, Qnil
);
11149 static unsigned int x_wire_count
;
11152 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11157 /* Handle SIGPIPE, which can happen when the connection to a server
11158 simply goes away. SIGPIPE is handled by x_connection_signal.
11159 Don't need to do anything, because the write which caused the
11160 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11161 which will do the appropriate cleanup for us. */
11164 x_connection_signal (signalnum
) /* If we don't have an argument, */
11165 int signalnum
; /* some compilers complain in signal calls. */
11168 /* USG systems forget handlers when they are used;
11169 must reestablish each time */
11170 signal (signalnum
, x_connection_signal
);
11174 /* Handling X errors. */
11176 /* Handle the loss of connection to display DISPLAY. */
11179 x_connection_closed (display
, error_message
)
11181 char *error_message
;
11183 struct x_display_info
*dpyinfo
= x_display_info_for_display (display
);
11184 Lisp_Object frame
, tail
;
11186 /* Indicate that this display is dead. */
11188 #if 0 /* Closing the display caused a bus error on OpenWindows. */
11189 #ifdef USE_X_TOOLKIT
11190 XtCloseDisplay (display
);
11195 dpyinfo
->display
= 0;
11197 /* First delete frames whose mini-buffers are on frames
11198 that are on the dead display. */
11199 FOR_EACH_FRAME (tail
, frame
)
11201 Lisp_Object minibuf_frame
;
11203 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11204 if (FRAME_X_P (XFRAME (frame
))
11205 && FRAME_X_P (XFRAME (minibuf_frame
))
11206 && ! EQ (frame
, minibuf_frame
)
11207 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11208 Fdelete_frame (frame
, Qt
);
11211 /* Now delete all remaining frames on the dead display.
11212 We are now sure none of these is used as the mini-buffer
11213 for another frame that we need to delete. */
11214 FOR_EACH_FRAME (tail
, frame
)
11215 if (FRAME_X_P (XFRAME (frame
))
11216 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11218 /* Set this to t so that Fdelete_frame won't get confused
11219 trying to find a replacement. */
11220 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
11221 Fdelete_frame (frame
, Qt
);
11225 x_delete_display (dpyinfo
);
11227 if (x_display_list
== 0)
11229 fprintf (stderr
, "%s\n", error_message
);
11230 shut_down_emacs (0, 0, Qnil
);
11234 /* Ordinary stack unwind doesn't deal with these. */
11236 sigunblock (sigmask (SIGIO
));
11238 sigunblock (sigmask (SIGALRM
));
11239 TOTALLY_UNBLOCK_INPUT
;
11241 clear_waiting_for_input ();
11242 handling_signal
= 0;
11243 error ("%s", error_message
);
11246 /* This is the usual handler for X protocol errors.
11247 It kills all frames on the display that we got the error for.
11248 If that was the only one, it prints an error message and kills Emacs. */
11251 x_error_quitter (display
, error
)
11253 XErrorEvent
*error
;
11255 char buf
[256], buf1
[356];
11257 /* Note that there is no real way portable across R3/R4 to get the
11258 original error handler. */
11260 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
11261 sprintf (buf1
, "X protocol error: %s on protocol request %d",
11262 buf
, error
->request_code
);
11263 x_connection_closed (display
, buf1
);
11266 /* This is the first-level handler for X protocol errors.
11267 It calls x_error_quitter or x_error_catcher. */
11270 x_error_handler (display
, error
)
11272 XErrorEvent
*error
;
11274 if (! NILP (x_error_message_string
))
11275 x_error_catcher (display
, error
);
11277 x_error_quitter (display
, error
);
11281 /* This is the handler for X IO errors, always.
11282 It kills all frames on the display that we lost touch with.
11283 If that was the only one, it prints an error message and kills Emacs. */
11286 x_io_error_quitter (display
)
11291 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
11292 x_connection_closed (display
, buf
);
11296 /* Changing the font of the frame. */
11298 /* Give frame F the font named FONTNAME as its default font, and
11299 return the full name of that font. FONTNAME may be a wildcard
11300 pattern; in that case, we choose some font that fits the pattern.
11301 The return value shows which font we chose. */
11304 x_new_font (f
, fontname
)
11306 register char *fontname
;
11308 struct font_info
*fontp
11309 = FS_LOAD_FONT (f
, 0, fontname
, -1);
11314 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
11315 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
11316 f
->output_data
.x
->fontset
= -1;
11318 /* Compute the scroll bar width in character columns. */
11319 if (f
->scroll_bar_pixel_width
> 0)
11321 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11322 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
11326 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11327 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
11330 /* Now make the frame display the given font. */
11331 if (FRAME_X_WINDOW (f
) != 0)
11333 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
11334 f
->output_data
.x
->font
->fid
);
11335 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
11336 f
->output_data
.x
->font
->fid
);
11337 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
11338 f
->output_data
.x
->font
->fid
);
11340 frame_update_line_height (f
);
11341 x_set_window_size (f
, 0, f
->width
, f
->height
);
11344 /* If we are setting a new frame's font for the first time,
11345 there are no faces yet, so this font's height is the line height. */
11346 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
11348 return build_string (fontp
->full_name
);
11351 /* Give frame F the fontset named FONTSETNAME as its default font, and
11352 return the full name of that fontset. FONTSETNAME may be a wildcard
11353 pattern; in that case, we choose some fontset that fits the pattern.
11354 The return value shows which fontset we chose. */
11357 x_new_fontset (f
, fontsetname
)
11361 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
11362 Lisp_Object result
;
11367 if (f
->output_data
.x
->fontset
== fontset
)
11368 /* This fontset is already set in frame F. There's nothing more
11370 return fontset_name (fontset
);
11372 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
11374 if (!STRINGP (result
))
11375 /* Can't load ASCII font. */
11378 /* Since x_new_font doesn't update any fontset information, do it now. */
11379 f
->output_data
.x
->fontset
= fontset
;
11383 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
11384 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
11387 return build_string (fontsetname
);
11391 /***********************************************************************
11393 ***********************************************************************/
11399 /* XIM destroy callback function, which is called whenever the
11400 connection to input method XIM dies. CLIENT_DATA contains a
11401 pointer to the x_display_info structure corresponding to XIM. */
11404 xim_destroy_callback (xim
, client_data
, call_data
)
11406 XPointer client_data
;
11407 XPointer call_data
;
11409 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
11410 Lisp_Object frame
, tail
;
11414 /* No need to call XDestroyIC.. */
11415 FOR_EACH_FRAME (tail
, frame
)
11417 struct frame
*f
= XFRAME (frame
);
11418 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
11420 FRAME_XIC (f
) = NULL
;
11421 if (FRAME_XIC_FONTSET (f
))
11423 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
11424 FRAME_XIC_FONTSET (f
) = NULL
;
11429 /* No need to call XCloseIM. */
11430 dpyinfo
->xim
= NULL
;
11431 XFree (dpyinfo
->xim_styles
);
11435 #endif /* HAVE_X11R6 */
11437 /* Open the connection to the XIM server on display DPYINFO.
11438 RESOURCE_NAME is the resource name Emacs uses. */
11441 xim_open_dpy (dpyinfo
, resource_name
)
11442 struct x_display_info
*dpyinfo
;
11443 char *resource_name
;
11448 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
11449 dpyinfo
->xim
= xim
;
11454 XIMCallback destroy
;
11457 /* Get supported styles and XIM values. */
11458 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
11461 destroy
.callback
= xim_destroy_callback
;
11462 destroy
.client_data
= (XPointer
)dpyinfo
;
11463 /* This isn't prptotyped in OSF 5.0. */
11464 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
11468 #else /* not USE_XIM */
11469 dpyinfo
->xim
= NULL
;
11470 #endif /* not USE_XIM */
11474 #ifdef HAVE_X11R6_XIM
11478 struct x_display_info
*dpyinfo
;
11479 char *resource_name
;
11482 /* XIM instantiate callback function, which is called whenever an XIM
11483 server is available. DISPLAY is teh display of the XIM.
11484 CLIENT_DATA contains a pointer to an xim_inst_t structure created
11485 when the callback was registered. */
11488 xim_instantiate_callback (display
, client_data
, call_data
)
11490 XPointer client_data
;
11491 XPointer call_data
;
11493 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
11494 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
11496 /* We don't support multiple XIM connections. */
11500 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
11502 /* Create XIC for the existing frames on the same display, as long
11503 as they have no XIC. */
11504 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
11506 Lisp_Object tail
, frame
;
11509 FOR_EACH_FRAME (tail
, frame
)
11511 struct frame
*f
= XFRAME (frame
);
11513 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
11514 if (FRAME_XIC (f
) == NULL
)
11516 create_frame_xic (f
);
11517 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
11518 xic_set_statusarea (f
);
11519 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
11521 struct window
*w
= XWINDOW (f
->selected_window
);
11522 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
11531 #endif /* HAVE_X11R6_XIM */
11534 /* Open a connection to the XIM server on display DPYINFO.
11535 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
11536 connection only at the first time. On X11R6, open the connection
11537 in the XIM instantiate callback function. */
11540 xim_initialize (dpyinfo
, resource_name
)
11541 struct x_display_info
*dpyinfo
;
11542 char *resource_name
;
11545 #ifdef HAVE_X11R6_XIM
11546 struct xim_inst_t
*xim_inst
;
11549 dpyinfo
->xim
= NULL
;
11550 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
11551 xim_inst
->dpyinfo
= dpyinfo
;
11552 len
= strlen (resource_name
);
11553 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
11554 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
11555 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
11556 resource_name
, EMACS_CLASS
,
11557 xim_instantiate_callback
,
11558 /* Fixme: This is XPointer in
11559 XFree86 but (XPointer *) on
11560 Tru64, at least. */
11561 (XPointer
) xim_inst
);
11562 #else /* not HAVE_X11R6_XIM */
11563 dpyinfo
->xim
= NULL
;
11564 xim_open_dpy (dpyinfo
, resource_name
);
11565 #endif /* not HAVE_X11R6_XIM */
11567 #else /* not USE_XIM */
11568 dpyinfo
->xim
= NULL
;
11569 #endif /* not USE_XIM */
11573 /* Close the connection to the XIM server on display DPYINFO. */
11576 xim_close_dpy (dpyinfo
)
11577 struct x_display_info
*dpyinfo
;
11580 #ifdef HAVE_X11R6_XIM
11581 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
11583 xim_instantiate_callback
, NULL
);
11584 #endif /* not HAVE_X11R6_XIM */
11585 XCloseIM (dpyinfo
->xim
);
11586 dpyinfo
->xim
= NULL
;
11587 XFree (dpyinfo
->xim_styles
);
11588 #endif /* USE_XIM */
11591 #endif /* not HAVE_X11R6_XIM */
11595 /* Calculate the absolute position in frame F
11596 from its current recorded position values and gravity. */
11599 x_calc_absolute_position (f
)
11603 int win_x
= 0, win_y
= 0;
11604 int flags
= f
->output_data
.x
->size_hint_flags
;
11607 /* We have nothing to do if the current position
11608 is already for the top-left corner. */
11609 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
11612 #ifdef USE_X_TOOLKIT
11613 this_window
= XtWindow (f
->output_data
.x
->widget
);
11615 this_window
= FRAME_X_WINDOW (f
);
11618 /* Find the position of the outside upper-left corner of
11619 the inner window, with respect to the outer window.
11620 But do this only if we will need the results. */
11621 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
11626 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
11629 x_clear_errors (FRAME_X_DISPLAY (f
));
11630 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
11632 /* From-window, to-window. */
11634 f
->output_data
.x
->parent_desc
,
11636 /* From-position, to-position. */
11637 0, 0, &win_x
, &win_y
,
11639 /* Child of win. */
11641 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
11643 Window newroot
, newparent
= 0xdeadbeef;
11644 Window
*newchildren
;
11645 unsigned int nchildren
;
11647 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
11648 &newparent
, &newchildren
, &nchildren
))
11651 XFree ((char *) newchildren
);
11653 f
->output_data
.x
->parent_desc
= newparent
;
11659 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
11663 /* Treat negative positions as relative to the leftmost bottommost
11664 position that fits on the screen. */
11665 if (flags
& XNegative
)
11666 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
11667 - 2 * f
->output_data
.x
->border_width
- win_x
11669 + f
->output_data
.x
->left_pos
);
11671 if (flags
& YNegative
)
11673 int menubar_height
= 0;
11675 #ifdef USE_X_TOOLKIT
11676 if (f
->output_data
.x
->menubar_widget
)
11678 = (f
->output_data
.x
->menubar_widget
->core
.height
11679 + f
->output_data
.x
->menubar_widget
->core
.border_width
);
11682 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
11683 - 2 * f
->output_data
.x
->border_width
11687 + f
->output_data
.x
->top_pos
);
11690 /* The left_pos and top_pos
11691 are now relative to the top and left screen edges,
11692 so the flags should correspond. */
11693 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
11696 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
11697 to really change the position, and 0 when calling from
11698 x_make_frame_visible (in that case, XOFF and YOFF are the current
11699 position values). It is -1 when calling from x_set_frame_parameters,
11700 which means, do adjust for borders but don't change the gravity. */
11703 x_set_offset (f
, xoff
, yoff
, change_gravity
)
11705 register int xoff
, yoff
;
11706 int change_gravity
;
11708 int modified_top
, modified_left
;
11710 if (change_gravity
> 0)
11712 f
->output_data
.x
->top_pos
= yoff
;
11713 f
->output_data
.x
->left_pos
= xoff
;
11714 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
11716 f
->output_data
.x
->size_hint_flags
|= XNegative
;
11718 f
->output_data
.x
->size_hint_flags
|= YNegative
;
11719 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
11721 x_calc_absolute_position (f
);
11724 x_wm_set_size_hint (f
, (long) 0, 0);
11726 modified_left
= f
->output_data
.x
->left_pos
;
11727 modified_top
= f
->output_data
.x
->top_pos
;
11728 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
11729 this seems to be unnecessary and incorrect. rms, 4/17/97. */
11730 /* It is a mystery why we need to add the border_width here
11731 when the frame is already visible, but experiment says we do. */
11732 if (change_gravity
!= 0)
11734 modified_left
+= f
->output_data
.x
->border_width
;
11735 modified_top
+= f
->output_data
.x
->border_width
;
11739 #ifdef USE_X_TOOLKIT
11740 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11741 modified_left
, modified_top
);
11742 #else /* not USE_X_TOOLKIT */
11743 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11744 modified_left
, modified_top
);
11745 #endif /* not USE_X_TOOLKIT */
11749 /* Call this to change the size of frame F's x-window.
11750 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
11751 for this size change and subsequent size changes.
11752 Otherwise we leave the window gravity unchanged. */
11755 x_set_window_size (f
, change_gravity
, cols
, rows
)
11757 int change_gravity
;
11760 #ifndef USE_X_TOOLKIT
11761 int pixelwidth
, pixelheight
;
11766 #ifdef USE_X_TOOLKIT
11768 /* The x and y position of the widget is clobbered by the
11769 call to XtSetValues within EmacsFrameSetCharSize.
11770 This is a real kludge, but I don't understand Xt so I can't
11771 figure out a correct fix. Can anyone else tell me? -- rms. */
11772 int xpos
= f
->output_data
.x
->widget
->core
.x
;
11773 int ypos
= f
->output_data
.x
->widget
->core
.y
;
11774 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
11775 f
->output_data
.x
->widget
->core
.x
= xpos
;
11776 f
->output_data
.x
->widget
->core
.y
= ypos
;
11779 #else /* not USE_X_TOOLKIT */
11781 check_frame_size (f
, &rows
, &cols
);
11782 f
->output_data
.x
->vertical_scroll_bar_extra
11783 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
11785 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
11786 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
11787 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
11788 f
->output_data
.x
->flags_areas_extra
11789 = FRAME_FLAGS_AREA_WIDTH (f
);
11790 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
11791 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
11793 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
11794 x_wm_set_size_hint (f
, (long) 0, 0);
11796 XSync (FRAME_X_DISPLAY (f
), False
);
11797 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11798 pixelwidth
, pixelheight
);
11800 /* Now, strictly speaking, we can't be sure that this is accurate,
11801 but the window manager will get around to dealing with the size
11802 change request eventually, and we'll hear how it went when the
11803 ConfigureNotify event gets here.
11805 We could just not bother storing any of this information here,
11806 and let the ConfigureNotify event set everything up, but that
11807 might be kind of confusing to the Lisp code, since size changes
11808 wouldn't be reported in the frame parameters until some random
11809 point in the future when the ConfigureNotify event arrives.
11811 We pass 1 for DELAY since we can't run Lisp code inside of
11813 change_frame_size (f
, rows
, cols
, 0, 1, 0);
11814 PIXEL_WIDTH (f
) = pixelwidth
;
11815 PIXEL_HEIGHT (f
) = pixelheight
;
11817 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
11818 receive in the ConfigureNotify event; if we get what we asked
11819 for, then the event won't cause the screen to become garbaged, so
11820 we have to make sure to do it here. */
11821 SET_FRAME_GARBAGED (f
);
11823 XFlush (FRAME_X_DISPLAY (f
));
11825 #endif /* not USE_X_TOOLKIT */
11827 /* If cursor was outside the new size, mark it as off. */
11828 mark_window_cursors_off (XWINDOW (f
->root_window
));
11830 /* Clear out any recollection of where the mouse highlighting was,
11831 since it might be in a place that's outside the new frame size.
11832 Actually checking whether it is outside is a pain in the neck,
11833 so don't try--just let the highlighting be done afresh with new size. */
11834 cancel_mouse_face (f
);
11839 /* Mouse warping. */
11842 x_set_mouse_position (f
, x
, y
)
11848 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
11849 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
11851 if (pix_x
< 0) pix_x
= 0;
11852 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
11854 if (pix_y
< 0) pix_y
= 0;
11855 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
11859 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
11860 0, 0, 0, 0, pix_x
, pix_y
);
11864 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
11867 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
11873 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
11874 0, 0, 0, 0, pix_x
, pix_y
);
11878 /* focus shifting, raising and lowering. */
11881 x_focus_on_frame (f
)
11884 #if 0 /* This proves to be unpleasant. */
11888 /* I don't think that the ICCCM allows programs to do things like this
11889 without the interaction of the window manager. Whatever you end up
11890 doing with this code, do it to x_unfocus_frame too. */
11891 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11892 RevertToPointerRoot
, CurrentTime
);
11897 x_unfocus_frame (f
)
11901 /* Look at the remarks in x_focus_on_frame. */
11902 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
11903 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
11904 RevertToPointerRoot
, CurrentTime
);
11908 /* Raise frame F. */
11914 if (f
->async_visible
)
11917 #ifdef USE_X_TOOLKIT
11918 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
11919 #else /* not USE_X_TOOLKIT */
11920 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11921 #endif /* not USE_X_TOOLKIT */
11922 XFlush (FRAME_X_DISPLAY (f
));
11927 /* Lower frame F. */
11933 if (f
->async_visible
)
11936 #ifdef USE_X_TOOLKIT
11937 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
11938 #else /* not USE_X_TOOLKIT */
11939 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11940 #endif /* not USE_X_TOOLKIT */
11941 XFlush (FRAME_X_DISPLAY (f
));
11947 XTframe_raise_lower (f
, raise_flag
)
11957 /* Change of visibility. */
11959 /* This tries to wait until the frame is really visible.
11960 However, if the window manager asks the user where to position
11961 the frame, this will return before the user finishes doing that.
11962 The frame will not actually be visible at that time,
11963 but it will become visible later when the window manager
11964 finishes with it. */
11967 x_make_frame_visible (f
)
11971 int original_top
, original_left
;
11972 int retry_count
= 2;
11978 type
= x_icon_type (f
);
11980 x_bitmap_icon (f
, type
);
11982 if (! FRAME_VISIBLE_P (f
))
11984 /* We test FRAME_GARBAGED_P here to make sure we don't
11985 call x_set_offset a second time
11986 if we get to x_make_frame_visible a second time
11987 before the window gets really visible. */
11988 if (! FRAME_ICONIFIED_P (f
)
11989 && ! f
->output_data
.x
->asked_for_visible
)
11990 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
11992 f
->output_data
.x
->asked_for_visible
= 1;
11994 if (! EQ (Vx_no_window_manager
, Qt
))
11995 x_wm_set_window_state (f
, NormalState
);
11996 #ifdef USE_X_TOOLKIT
11997 /* This was XtPopup, but that did nothing for an iconified frame. */
11998 XtMapWidget (f
->output_data
.x
->widget
);
11999 #else /* not USE_X_TOOLKIT */
12000 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12001 #endif /* not USE_X_TOOLKIT */
12002 #if 0 /* This seems to bring back scroll bars in the wrong places
12003 if the window configuration has changed. They seem
12004 to come back ok without this. */
12005 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12006 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12010 XFlush (FRAME_X_DISPLAY (f
));
12012 /* Synchronize to ensure Emacs knows the frame is visible
12013 before we do anything else. We do this loop with input not blocked
12014 so that incoming events are handled. */
12018 /* This must be before UNBLOCK_INPUT
12019 since events that arrive in response to the actions above
12020 will set it when they are handled. */
12021 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12023 original_left
= f
->output_data
.x
->left_pos
;
12024 original_top
= f
->output_data
.x
->top_pos
;
12026 /* This must come after we set COUNT. */
12029 /* We unblock here so that arriving X events are processed. */
12031 /* Now move the window back to where it was "supposed to be".
12032 But don't do it if the gravity is negative.
12033 When the gravity is negative, this uses a position
12034 that is 3 pixels too low. Perhaps that's really the border width.
12036 Don't do this if the window has never been visible before,
12037 because the window manager may choose the position
12038 and we don't want to override it. */
12040 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12041 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12042 && previously_visible
)
12046 unsigned int width
, height
, border
, depth
;
12050 /* On some window managers (such as FVWM) moving an existing
12051 window, even to the same place, causes the window manager
12052 to introduce an offset. This can cause the window to move
12053 to an unexpected location. Check the geometry (a little
12054 slow here) and then verify that the window is in the right
12055 place. If the window is not in the right place, move it
12056 there, and take the potential window manager hit. */
12057 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12058 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12060 if (original_left
!= x
|| original_top
!= y
)
12061 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12062 original_left
, original_top
);
12067 XSETFRAME (frame
, f
);
12069 /* Wait until the frame is visible. Process X events until a
12070 MapNotify event has been seen, or until we think we won't get a
12071 MapNotify at all.. */
12072 for (count
= input_signal_count
+ 10;
12073 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12075 /* Force processing of queued events. */
12078 /* Machines that do polling rather than SIGIO have been
12079 observed to go into a busy-wait here. So we'll fake an
12080 alarm signal to let the handler know that there's something
12081 to be read. We used to raise a real alarm, but it seems
12082 that the handler isn't always enabled here. This is
12084 if (input_polling_used ())
12086 /* It could be confusing if a real alarm arrives while
12087 processing the fake one. Turn it off and let the
12088 handler reset it. */
12089 extern void poll_for_input_1
P_ ((void));
12090 int old_poll_suppress_count
= poll_suppress_count
;
12091 poll_suppress_count
= 1;
12092 poll_for_input_1 ();
12093 poll_suppress_count
= old_poll_suppress_count
;
12096 /* See if a MapNotify event has been processed. */
12097 FRAME_SAMPLE_VISIBILITY (f
);
12102 (let ((f (selected-frame)))
12106 the frame is not raised with various window managers on
12107 FreeBSD, Linux and Solaris. It turns out that, for some
12108 unknown reason, the call to XtMapWidget is completely ignored.
12109 Mapping the widget a second time works. */
12111 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12116 /* Change from mapped state to withdrawn state. */
12118 /* Make the frame visible (mapped and not iconified). */
12121 x_make_frame_invisible (f
)
12126 #ifdef USE_X_TOOLKIT
12127 /* Use the frame's outermost window, not the one we normally draw on. */
12128 window
= XtWindow (f
->output_data
.x
->widget
);
12129 #else /* not USE_X_TOOLKIT */
12130 window
= FRAME_X_WINDOW (f
);
12131 #endif /* not USE_X_TOOLKIT */
12133 /* Don't keep the highlight on an invisible frame. */
12134 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12135 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12137 #if 0/* This might add unreliability; I don't trust it -- rms. */
12138 if (! f
->async_visible
&& ! f
->async_iconified
)
12144 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12145 that the current position of the window is user-specified, rather than
12146 program-specified, so that when the window is mapped again, it will be
12147 placed at the same location, without forcing the user to position it
12148 by hand again (they have already done that once for this window.) */
12149 x_wm_set_size_hint (f
, (long) 0, 1);
12153 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12154 DefaultScreen (FRAME_X_DISPLAY (f
))))
12156 UNBLOCK_INPUT_RESIGNAL
;
12157 error ("Can't notify window manager of window withdrawal");
12159 #else /* ! defined (HAVE_X11R4) */
12161 /* Tell the window manager what we're going to do. */
12162 if (! EQ (Vx_no_window_manager
, Qt
))
12166 unmap
.xunmap
.type
= UnmapNotify
;
12167 unmap
.xunmap
.window
= window
;
12168 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12169 unmap
.xunmap
.from_configure
= False
;
12170 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12171 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12173 SubstructureRedirectMaskSubstructureNotifyMask
,
12176 UNBLOCK_INPUT_RESIGNAL
;
12177 error ("Can't notify window manager of withdrawal");
12181 /* Unmap the window ourselves. Cheeky! */
12182 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12183 #endif /* ! defined (HAVE_X11R4) */
12185 /* We can't distinguish this from iconification
12186 just by the event that we get from the server.
12187 So we can't win using the usual strategy of letting
12188 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
12189 and synchronize with the server to make sure we agree. */
12191 FRAME_ICONIFIED_P (f
) = 0;
12192 f
->async_visible
= 0;
12193 f
->async_iconified
= 0;
12200 /* Change window state from mapped to iconified. */
12203 x_iconify_frame (f
)
12209 /* Don't keep the highlight on an invisible frame. */
12210 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12211 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12213 if (f
->async_iconified
)
12218 FRAME_SAMPLE_VISIBILITY (f
);
12220 type
= x_icon_type (f
);
12222 x_bitmap_icon (f
, type
);
12224 #ifdef USE_X_TOOLKIT
12226 if (! FRAME_VISIBLE_P (f
))
12228 if (! EQ (Vx_no_window_manager
, Qt
))
12229 x_wm_set_window_state (f
, IconicState
);
12230 /* This was XtPopup, but that did nothing for an iconified frame. */
12231 XtMapWidget (f
->output_data
.x
->widget
);
12232 /* The server won't give us any event to indicate
12233 that an invisible frame was changed to an icon,
12234 so we have to record it here. */
12237 f
->async_iconified
= 1;
12238 f
->async_visible
= 0;
12243 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
12244 XtWindow (f
->output_data
.x
->widget
),
12245 DefaultScreen (FRAME_X_DISPLAY (f
)));
12249 error ("Can't notify window manager of iconification");
12251 f
->async_iconified
= 1;
12252 f
->async_visible
= 0;
12256 XFlush (FRAME_X_DISPLAY (f
));
12258 #else /* not USE_X_TOOLKIT */
12260 /* Make sure the X server knows where the window should be positioned,
12261 in case the user deiconifies with the window manager. */
12262 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
12263 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12265 /* Since we don't know which revision of X we're running, we'll use both
12266 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
12268 /* X11R4: send a ClientMessage to the window manager using the
12269 WM_CHANGE_STATE type. */
12273 message
.xclient
.window
= FRAME_X_WINDOW (f
);
12274 message
.xclient
.type
= ClientMessage
;
12275 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
12276 message
.xclient
.format
= 32;
12277 message
.xclient
.data
.l
[0] = IconicState
;
12279 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12280 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12282 SubstructureRedirectMask
| SubstructureNotifyMask
,
12285 UNBLOCK_INPUT_RESIGNAL
;
12286 error ("Can't notify window manager of iconification");
12290 /* X11R3: set the initial_state field of the window manager hints to
12292 x_wm_set_window_state (f
, IconicState
);
12294 if (!FRAME_VISIBLE_P (f
))
12296 /* If the frame was withdrawn, before, we must map it. */
12297 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12300 f
->async_iconified
= 1;
12301 f
->async_visible
= 0;
12303 XFlush (FRAME_X_DISPLAY (f
));
12305 #endif /* not USE_X_TOOLKIT */
12308 /* Destroy the X window of frame F. */
12311 x_destroy_window (f
)
12314 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12318 /* If a display connection is dead, don't try sending more
12319 commands to the X server. */
12320 if (dpyinfo
->display
!= 0)
12322 if (f
->output_data
.x
->icon_desc
!= 0)
12323 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
12326 free_frame_xic (f
);
12328 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->window_desc
);
12329 #ifdef USE_X_TOOLKIT
12330 if (f
->output_data
.x
->widget
)
12331 XtDestroyWidget (f
->output_data
.x
->widget
);
12332 free_frame_menubar (f
);
12333 #endif /* USE_X_TOOLKIT */
12335 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
12336 unload_color (f
, f
->output_data
.x
->background_pixel
);
12337 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
12338 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
12339 unload_color (f
, f
->output_data
.x
->border_pixel
);
12340 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
12341 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
12342 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
12343 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
12344 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
12345 if (f
->output_data
.x
->white_relief
.allocated_p
)
12346 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
12347 if (f
->output_data
.x
->black_relief
.allocated_p
)
12348 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
12350 free_frame_faces (f
);
12351 XFlush (FRAME_X_DISPLAY (f
));
12354 if (f
->output_data
.x
->saved_menu_event
)
12355 xfree (f
->output_data
.x
->saved_menu_event
);
12357 xfree (f
->output_data
.x
);
12358 f
->output_data
.x
= 0;
12359 if (f
== dpyinfo
->x_focus_frame
)
12360 dpyinfo
->x_focus_frame
= 0;
12361 if (f
== dpyinfo
->x_focus_event_frame
)
12362 dpyinfo
->x_focus_event_frame
= 0;
12363 if (f
== dpyinfo
->x_highlight_frame
)
12364 dpyinfo
->x_highlight_frame
= 0;
12366 dpyinfo
->reference_count
--;
12368 if (f
== dpyinfo
->mouse_face_mouse_frame
)
12370 dpyinfo
->mouse_face_beg_row
12371 = dpyinfo
->mouse_face_beg_col
= -1;
12372 dpyinfo
->mouse_face_end_row
12373 = dpyinfo
->mouse_face_end_col
= -1;
12374 dpyinfo
->mouse_face_window
= Qnil
;
12375 dpyinfo
->mouse_face_deferred_gc
= 0;
12376 dpyinfo
->mouse_face_mouse_frame
= 0;
12382 /* Setting window manager hints. */
12384 /* Set the normal size hints for the window manager, for frame F.
12385 FLAGS is the flags word to use--or 0 meaning preserve the flags
12386 that the window now has.
12387 If USER_POSITION is nonzero, we set the USPosition
12388 flag (this is useful when FLAGS is 0). */
12391 x_wm_set_size_hint (f
, flags
, user_position
)
12396 XSizeHints size_hints
;
12398 #ifdef USE_X_TOOLKIT
12401 Dimension widget_width
, widget_height
;
12402 Window window
= XtWindow (f
->output_data
.x
->widget
);
12403 #else /* not USE_X_TOOLKIT */
12404 Window window
= FRAME_X_WINDOW (f
);
12405 #endif /* not USE_X_TOOLKIT */
12407 /* Setting PMaxSize caused various problems. */
12408 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
12410 size_hints
.x
= f
->output_data
.x
->left_pos
;
12411 size_hints
.y
= f
->output_data
.x
->top_pos
;
12413 #ifdef USE_X_TOOLKIT
12414 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
12415 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
12416 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
12417 size_hints
.height
= widget_height
;
12418 size_hints
.width
= widget_width
;
12419 #else /* not USE_X_TOOLKIT */
12420 size_hints
.height
= PIXEL_HEIGHT (f
);
12421 size_hints
.width
= PIXEL_WIDTH (f
);
12422 #endif /* not USE_X_TOOLKIT */
12424 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
12425 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
12426 size_hints
.max_width
12427 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
12428 size_hints
.max_height
12429 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
12431 /* Calculate the base and minimum sizes.
12433 (When we use the X toolkit, we don't do it here.
12434 Instead we copy the values that the widgets are using, below.) */
12435 #ifndef USE_X_TOOLKIT
12437 int base_width
, base_height
;
12438 int min_rows
= 0, min_cols
= 0;
12440 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
12441 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
12443 check_frame_size (f
, &min_rows
, &min_cols
);
12445 /* The window manager uses the base width hints to calculate the
12446 current number of rows and columns in the frame while
12447 resizing; min_width and min_height aren't useful for this
12448 purpose, since they might not give the dimensions for a
12449 zero-row, zero-column frame.
12451 We use the base_width and base_height members if we have
12452 them; otherwise, we set the min_width and min_height members
12453 to the size for a zero x zero frame. */
12456 size_hints
.flags
|= PBaseSize
;
12457 size_hints
.base_width
= base_width
;
12458 size_hints
.base_height
= base_height
;
12459 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
12460 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
12462 size_hints
.min_width
= base_width
;
12463 size_hints
.min_height
= base_height
;
12467 /* If we don't need the old flags, we don't need the old hint at all. */
12470 size_hints
.flags
|= flags
;
12473 #endif /* not USE_X_TOOLKIT */
12476 XSizeHints hints
; /* Sometimes I hate X Windows... */
12477 long supplied_return
;
12481 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
12484 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
12487 #ifdef USE_X_TOOLKIT
12488 size_hints
.base_height
= hints
.base_height
;
12489 size_hints
.base_width
= hints
.base_width
;
12490 size_hints
.min_height
= hints
.min_height
;
12491 size_hints
.min_width
= hints
.min_width
;
12495 size_hints
.flags
|= flags
;
12500 if (hints
.flags
& PSize
)
12501 size_hints
.flags
|= PSize
;
12502 if (hints
.flags
& PPosition
)
12503 size_hints
.flags
|= PPosition
;
12504 if (hints
.flags
& USPosition
)
12505 size_hints
.flags
|= USPosition
;
12506 if (hints
.flags
& USSize
)
12507 size_hints
.flags
|= USSize
;
12511 #ifndef USE_X_TOOLKIT
12516 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
12517 size_hints
.flags
|= PWinGravity
;
12521 size_hints
.flags
&= ~ PPosition
;
12522 size_hints
.flags
|= USPosition
;
12524 #endif /* PWinGravity */
12527 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
12529 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
12533 /* Used for IconicState or NormalState */
12536 x_wm_set_window_state (f
, state
)
12540 #ifdef USE_X_TOOLKIT
12543 XtSetArg (al
[0], XtNinitialState
, state
);
12544 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
12545 #else /* not USE_X_TOOLKIT */
12546 Window window
= FRAME_X_WINDOW (f
);
12548 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
12549 f
->output_data
.x
->wm_hints
.initial_state
= state
;
12551 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
12552 #endif /* not USE_X_TOOLKIT */
12556 x_wm_set_icon_pixmap (f
, pixmap_id
)
12560 Pixmap icon_pixmap
;
12562 #ifndef USE_X_TOOLKIT
12563 Window window
= FRAME_X_WINDOW (f
);
12568 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
12569 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
12573 /* It seems there is no way to turn off use of an icon pixmap.
12574 The following line does it, only if no icon has yet been created,
12575 for some window managers. But with mwm it crashes.
12576 Some people say it should clear the IconPixmapHint bit in this case,
12577 but that doesn't work, and the X consortium said it isn't the
12578 right thing at all. Since there is no way to win,
12579 best to explicitly give up. */
12581 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
12587 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
12591 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
12592 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
12595 #else /* not USE_X_TOOLKIT */
12597 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
12598 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
12600 #endif /* not USE_X_TOOLKIT */
12604 x_wm_set_icon_position (f
, icon_x
, icon_y
)
12606 int icon_x
, icon_y
;
12608 #ifdef USE_X_TOOLKIT
12609 Window window
= XtWindow (f
->output_data
.x
->widget
);
12611 Window window
= FRAME_X_WINDOW (f
);
12614 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
12615 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
12616 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
12618 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
12622 /***********************************************************************
12624 ***********************************************************************/
12626 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
12629 x_get_font_info (f
, font_idx
)
12633 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
12637 /* Return a list of names of available fonts matching PATTERN on frame
12638 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
12639 to be listed. Frame F NULL means we have not yet created any
12640 frame on X, and consult the first display in x_display_list.
12641 MAXNAMES sets a limit on how many fonts to match. */
12644 x_list_fonts (f
, pattern
, size
, maxnames
)
12646 Lisp_Object pattern
;
12650 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
12651 Lisp_Object tem
, second_best
;
12652 Display
*dpy
= f
!= NULL
? FRAME_X_DISPLAY (f
) : x_display_list
->display
;
12653 int try_XLoadQueryFont
= 0;
12656 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
12657 if (NILP (patterns
))
12658 patterns
= Fcons (pattern
, Qnil
);
12660 if (maxnames
== 1 && !size
)
12661 /* We can return any single font matching PATTERN. */
12662 try_XLoadQueryFont
= 1;
12664 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
12667 char **names
= NULL
;
12669 pattern
= XCAR (patterns
);
12670 /* See if we cached the result for this particular query.
12671 The cache is an alist of the form:
12672 (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
12674 if (f
&& (tem
= XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
),
12675 key
= Fcons (pattern
, make_number (maxnames
)),
12676 !NILP (list
= Fassoc (key
, tem
))))
12678 list
= Fcdr_safe (list
);
12679 /* We have a cashed list. Don't have to get the list again. */
12683 /* At first, put PATTERN in the cache. */
12686 count
= x_catch_errors (dpy
);
12688 if (try_XLoadQueryFont
)
12691 unsigned long value
;
12693 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
12694 if (x_had_errors_p (dpy
))
12696 /* This error is perhaps due to insufficient memory on X
12697 server. Let's just ignore it. */
12699 x_clear_errors (dpy
);
12703 && XGetFontProperty (font
, XA_FONT
, &value
))
12705 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
12706 int len
= strlen (name
);
12709 /* If DXPC (a Differential X Protocol Compressor)
12710 Ver.3.7 is running, XGetAtomName will return null
12711 string. We must avoid such a name. */
12713 try_XLoadQueryFont
= 0;
12717 names
= (char **) alloca (sizeof (char *));
12718 /* Some systems only allow alloca assigned to a
12720 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
12721 bcopy (name
, names
[0], len
+ 1);
12726 try_XLoadQueryFont
= 0;
12729 XFreeFont (dpy
, font
);
12732 if (!try_XLoadQueryFont
)
12734 /* We try at least 10 fonts because XListFonts will return
12735 auto-scaled fonts at the head. */
12736 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
12738 if (x_had_errors_p (dpy
))
12740 /* This error is perhaps due to insufficient memory on X
12741 server. Let's just ignore it. */
12743 x_clear_errors (dpy
);
12747 x_uncatch_errors (dpy
, count
);
12754 /* Make a list of all the fonts we got back.
12755 Store that in the font cache for the display. */
12756 for (i
= 0; i
< num_fonts
; i
++)
12759 char *p
= names
[i
];
12760 int average_width
= -1, dashes
= 0;
12762 /* Count the number of dashes in NAMES[I]. If there are
12763 14 dashes, and the field value following 12th dash
12764 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
12765 is usually too ugly to be used for editing. Let's
12771 if (dashes
== 7) /* PIXEL_SIZE field */
12773 else if (dashes
== 12) /* AVERAGE_WIDTH field */
12774 average_width
= atoi (p
);
12776 if (dashes
< 14 || average_width
!= 0)
12778 tem
= build_string (names
[i
]);
12779 if (NILP (Fassoc (tem
, list
)))
12781 if (STRINGP (Vx_pixel_size_width_font_regexp
)
12782 && ((fast_c_string_match_ignore_case
12783 (Vx_pixel_size_width_font_regexp
, names
[i
]))
12785 /* We can set the value of PIXEL_SIZE to the
12786 width of this font. */
12787 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
12789 /* For the moment, width is not known. */
12790 list
= Fcons (Fcons (tem
, Qnil
), list
);
12794 if (!try_XLoadQueryFont
)
12795 XFreeFontNames (names
);
12798 /* Now store the result in the cache. */
12800 XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)
12801 = Fcons (Fcons (key
, list
),
12802 XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
));
12805 if (NILP (list
)) continue; /* Try the remaining alternatives. */
12807 newlist
= second_best
= Qnil
;
12808 /* Make a list of the fonts that have the right width. */
12809 for (; CONSP (list
); list
= XCDR (list
))
12815 if (!CONSP (tem
) || NILP (XCAR (tem
)))
12819 newlist
= Fcons (XCAR (tem
), newlist
);
12823 if (!INTEGERP (XCDR (tem
)))
12825 /* Since we have not yet known the size of this font, we
12826 must try slow function call XLoadQueryFont. */
12827 XFontStruct
*thisinfo
;
12830 count
= x_catch_errors (dpy
);
12831 thisinfo
= XLoadQueryFont (dpy
,
12832 XSTRING (XCAR (tem
))->data
);
12833 if (x_had_errors_p (dpy
))
12835 /* This error is perhaps due to insufficient memory on X
12836 server. Let's just ignore it. */
12838 x_clear_errors (dpy
);
12840 x_uncatch_errors (dpy
, count
);
12846 = (thisinfo
->min_bounds
.width
== 0
12848 : make_number (thisinfo
->max_bounds
.width
));
12849 XFreeFont (dpy
, thisinfo
);
12852 /* For unknown reason, the previous call of XListFont had
12853 returned a font which can't be opened. Record the size
12854 as 0 not to try to open it again. */
12855 XCDR (tem
) = make_number (0);
12858 found_size
= XINT (XCDR (tem
));
12859 if (found_size
== size
)
12860 newlist
= Fcons (XCAR (tem
), newlist
);
12861 else if (found_size
> 0)
12863 if (NILP (second_best
))
12865 else if (found_size
< size
)
12867 if (XINT (XCDR (second_best
)) > size
12868 || XINT (XCDR (second_best
)) < found_size
)
12873 if (XINT (XCDR (second_best
)) > size
12874 && XINT (XCDR (second_best
)) > found_size
)
12879 if (!NILP (newlist
))
12881 else if (!NILP (second_best
))
12883 newlist
= Fcons (XCAR (second_best
), Qnil
);
12894 /* Check that FONT is valid on frame F. It is if it can be found in F's
12898 x_check_font (f
, font
)
12903 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12905 xassert (font
!= NULL
);
12907 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
12908 if (dpyinfo
->font_table
[i
].name
12909 && font
== dpyinfo
->font_table
[i
].font
)
12912 xassert (i
< dpyinfo
->n_fonts
);
12915 #endif /* GLYPH_DEBUG != 0 */
12917 /* Set *W to the minimum width, *H to the minimum font height of FONT.
12918 Note: There are (broken) X fonts out there with invalid XFontStruct
12919 min_bounds contents. For example, handa@etl.go.jp reports that
12920 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
12921 have font->min_bounds.width == 0. */
12924 x_font_min_bounds (font
, w
, h
)
12928 *h
= FONT_HEIGHT (font
);
12929 *w
= font
->min_bounds
.width
;
12931 /* Try to handle the case where FONT->min_bounds has invalid
12932 contents. Since the only font known to have invalid min_bounds
12933 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
12935 *w
= font
->max_bounds
.width
;
12939 /* Compute the smallest character width and smallest font height over
12940 all fonts available on frame F. Set the members smallest_char_width
12941 and smallest_font_height in F's x_display_info structure to
12942 the values computed. Value is non-zero if smallest_font_height or
12943 smallest_char_width become smaller than they were before. */
12946 x_compute_min_glyph_bounds (f
)
12950 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12952 int old_width
= dpyinfo
->smallest_char_width
;
12953 int old_height
= dpyinfo
->smallest_font_height
;
12955 dpyinfo
->smallest_font_height
= 100000;
12956 dpyinfo
->smallest_char_width
= 100000;
12958 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
12959 if (dpyinfo
->font_table
[i
].name
)
12961 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
12964 font
= (XFontStruct
*) fontp
->font
;
12965 xassert (font
!= (XFontStruct
*) ~0);
12966 x_font_min_bounds (font
, &w
, &h
);
12968 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
12969 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
12972 xassert (dpyinfo
->smallest_char_width
> 0
12973 && dpyinfo
->smallest_font_height
> 0);
12975 return (dpyinfo
->n_fonts
== 1
12976 || dpyinfo
->smallest_char_width
< old_width
12977 || dpyinfo
->smallest_font_height
< old_height
);
12981 /* Load font named FONTNAME of the size SIZE for frame F, and return a
12982 pointer to the structure font_info while allocating it dynamically.
12983 If SIZE is 0, load any size of font.
12984 If loading is failed, return NULL. */
12987 x_load_font (f
, fontname
, size
)
12989 register char *fontname
;
12992 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12993 Lisp_Object font_names
;
12996 /* Get a list of all the fonts that match this name. Once we
12997 have a list of matching fonts, we compare them against the fonts
12998 we already have by comparing names. */
12999 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13001 if (!NILP (font_names
))
13006 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13007 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13008 if (dpyinfo
->font_table
[i
].name
13009 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13010 XSTRING (XCAR (tail
))->data
)
13011 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13012 XSTRING (XCAR (tail
))->data
)))
13013 return (dpyinfo
->font_table
+ i
);
13016 /* Load the font and add it to the table. */
13020 struct font_info
*fontp
;
13021 unsigned long value
;
13024 /* If we have found fonts by x_list_font, load one of them. If
13025 not, we still try to load a font by the name given as FONTNAME
13026 because XListFonts (called in x_list_font) of some X server has
13027 a bug of not finding a font even if the font surely exists and
13028 is loadable by XLoadQueryFont. */
13029 if (size
> 0 && !NILP (font_names
))
13030 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13033 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13034 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13035 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13037 /* This error is perhaps due to insufficient memory on X
13038 server. Let's just ignore it. */
13040 x_clear_errors (FRAME_X_DISPLAY (f
));
13042 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13047 /* Find a free slot in the font table. */
13048 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13049 if (dpyinfo
->font_table
[i
].name
== NULL
)
13052 /* If no free slot found, maybe enlarge the font table. */
13053 if (i
== dpyinfo
->n_fonts
13054 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13057 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13058 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13059 dpyinfo
->font_table
13060 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13063 fontp
= dpyinfo
->font_table
+ i
;
13064 if (i
== dpyinfo
->n_fonts
)
13065 ++dpyinfo
->n_fonts
;
13067 /* Now fill in the slots of *FONTP. */
13069 fontp
->font
= font
;
13070 fontp
->font_idx
= i
;
13071 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13072 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13074 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13076 if (XGetFontProperty (font
, XA_FONT
, &value
))
13078 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13082 /* Count the number of dashes in the "full name".
13083 If it is too few, this isn't really the font's full name,
13085 In X11R4, the fonts did not come with their canonical names
13096 full_name
= (char *) xmalloc (p
- name
+ 1);
13097 bcopy (name
, full_name
, p
- name
+ 1);
13103 if (full_name
!= 0)
13104 fontp
->full_name
= full_name
;
13106 fontp
->full_name
= fontp
->name
;
13108 fontp
->size
= font
->max_bounds
.width
;
13109 fontp
->height
= FONT_HEIGHT (font
);
13111 /* For some font, ascent and descent in max_bounds field is
13112 larger than the above value. */
13113 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
13114 if (max_height
> fontp
->height
)
13115 fontp
->height
= max_height
;
13118 if (NILP (font_names
))
13120 /* We come here because of a bug of XListFonts mentioned at
13121 the head of this block. Let's store this information in
13122 the cache for x_list_fonts. */
13123 Lisp_Object lispy_name
= build_string (fontname
);
13124 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13126 XCDR (dpyinfo
->name_list_element
)
13127 = Fcons (Fcons (Fcons (lispy_name
, make_number (256)),
13128 Fcons (Fcons (lispy_full_name
,
13129 make_number (fontp
->size
)),
13131 XCDR (dpyinfo
->name_list_element
));
13133 XCDR (dpyinfo
->name_list_element
)
13134 = Fcons (Fcons (Fcons (lispy_full_name
, make_number (256)),
13135 Fcons (Fcons (lispy_full_name
,
13136 make_number (fontp
->size
)),
13138 XCDR (dpyinfo
->name_list_element
));
13141 /* The slot `encoding' specifies how to map a character
13142 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
13143 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
13144 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
13145 2:0xA020..0xFF7F). For the moment, we don't know which charset
13146 uses this font. So, we set information in fontp->encoding[1]
13147 which is never used by any charset. If mapping can't be
13148 decided, set FONT_ENCODING_NOT_DECIDED. */
13150 = (font
->max_byte1
== 0
13152 ? (font
->min_char_or_byte2
< 0x80
13153 ? (font
->max_char_or_byte2
< 0x80
13154 ? 0 /* 0x20..0x7F */
13155 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
13156 : 1) /* 0xA0..0xFF */
13158 : (font
->min_byte1
< 0x80
13159 ? (font
->max_byte1
< 0x80
13160 ? (font
->min_char_or_byte2
< 0x80
13161 ? (font
->max_char_or_byte2
< 0x80
13162 ? 0 /* 0x2020..0x7F7F */
13163 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
13164 : 3) /* 0x20A0..0x7FFF */
13165 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
13166 : (font
->min_char_or_byte2
< 0x80
13167 ? (font
->max_char_or_byte2
< 0x80
13168 ? 2 /* 0xA020..0xFF7F */
13169 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
13170 : 1))); /* 0xA0A0..0xFFFF */
13172 fontp
->baseline_offset
13173 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
13174 ? (long) value
: 0);
13175 fontp
->relative_compose
13176 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
13177 ? (long) value
: 0);
13178 fontp
->default_ascent
13179 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
13180 ? (long) value
: 0);
13182 /* Set global flag fonts_changed_p to non-zero if the font loaded
13183 has a character with a smaller width than any other character
13184 before, or if the font loaded has a smalle>r height than any
13185 other font loaded before. If this happens, it will make a
13186 glyph matrix reallocation necessary. */
13187 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
13194 /* Return a pointer to struct font_info of a font named FONTNAME for
13195 frame F. If no such font is loaded, return NULL. */
13198 x_query_font (f
, fontname
)
13200 register char *fontname
;
13202 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13205 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13206 if (dpyinfo
->font_table
[i
].name
13207 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
13208 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
13209 return (dpyinfo
->font_table
+ i
);
13214 /* Find a CCL program for a font specified by FONTP, and set the member
13215 `encoder' of the structure. */
13218 x_find_ccl_program (fontp
)
13219 struct font_info
*fontp
;
13221 Lisp_Object list
, elt
;
13224 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
13228 && STRINGP (XCAR (elt
))
13229 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
13231 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
13238 struct ccl_program
*ccl
13239 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
13241 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
13244 fontp
->font_encoder
= ccl
;
13250 /***********************************************************************
13252 ***********************************************************************/
13254 #ifdef USE_X_TOOLKIT
13255 static XrmOptionDescRec emacs_options
[] = {
13256 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13257 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13259 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13260 XrmoptionSepArg
, NULL
},
13261 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13263 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13264 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13265 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13266 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13267 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13268 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13269 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13271 #endif /* USE_X_TOOLKIT */
13273 static int x_initialized
;
13275 #ifdef MULTI_KBOARD
13276 /* Test whether two display-name strings agree up to the dot that separates
13277 the screen number from the server number. */
13279 same_x_server (name1
, name2
)
13280 char *name1
, *name2
;
13282 int seen_colon
= 0;
13283 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
13284 int system_name_length
= strlen (system_name
);
13285 int length_until_period
= 0;
13287 while (system_name
[length_until_period
] != 0
13288 && system_name
[length_until_period
] != '.')
13289 length_until_period
++;
13291 /* Treat `unix' like an empty host name. */
13292 if (! strncmp (name1
, "unix:", 5))
13294 if (! strncmp (name2
, "unix:", 5))
13296 /* Treat this host's name like an empty host name. */
13297 if (! strncmp (name1
, system_name
, system_name_length
)
13298 && name1
[system_name_length
] == ':')
13299 name1
+= system_name_length
;
13300 if (! strncmp (name2
, system_name
, system_name_length
)
13301 && name2
[system_name_length
] == ':')
13302 name2
+= system_name_length
;
13303 /* Treat this host's domainless name like an empty host name. */
13304 if (! strncmp (name1
, system_name
, length_until_period
)
13305 && name1
[length_until_period
] == ':')
13306 name1
+= length_until_period
;
13307 if (! strncmp (name2
, system_name
, length_until_period
)
13308 && name2
[length_until_period
] == ':')
13309 name2
+= length_until_period
;
13311 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13315 if (seen_colon
&& *name1
== '.')
13319 && (*name1
== '.' || *name1
== '\0')
13320 && (*name2
== '.' || *name2
== '\0'));
13324 struct x_display_info
*
13325 x_term_init (display_name
, xrm_option
, resource_name
)
13326 Lisp_Object display_name
;
13328 char *resource_name
;
13332 struct x_display_info
*dpyinfo
;
13337 if (!x_initialized
)
13343 #ifdef USE_X_TOOLKIT
13344 /* weiner@footloose.sps.mot.com reports that this causes
13346 X protocol error: BadAtom (invalid Atom parameter)
13347 on protocol request 18skiloaf.
13348 So let's not use it until R6. */
13349 #ifdef HAVE_X11XTR6
13350 XtSetLanguageProc (NULL
, NULL
, NULL
);
13361 argv
[argc
++] = "-xrm";
13362 argv
[argc
++] = xrm_option
;
13364 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
13365 resource_name
, EMACS_CLASS
,
13366 emacs_options
, XtNumber (emacs_options
),
13369 #ifdef HAVE_X11XTR6
13370 /* I think this is to compensate for XtSetLanguageProc. */
13375 #else /* not USE_X_TOOLKIT */
13377 XSetLocaleModifiers ("");
13379 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
13380 #endif /* not USE_X_TOOLKIT */
13382 /* Detect failure. */
13389 /* We have definitely succeeded. Record the new connection. */
13391 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
13392 bzero (dpyinfo
, sizeof *dpyinfo
);
13394 #ifdef MULTI_KBOARD
13396 struct x_display_info
*share
;
13399 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
13400 share
= share
->next
, tail
= XCDR (tail
))
13401 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
13402 XSTRING (display_name
)->data
))
13405 dpyinfo
->kboard
= share
->kboard
;
13408 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
13409 init_kboard (dpyinfo
->kboard
);
13410 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
13412 char *vendor
= ServerVendor (dpy
);
13414 dpyinfo
->kboard
->Vsystem_key_alist
13415 = call1 (Qvendor_specific_keysyms
,
13416 build_string (vendor
? vendor
: ""));
13420 dpyinfo
->kboard
->next_kboard
= all_kboards
;
13421 all_kboards
= dpyinfo
->kboard
;
13422 /* Don't let the initial kboard remain current longer than necessary.
13423 That would cause problems if a file loaded on startup tries to
13424 prompt in the mini-buffer. */
13425 if (current_kboard
== initial_kboard
)
13426 current_kboard
= dpyinfo
->kboard
;
13428 dpyinfo
->kboard
->reference_count
++;
13432 /* Put this display on the chain. */
13433 dpyinfo
->next
= x_display_list
;
13434 x_display_list
= dpyinfo
;
13436 /* Put it on x_display_name_list as well, to keep them parallel. */
13437 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
13438 x_display_name_list
);
13439 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13441 dpyinfo
->display
= dpy
;
13444 XSetAfterFunction (x_current_display
, x_trace_wire
);
13448 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
13449 + STRING_BYTES (XSTRING (Vsystem_name
))
13451 sprintf (dpyinfo
->x_id_name
, "%s@%s",
13452 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
13454 /* Figure out which modifier bits mean what. */
13455 x_find_modifier_meanings (dpyinfo
);
13457 /* Get the scroll bar cursor. */
13458 dpyinfo
->vertical_scroll_bar_cursor
13459 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
13461 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
13462 resource_name
, EMACS_CLASS
);
13463 #ifdef HAVE_XRMSETDATABASE
13464 XrmSetDatabase (dpyinfo
->display
, xrdb
);
13466 dpyinfo
->display
->db
= xrdb
;
13468 /* Put the rdb where we can find it in a way that works on
13470 dpyinfo
->xrdb
= xrdb
;
13472 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
13473 DefaultScreen (dpyinfo
->display
));
13474 select_visual (dpyinfo
);
13475 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
13476 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
13477 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
13478 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
13479 dpyinfo
->grabbed
= 0;
13480 dpyinfo
->reference_count
= 0;
13481 dpyinfo
->icon_bitmap_id
= -1;
13482 dpyinfo
->font_table
= NULL
;
13483 dpyinfo
->n_fonts
= 0;
13484 dpyinfo
->font_table_size
= 0;
13485 dpyinfo
->bitmaps
= 0;
13486 dpyinfo
->bitmaps_size
= 0;
13487 dpyinfo
->bitmaps_last
= 0;
13488 dpyinfo
->scratch_cursor_gc
= 0;
13489 dpyinfo
->mouse_face_mouse_frame
= 0;
13490 dpyinfo
->mouse_face_deferred_gc
= 0;
13491 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13492 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13493 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13494 dpyinfo
->mouse_face_window
= Qnil
;
13495 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
13496 dpyinfo
->mouse_face_defer
= 0;
13497 dpyinfo
->x_focus_frame
= 0;
13498 dpyinfo
->x_focus_event_frame
= 0;
13499 dpyinfo
->x_highlight_frame
= 0;
13500 dpyinfo
->image_cache
= make_image_cache ();
13502 /* See if a private colormap is requested. */
13503 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
13505 if (dpyinfo
->visual
->class == PseudoColor
)
13508 value
= display_x_get_resource (dpyinfo
,
13509 build_string ("privateColormap"),
13510 build_string ("PrivateColormap"),
13512 if (STRINGP (value
)
13513 && (!strcmp (XSTRING (value
)->data
, "true")
13514 || !strcmp (XSTRING (value
)->data
, "on")))
13515 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
13519 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
13520 dpyinfo
->visual
, AllocNone
);
13523 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
13524 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
13525 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
13526 dpyinfo
->resy
= pixels
* 25.4 / mm
;
13527 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
13528 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
13529 dpyinfo
->resx
= pixels
* 25.4 / mm
;
13532 dpyinfo
->Xatom_wm_protocols
13533 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
13534 dpyinfo
->Xatom_wm_take_focus
13535 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
13536 dpyinfo
->Xatom_wm_save_yourself
13537 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
13538 dpyinfo
->Xatom_wm_delete_window
13539 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
13540 dpyinfo
->Xatom_wm_change_state
13541 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
13542 dpyinfo
->Xatom_wm_configure_denied
13543 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
13544 dpyinfo
->Xatom_wm_window_moved
13545 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
13546 dpyinfo
->Xatom_editres
13547 = XInternAtom (dpyinfo
->display
, "Editres", False
);
13548 dpyinfo
->Xatom_CLIPBOARD
13549 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
13550 dpyinfo
->Xatom_TIMESTAMP
13551 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
13552 dpyinfo
->Xatom_TEXT
13553 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
13554 dpyinfo
->Xatom_COMPOUND_TEXT
13555 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
13556 dpyinfo
->Xatom_DELETE
13557 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
13558 dpyinfo
->Xatom_MULTIPLE
13559 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
13560 dpyinfo
->Xatom_INCR
13561 = XInternAtom (dpyinfo
->display
, "INCR", False
);
13562 dpyinfo
->Xatom_EMACS_TMP
13563 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
13564 dpyinfo
->Xatom_TARGETS
13565 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
13566 dpyinfo
->Xatom_NULL
13567 = XInternAtom (dpyinfo
->display
, "NULL", False
);
13568 dpyinfo
->Xatom_ATOM_PAIR
13569 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
13570 /* For properties of font. */
13571 dpyinfo
->Xatom_PIXEL_SIZE
13572 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
13573 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
13574 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
13575 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
13576 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
13577 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
13578 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
13580 /* Ghostscript support. */
13581 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
13582 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
13584 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
13587 dpyinfo
->cut_buffers_initialized
= 0;
13589 connection
= ConnectionNumber (dpyinfo
->display
);
13590 dpyinfo
->connection
= connection
;
13595 null_bits
[0] = 0x00;
13597 dpyinfo
->null_pixel
13598 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
13599 null_bits
, 1, 1, (long) 0, (long) 0,
13604 extern int gray_bitmap_width
, gray_bitmap_height
;
13605 extern unsigned char *gray_bitmap_bits
;
13607 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
13609 gray_bitmap_width
, gray_bitmap_height
,
13610 (unsigned long) 1, (unsigned long) 0, 1);
13614 xim_initialize (dpyinfo
, resource_name
);
13617 #ifdef subprocesses
13618 /* This is only needed for distinguishing keyboard and process input. */
13619 if (connection
!= 0)
13620 add_keyboard_wait_descriptor (connection
);
13623 #ifndef F_SETOWN_BUG
13625 #ifdef F_SETOWN_SOCK_NEG
13626 /* stdin is a socket here */
13627 fcntl (connection
, F_SETOWN
, -getpid ());
13628 #else /* ! defined (F_SETOWN_SOCK_NEG) */
13629 fcntl (connection
, F_SETOWN
, getpid ());
13630 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
13631 #endif /* ! defined (F_SETOWN) */
13632 #endif /* F_SETOWN_BUG */
13635 if (interrupt_input
)
13636 init_sigio (connection
);
13637 #endif /* ! defined (SIGIO) */
13640 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
13641 /* Make sure that we have a valid font for dialog boxes
13642 so that Xt does not crash. */
13644 Display
*dpy
= dpyinfo
->display
;
13645 XrmValue d
, fr
, to
;
13649 d
.addr
= (XPointer
)&dpy
;
13650 d
.size
= sizeof (Display
*);
13651 fr
.addr
= XtDefaultFont
;
13652 fr
.size
= sizeof (XtDefaultFont
);
13653 to
.size
= sizeof (Font
*);
13654 to
.addr
= (XPointer
)&font
;
13655 count
= x_catch_errors (dpy
);
13656 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
13658 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
13659 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
13660 x_uncatch_errors (dpy
, count
);
13665 /* See if we should run in synchronous mode. This is useful
13666 for debugging X code. */
13669 value
= display_x_get_resource (dpyinfo
,
13670 build_string ("synchronous"),
13671 build_string ("Synchronous"),
13673 if (STRINGP (value
)
13674 && (!strcmp (XSTRING (value
)->data
, "true")
13675 || !strcmp (XSTRING (value
)->data
, "on")))
13676 XSynchronize (dpyinfo
->display
, True
);
13684 /* Get rid of display DPYINFO, assuming all frames are already gone,
13685 and without sending any more commands to the X server. */
13688 x_delete_display (dpyinfo
)
13689 struct x_display_info
*dpyinfo
;
13691 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
13693 /* Discard this display from x_display_name_list and x_display_list.
13694 We can't use Fdelq because that can quit. */
13695 if (! NILP (x_display_name_list
)
13696 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
13697 x_display_name_list
= XCDR (x_display_name_list
);
13702 tail
= x_display_name_list
;
13703 while (CONSP (tail
) && CONSP (XCDR (tail
)))
13705 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
13707 XCDR (tail
) = XCDR (XCDR (tail
));
13710 tail
= XCDR (tail
);
13714 if (next_noop_dpyinfo
== dpyinfo
)
13715 next_noop_dpyinfo
= dpyinfo
->next
;
13717 if (x_display_list
== dpyinfo
)
13718 x_display_list
= dpyinfo
->next
;
13721 struct x_display_info
*tail
;
13723 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
13724 if (tail
->next
== dpyinfo
)
13725 tail
->next
= tail
->next
->next
;
13728 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
13729 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
13730 XrmDestroyDatabase (dpyinfo
->xrdb
);
13733 #ifdef MULTI_KBOARD
13734 if (--dpyinfo
->kboard
->reference_count
== 0)
13735 delete_kboard (dpyinfo
->kboard
);
13739 xim_close_dpy (dpyinfo
);
13742 xfree (dpyinfo
->font_table
);
13743 xfree (dpyinfo
->x_id_name
);
13744 xfree (dpyinfo
->color_cells
);
13749 /* Set up use of X before we make the first connection. */
13751 static struct redisplay_interface x_redisplay_interface
=
13756 x_clear_end_of_line
,
13758 x_after_update_window_line
,
13759 x_update_window_begin
,
13760 x_update_window_end
,
13763 x_clear_mouse_face
,
13764 x_get_glyph_overhangs
,
13765 x_fix_overlapping_area
13771 rif
= &x_redisplay_interface
;
13773 clear_frame_hook
= x_clear_frame
;
13774 ins_del_lines_hook
= x_ins_del_lines
;
13775 change_line_highlight_hook
= x_change_line_highlight
;
13776 delete_glyphs_hook
= x_delete_glyphs
;
13777 ring_bell_hook
= XTring_bell
;
13778 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13779 set_terminal_modes_hook
= XTset_terminal_modes
;
13780 update_begin_hook
= x_update_begin
;
13781 update_end_hook
= x_update_end
;
13782 set_terminal_window_hook
= XTset_terminal_window
;
13783 read_socket_hook
= XTread_socket
;
13784 frame_up_to_date_hook
= XTframe_up_to_date
;
13785 reassert_line_highlight_hook
= XTreassert_line_highlight
;
13786 mouse_position_hook
= XTmouse_position
;
13787 frame_rehighlight_hook
= XTframe_rehighlight
;
13788 frame_raise_lower_hook
= XTframe_raise_lower
;
13789 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13790 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13791 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13792 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13793 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13795 scroll_region_ok
= 1; /* we'll scroll partial frames */
13796 char_ins_del_ok
= 0; /* just as fast to write the line */
13797 line_ins_del_ok
= 1; /* we'll just blt 'em */
13798 fast_clear_end_of_line
= 1; /* X does this well */
13799 memory_below_frame
= 0; /* we don't remember what scrolls
13804 last_tool_bar_item
= -1;
13805 any_help_event_p
= 0;
13807 /* Try to use interrupt input; if we can't, then start polling. */
13808 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13810 #ifdef USE_X_TOOLKIT
13811 XtToolkitInitialize ();
13812 Xt_app_con
= XtCreateApplicationContext ();
13813 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13815 /* Install an asynchronous timer that processes Xt timeout events
13816 every 0.1s. This is necessary because some widget sets use
13817 timeouts internally, for example the LessTif menu bar, or the
13818 Xaw3d scroll bar. When Xt timouts aren't processed, these
13819 widgets don't behave normally. */
13821 EMACS_TIME interval
;
13822 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13823 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13827 #if USE_TOOLKIT_SCROLL_BARS
13828 xaw3d_arrow_scroll
= False
;
13829 xaw3d_pick_top
= True
;
13832 /* Note that there is no real way portable across R3/R4 to get the
13833 original error handler. */
13834 XSetErrorHandler (x_error_handler
);
13835 XSetIOErrorHandler (x_io_error_quitter
);
13837 /* Disable Window Change signals; they are handled by X events. */
13839 signal (SIGWINCH
, SIG_DFL
);
13840 #endif /* ! defined (SIGWINCH) */
13842 signal (SIGPIPE
, x_connection_signal
);
13849 staticpro (&x_error_message_string
);
13850 x_error_message_string
= Qnil
;
13852 staticpro (&x_display_name_list
);
13853 x_display_name_list
= Qnil
;
13855 staticpro (&last_mouse_scroll_bar
);
13856 last_mouse_scroll_bar
= Qnil
;
13858 staticpro (&Qvendor_specific_keysyms
);
13859 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13861 staticpro (&last_mouse_press_frame
);
13862 last_mouse_press_frame
= Qnil
;
13865 staticpro (&help_echo
);
13866 help_echo_object
= Qnil
;
13867 staticpro (&help_echo_object
);
13868 help_echo_window
= Qnil
;
13869 staticpro (&help_echo_window
);
13870 previous_help_echo
= Qnil
;
13871 staticpro (&previous_help_echo
);
13872 help_echo_pos
= -1;
13874 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13875 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
13876 For example, if a block cursor is over a tab, it will be drawn as\n\
13877 wide as that tab on the display.");
13878 x_stretch_cursor_p
= 0;
13880 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
13881 "If not nil, Emacs uses toolkit scroll bars.");
13882 #if USE_TOOLKIT_SCROLL_BARS
13883 x_toolkit_scroll_bars_p
= 1;
13885 x_toolkit_scroll_bars_p
= 0;
13888 staticpro (&last_mouse_motion_frame
);
13889 last_mouse_motion_frame
= Qnil
;
13892 #endif /* not HAVE_X_WINDOWS */