1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
23 /* Xt features made by Fred Pierresteguy. */
27 /* On 4.3 these lose if they come after xterm.h. */
28 /* Putting these at the beginning seems to be standard for other .c files. */
36 #include "blockinput.h"
38 /* Need syssignal.h for various externs and definitions that may be required
39 by some configurations for calls to signal later in this source file. */
40 #include "syssignal.h"
42 /* This may include sys/types.h, and that somehow loses
43 if this is not done before the other system files. */
45 #include <X11/cursorfont.h>
47 /* Load sys/types.h if not already loaded.
48 In some systems loading it twice is suicidal. */
50 #include <sys/types.h>
54 #include <sys/ioctl.h>
55 #endif /* ! defined (BSD_SYSTEM) */
60 #ifndef INCLUDED_FCNTL
67 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
68 /* #include <sys/param.h> */
74 #include "dispextern.h"
76 #include "termhooks.h"
84 #include "intervals.h"
90 #include <X11/Shell.h>
93 #ifdef HAVE_SYS_TIME_H
101 extern int xlwmenu_window_p
P_ ((Widget w
, Window window
));
102 extern void xlwmenu_redisplay
P_ ((Widget
));
107 extern void free_frame_menubar
P_ ((struct frame
*));
108 extern struct frame
*x_menubar_window_to_frame
P_ ((struct x_display_info
*,
111 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
113 extern void _XEditResCheckMessages ();
114 #endif /* not NO_EDITRES */
116 /* Include toolkit specific headers for the scroll bar widget. */
118 #ifdef USE_TOOLKIT_SCROLL_BARS
119 #if defined USE_MOTIF
120 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
121 #include <Xm/ScrollBar.h>
122 #else /* !USE_MOTIF i.e. use Xaw */
125 #include <X11/Xaw3d/Simple.h>
126 #include <X11/Xaw3d/Scrollbar.h>
127 #define ARROW_SCROLLBAR
128 #include <X11/Xaw3d/ScrollbarP.h>
129 #else /* !HAVE_XAW3D */
130 #include <X11/Xaw/Simple.h>
131 #include <X11/Xaw/Scrollbar.h>
132 #endif /* !HAVE_XAW3D */
134 #define XtNpickTop "pickTop"
135 #endif /* !XtNpickTop */
136 #endif /* !USE_MOTIF */
137 #endif /* USE_TOOLKIT_SCROLL_BARS */
139 #endif /* USE_X_TOOLKIT */
141 #ifndef USE_X_TOOLKIT
142 #define x_any_window_to_frame x_window_to_frame
143 #define x_top_window_to_frame x_window_to_frame
148 #ifndef XtNinitialState
149 #define XtNinitialState "initialState"
153 #define abs(x) ((x) < 0 ? -(x) : (x))
155 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
158 /* Fringe bitmaps. */
160 enum fringe_bitmap_type
163 LEFT_TRUNCATION_BITMAP
,
164 RIGHT_TRUNCATION_BITMAP
,
165 OVERLAY_ARROW_BITMAP
,
166 CONTINUED_LINE_BITMAP
,
167 CONTINUATION_LINE_BITMAP
,
171 /* Bitmap drawn to indicate lines not displaying text if
172 `indicate-empty-lines' is non-nil. */
177 static unsigned char zv_bits
[] = {
178 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
179 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
180 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
181 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
182 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
183 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
184 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
185 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
187 /* An arrow like this: `<-'. */
190 #define left_height 8
191 static unsigned char left_bits
[] = {
192 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
194 /* Right truncation arrow bitmap `->'. */
196 #define right_width 8
197 #define right_height 8
198 static unsigned char right_bits
[] = {
199 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
201 /* Marker for continued lines. */
203 #define continued_width 8
204 #define continued_height 8
205 static unsigned char continued_bits
[] = {
206 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
208 /* Marker for continuation lines. */
210 #define continuation_width 8
211 #define continuation_height 8
212 static unsigned char continuation_bits
[] = {
213 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
215 /* Overlay arrow bitmap. */
221 static unsigned char ov_bits
[] = {
222 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
224 /* A triangular arrow. */
227 static unsigned char ov_bits
[] = {
228 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
232 extern Lisp_Object Qhelp_echo
;
235 /* Non-nil means Emacs uses toolkit scroll bars. */
237 Lisp_Object Vx_toolkit_scroll_bars
;
239 /* If a string, XTread_socket generates an event to display that string.
240 (The display is done in read_char.) */
242 static Lisp_Object help_echo
;
243 static Lisp_Object help_echo_window
;
244 static Lisp_Object help_echo_object
;
245 static int help_echo_pos
;
247 /* Temporary variable for XTread_socket. */
249 static Lisp_Object previous_help_echo
;
251 /* Non-zero means that a HELP_EVENT has been generated since Emacs
254 static int any_help_event_p
;
256 /* Non-zero means autoselect window with the mouse cursor. */
258 int mouse_autoselect_window
;
260 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
261 static Lisp_Object last_window
;
263 /* Non-zero means draw block and hollow cursor as wide as the glyph
264 under it. For example, if a block cursor is over a tab, it will be
265 drawn as wide as that tab on the display. */
267 int x_stretch_cursor_p
;
269 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
271 int x_use_underline_position_properties
;
273 /* This is a chain of structures for all the X displays currently in
276 struct x_display_info
*x_display_list
;
278 /* This is a list of cons cells, each of the form (NAME
279 . FONT-LIST-CACHE), one for each element of x_display_list and in
280 the same order. NAME is the name of the frame. FONT-LIST-CACHE
281 records previous values returned by x-list-fonts. */
283 Lisp_Object x_display_name_list
;
285 /* Frame being updated by update_frame. This is declared in term.c.
286 This is set by update_begin and looked at by all the XT functions.
287 It is zero while not inside an update. In that case, the XT
288 functions assume that `selected_frame' is the frame to apply to. */
290 extern struct frame
*updating_frame
;
292 /* This is a frame waiting to be auto-raised, within XTread_socket. */
294 struct frame
*pending_autoraise_frame
;
297 /* The application context for Xt use. */
298 XtAppContext Xt_app_con
;
299 static String Xt_default_resources
[] = {0};
300 #endif /* USE_X_TOOLKIT */
302 /* Nominal cursor position -- where to draw output.
303 HPOS and VPOS are window relative glyph matrix coordinates.
304 X and Y are window relative pixel coordinates. */
306 struct cursor_pos output_cursor
;
308 /* Non-zero means user is interacting with a toolkit scroll bar. */
310 static int toolkit_scroll_bar_interaction
;
314 Formerly, we used PointerMotionHintMask (in standard_event_mask)
315 so that we would have to call XQueryPointer after each MotionNotify
316 event to ask for another such event. However, this made mouse tracking
317 slow, and there was a bug that made it eventually stop.
319 Simply asking for MotionNotify all the time seems to work better.
321 In order to avoid asking for motion events and then throwing most
322 of them away or busy-polling the server for mouse positions, we ask
323 the server for pointer motion hints. This means that we get only
324 one event per group of mouse movements. "Groups" are delimited by
325 other kinds of events (focus changes and button clicks, for
326 example), or by XQueryPointer calls; when one of these happens, we
327 get another MotionNotify event the next time the mouse moves. This
328 is at least as efficient as getting motion events when mouse
329 tracking is on, and I suspect only negligibly worse when tracking
332 /* Where the mouse was last time we reported a mouse event. */
334 FRAME_PTR last_mouse_frame
;
335 static XRectangle last_mouse_glyph
;
336 static Lisp_Object last_mouse_press_frame
;
338 /* The scroll bar in which the last X motion event occurred.
340 If the last X motion event occurred in a scroll bar, we set this so
341 XTmouse_position can know whether to report a scroll bar motion or
344 If the last X motion event didn't occur in a scroll bar, we set
345 this to Qnil, to tell XTmouse_position to return an ordinary motion
348 static Lisp_Object last_mouse_scroll_bar
;
350 /* This is a hack. We would really prefer that XTmouse_position would
351 return the time associated with the position it returns, but there
352 doesn't seem to be any way to wrest the time-stamp from the server
353 along with the position query. So, we just keep track of the time
354 of the last movement we received, and return that in hopes that
355 it's somewhat accurate. */
357 static Time last_mouse_movement_time
;
359 /* Incremented by XTread_socket whenever it really tries to read
363 static int volatile input_signal_count
;
365 static int input_signal_count
;
368 /* Used locally within XTread_socket. */
370 static int x_noop_count
;
372 /* Initial values of argv and argc. */
374 extern char **initial_argv
;
375 extern int initial_argc
;
377 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
379 /* Tells if a window manager is present or not. */
381 extern Lisp_Object Vx_no_window_manager
;
383 extern Lisp_Object Qface
, Qmouse_face
, Qeql
;
387 /* A mask of extra modifier bits to put into every keyboard char. */
389 extern EMACS_INT extra_keyboard_modifiers
;
391 /* The keysyms to use for the various modifiers. */
393 Lisp_Object Vx_alt_keysym
, Vx_hyper_keysym
, Vx_meta_keysym
, Vx_super_keysym
;
394 Lisp_Object Vx_keysym_table
;
395 static Lisp_Object Qalt
, Qhyper
, Qmeta
, Qsuper
, Qmodifier_value
;
397 static Lisp_Object Qvendor_specific_keysyms
;
398 static Lisp_Object Qlatin_1
, Qutf_8
;
400 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
401 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
404 /* Enumeration for overriding/changing the face to use for drawing
405 glyphs in x_draw_glyphs. */
407 enum draw_glyphs_face
417 static int cursor_in_mouse_face_p
P_ ((struct window
*));
418 static int clear_mouse_face
P_ ((struct x_display_info
*));
419 static int x_alloc_nearest_color_1
P_ ((Display
*, Colormap
, XColor
*));
420 static void x_set_window_size_1
P_ ((struct frame
*, int, int, int));
421 static const XColor
*x_color_cells
P_ ((Display
*, int *));
422 static void x_update_window_end
P_ ((struct window
*, int, int));
423 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
424 void x_delete_display
P_ ((struct x_display_info
*));
425 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
427 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
428 int *, int *, Lisp_Object
));
429 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
430 int *, int *, int *, int *, int));
431 static void set_output_cursor
P_ ((struct cursor_pos
*));
432 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
433 int *, int *, int *, int));
434 static void note_mode_line_or_margin_highlight
P_ ((struct window
*, int,
436 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
437 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
438 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
439 static void show_mouse_face
P_ ((struct x_display_info
*,
440 enum draw_glyphs_face
));
441 static int x_io_error_quitter
P_ ((Display
*));
442 int x_catch_errors
P_ ((Display
*));
443 void x_uncatch_errors
P_ ((Display
*, int));
444 void x_lower_frame
P_ ((struct frame
*));
445 void x_scroll_bar_clear
P_ ((struct frame
*));
446 int x_had_errors_p
P_ ((Display
*));
447 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
448 void x_raise_frame
P_ ((struct frame
*));
449 void x_set_window_size
P_ ((struct frame
*, int, int, int));
450 void x_wm_set_window_state
P_ ((struct frame
*, int));
451 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
452 void x_initialize
P_ ((void));
453 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
454 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
455 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
457 enum draw_glyphs_face
));
458 static void x_update_end
P_ ((struct frame
*));
459 static void XTframe_up_to_date
P_ ((struct frame
*));
460 static void XTset_terminal_modes
P_ ((void));
461 static void XTreset_terminal_modes
P_ ((void));
462 static void XTcursor_to
P_ ((int, int, int, int));
463 static void x_write_glyphs
P_ ((struct glyph
*, int));
464 static void x_clear_end_of_line
P_ ((int));
465 static void x_clear_frame
P_ ((void));
466 static void x_clear_cursor
P_ ((struct window
*));
467 static void frame_highlight
P_ ((struct frame
*));
468 static void frame_unhighlight
P_ ((struct frame
*));
469 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
470 static int x_focus_changed
P_ ((int,
472 struct x_display_info
*,
474 struct input_event
*,
476 static int x_detect_focus_change
P_ ((struct x_display_info
*,
478 struct input_event
*,
480 static void XTframe_rehighlight
P_ ((struct frame
*));
481 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
482 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
483 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
484 enum text_cursor_kinds
));
485 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
487 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
488 static int expose_window_tree
P_ ((struct window
*, XRectangle
*));
489 static void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
490 struct glyph_row
*));
491 static int expose_window
P_ ((struct window
*, XRectangle
*));
492 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
493 XRectangle
*, enum glyph_row_area
));
494 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
496 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
497 static void x_update_window_cursor
P_ ((struct window
*, int));
498 static void x_erase_phys_cursor
P_ ((struct window
*));
499 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
500 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
501 enum fringe_bitmap_type
, int left_p
));
503 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
505 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
506 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
507 static void notice_overwritten_cursor
P_ ((struct window
*, enum glyph_row_area
,
508 int, int, int, int));
509 static void x_flush
P_ ((struct frame
*f
));
510 static void x_update_begin
P_ ((struct frame
*));
511 static void x_update_window_begin
P_ ((struct window
*));
512 static void x_draw_vertical_border
P_ ((struct window
*));
513 static void x_after_update_window_line
P_ ((struct glyph_row
*));
514 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
515 static void x_produce_stretch_glyph
P_ ((struct it
*));
516 static struct scroll_bar
*x_window_to_scroll_bar
P_ ((Window
));
517 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
518 enum scroll_bar_part
*,
519 Lisp_Object
*, Lisp_Object
*,
521 static void x_check_fullscreen
P_ ((struct frame
*));
522 static void x_check_fullscreen_move
P_ ((struct frame
*));
524 /* Flush display of frame F, or of all frames if F is null. */
533 Lisp_Object rest
, frame
;
534 FOR_EACH_FRAME (rest
, frame
)
535 x_flush (XFRAME (frame
));
537 else if (FRAME_X_P (f
))
538 XFlush (FRAME_X_DISPLAY (f
));
543 /* Remove calls to XFlush by defining XFlush to an empty replacement.
544 Calls to XFlush should be unnecessary because the X output buffer
545 is flushed automatically as needed by calls to XPending,
546 XNextEvent, or XWindowEvent according to the XFlush man page.
547 XTread_socket calls XPending. Removing XFlush improves
550 #define XFlush(DISPLAY) (void) 0
553 /***********************************************************************
555 ***********************************************************************/
559 /* This is a function useful for recording debugging information about
560 the sequence of occurrences in this file. */
568 struct record event_record
[100];
570 int event_record_index
;
572 record_event (locus
, type
)
576 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
577 event_record_index
= 0;
579 event_record
[event_record_index
].locus
= locus
;
580 event_record
[event_record_index
].type
= type
;
581 event_record_index
++;
588 /* Return the struct x_display_info corresponding to DPY. */
590 struct x_display_info
*
591 x_display_info_for_display (dpy
)
594 struct x_display_info
*dpyinfo
;
596 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
597 if (dpyinfo
->display
== dpy
)
605 /***********************************************************************
606 Starting and ending an update
607 ***********************************************************************/
609 /* Start an update of frame F. This function is installed as a hook
610 for update_begin, i.e. it is called when update_begin is called.
611 This function is called prior to calls to x_update_window_begin for
612 each window being updated. Currently, there is nothing to do here
613 because all interesting stuff is done on a window basis. */
623 /* Start update of window W. Set the global variable updated_window
624 to the window being updated and set output_cursor to the cursor
628 x_update_window_begin (w
)
631 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
632 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
635 set_output_cursor (&w
->cursor
);
639 if (f
== display_info
->mouse_face_mouse_frame
)
641 /* Don't do highlighting for mouse motion during the update. */
642 display_info
->mouse_face_defer
= 1;
644 /* If F needs to be redrawn, simply forget about any prior mouse
646 if (FRAME_GARBAGED_P (f
))
647 display_info
->mouse_face_window
= Qnil
;
649 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
650 their mouse_face_p flag set, which means that they are always
651 unequal to rows in a desired matrix which never have that
652 flag set. So, rows containing mouse-face glyphs are never
653 scrolled, and we don't have to switch the mouse highlight off
654 here to prevent it from being scrolled. */
656 /* Can we tell that this update does not affect the window
657 where the mouse highlight is? If so, no need to turn off.
658 Likewise, don't do anything if the frame is garbaged;
659 in that case, the frame's current matrix that we would use
660 is all wrong, and we will redisplay that line anyway. */
661 if (!NILP (display_info
->mouse_face_window
)
662 && w
== XWINDOW (display_info
->mouse_face_window
))
666 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
667 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
670 if (i
< w
->desired_matrix
->nrows
)
671 clear_mouse_face (display_info
);
680 /* Draw a vertical window border to the right of window W if W doesn't
681 have vertical scroll bars. */
684 x_draw_vertical_border (w
)
687 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
689 /* Redraw borders between horizontally adjacent windows. Don't
690 do it for frames with vertical scroll bars because either the
691 right scroll bar of a window, or the left scroll bar of its
692 neighbor will suffice as a border. */
693 if (!WINDOW_RIGHTMOST_P (w
)
694 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
698 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
699 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
702 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
703 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
708 /* End update of window W (which is equal to updated_window).
710 Draw vertical borders between horizontally adjacent windows, and
711 display W's cursor if CURSOR_ON_P is non-zero.
713 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
714 glyphs in mouse-face were overwritten. In that case we have to
715 make sure that the mouse-highlight is properly redrawn.
717 W may be a menu bar pseudo-window in case we don't have X toolkit
718 support. Such windows don't have a cursor, so don't display it
722 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
724 int cursor_on_p
, mouse_face_overwritten_p
;
726 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
728 if (!w
->pseudo_window_p
)
733 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
735 output_cursor
.x
, output_cursor
.y
);
737 x_draw_vertical_border (w
);
741 /* If a row with mouse-face was overwritten, arrange for
742 XTframe_up_to_date to redisplay the mouse highlight. */
743 if (mouse_face_overwritten_p
)
745 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
746 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
747 dpyinfo
->mouse_face_window
= Qnil
;
750 updated_window
= NULL
;
754 /* End update of frame F. This function is installed as a hook in
761 /* Mouse highlight may be displayed again. */
762 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
765 XFlush (FRAME_X_DISPLAY (f
));
770 /* This function is called from various places in xdisp.c whenever a
771 complete update has been performed. The global variable
772 updated_window is not available here. */
775 XTframe_up_to_date (f
)
780 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
782 if (dpyinfo
->mouse_face_deferred_gc
783 || f
== dpyinfo
->mouse_face_mouse_frame
)
786 if (dpyinfo
->mouse_face_mouse_frame
)
787 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
788 dpyinfo
->mouse_face_mouse_x
,
789 dpyinfo
->mouse_face_mouse_y
);
790 dpyinfo
->mouse_face_deferred_gc
= 0;
797 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
798 arrow bitmaps, or clear the fringes if no bitmaps are required
799 before DESIRED_ROW is made current. The window being updated is
800 found in updated_window. This function It is called from
801 update_window_line only if it is known that there are differences
802 between bitmaps to be drawn between current row and DESIRED_ROW. */
805 x_after_update_window_line (desired_row
)
806 struct glyph_row
*desired_row
;
808 struct window
*w
= updated_window
;
814 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
817 x_draw_row_fringe_bitmaps (w
, desired_row
);
821 /* When a window has disappeared, make sure that no rest of
822 full-width rows stays visible in the internal border. Could
823 check here if updated_window is the leftmost/rightmost window,
824 but I guess it's not worth doing since vertically split windows
825 are almost never used, internal border is rarely set, and the
826 overhead is very small. */
827 if (windows_or_buffers_changed
828 && desired_row
->full_width_p
829 && (f
= XFRAME (w
->frame
),
830 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
832 && (height
= desired_row
->visible_height
,
835 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
837 /* Internal border is drawn below the tool bar. */
838 if (WINDOWP (f
->tool_bar_window
)
839 && w
== XWINDOW (f
->tool_bar_window
))
843 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
844 0, y
, width
, height
, False
);
845 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
846 f
->output_data
.x
->pixel_width
- width
,
847 y
, width
, height
, False
);
853 /* Draw the bitmap WHICH in one of the left or right fringes of
854 window W. ROW is the glyph row for which to display the bitmap; it
855 determines the vertical position at which the bitmap has to be
859 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
861 struct glyph_row
*row
;
862 enum fringe_bitmap_type which
;
865 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
866 Display
*display
= FRAME_X_DISPLAY (f
);
867 Window window
= FRAME_X_WINDOW (f
);
870 unsigned char *bits
= NULL
;
872 GC gc
= f
->output_data
.x
->normal_gc
;
874 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
876 /* Must clip because of partially visible lines. */
877 x_clip_to_row (w
, row
, gc
, 1);
879 /* Convert row to frame coordinates. */
880 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
884 case NO_FRINGE_BITMAP
:
889 case LEFT_TRUNCATION_BITMAP
:
895 case OVERLAY_ARROW_BITMAP
:
901 case RIGHT_TRUNCATION_BITMAP
:
907 case CONTINUED_LINE_BITMAP
:
908 wd
= continued_width
;
909 h
= continued_height
;
910 bits
= continued_bits
;
913 case CONTINUATION_LINE_BITMAP
:
914 wd
= continuation_width
;
915 h
= continuation_height
;
916 bits
= continuation_bits
;
921 h
= zv_height
- (y
% zv_period
);
922 bits
= zv_bits
+ (y
% zv_period
);
929 /* Clip bitmap if too high. */
933 /* Set dy to the offset in the row to start drawing the bitmap. */
934 dy
= (row
->height
- h
) / 2;
936 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
937 PREPARE_FACE_FOR_DISPLAY (f
, face
);
939 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
944 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
945 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
946 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
948 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
949 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
951 /* If W has a vertical border to its left, don't draw over it. */
952 int border
= ((XFASTINT (w
->left
) > 0
953 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
955 b1
= (window_box_left (w
, -1)
956 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
958 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
963 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
964 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
965 x
= (window_box_right (w
, -1)
966 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
967 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
969 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
971 b1
= window_box_right (w
, -1);
972 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
978 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
980 /* In case the same realized face is used for fringes and
981 for something displayed in the text (e.g. face `region' on
982 mono-displays, the fill style may have been changed to
983 FillSolid in x_draw_glyph_string_background. */
985 XSetFillStyle (display
, face
->gc
, FillOpaqueStippled
);
987 XSetForeground (display
, face
->gc
, face
->background
);
989 XFillRectangle (display
, window
, face
->gc
,
991 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
994 row
->visible_height
);
996 XSetForeground (display
, face
->gc
, face
->foreground
);
999 if (which
!= NO_FRINGE_BITMAP
)
1001 /* Draw the bitmap. I believe these small pixmaps can be cached
1003 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
1005 face
->background
, depth
);
1006 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
1007 XFreePixmap (display
, pixmap
);
1010 XSetClipMask (display
, gc
, None
);
1014 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1015 function with input blocked. */
1018 x_draw_row_fringe_bitmaps (w
, row
)
1020 struct glyph_row
*row
;
1022 struct frame
*f
= XFRAME (w
->frame
);
1023 enum fringe_bitmap_type bitmap
;
1025 xassert (interrupt_input_blocked
);
1027 /* If row is completely invisible, because of vscrolling, we
1028 don't have to draw anything. */
1029 if (row
->visible_height
<= 0)
1032 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1034 /* Decide which bitmap to draw in the left fringe. */
1035 if (row
->overlay_arrow_p
)
1036 bitmap
= OVERLAY_ARROW_BITMAP
;
1037 else if (row
->truncated_on_left_p
)
1038 bitmap
= LEFT_TRUNCATION_BITMAP
;
1039 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1040 bitmap
= CONTINUATION_LINE_BITMAP
;
1041 else if (row
->indicate_empty_line_p
)
1042 bitmap
= ZV_LINE_BITMAP
;
1044 bitmap
= NO_FRINGE_BITMAP
;
1046 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1049 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1051 /* Decide which bitmap to draw in the right fringe. */
1052 if (row
->truncated_on_right_p
)
1053 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1054 else if (row
->continued_p
)
1055 bitmap
= CONTINUED_LINE_BITMAP
;
1056 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1057 bitmap
= ZV_LINE_BITMAP
;
1059 bitmap
= NO_FRINGE_BITMAP
;
1061 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1067 /* This is called when starting Emacs and when restarting after
1068 suspend. When starting Emacs, no X window is mapped. And nothing
1069 must be done to Emacs's own window if it is suspended (though that
1073 XTset_terminal_modes ()
1077 /* This is called when exiting or suspending Emacs. Exiting will make
1078 the X-windows go away, and suspending requires no action. */
1081 XTreset_terminal_modes ()
1087 /***********************************************************************
1089 ***********************************************************************/
1091 /* Set the global variable output_cursor to CURSOR. All cursor
1092 positions are relative to updated_window. */
1095 set_output_cursor (cursor
)
1096 struct cursor_pos
*cursor
;
1098 output_cursor
.hpos
= cursor
->hpos
;
1099 output_cursor
.vpos
= cursor
->vpos
;
1100 output_cursor
.x
= cursor
->x
;
1101 output_cursor
.y
= cursor
->y
;
1105 /* Set a nominal cursor position.
1107 HPOS and VPOS are column/row positions in a window glyph matrix. X
1108 and Y are window text area relative pixel positions.
1110 If this is done during an update, updated_window will contain the
1111 window that is being updated and the position is the future output
1112 cursor position for that window. If updated_window is null, use
1113 selected_window and display the cursor at the given position. */
1116 XTcursor_to (vpos
, hpos
, y
, x
)
1117 int vpos
, hpos
, y
, x
;
1121 /* If updated_window is not set, work on selected_window. */
1125 w
= XWINDOW (selected_window
);
1127 /* Set the output cursor. */
1128 output_cursor
.hpos
= hpos
;
1129 output_cursor
.vpos
= vpos
;
1130 output_cursor
.x
= x
;
1131 output_cursor
.y
= y
;
1133 /* If not called as part of an update, really display the cursor.
1134 This will also set the cursor position of W. */
1135 if (updated_window
== NULL
)
1138 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1139 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1146 /***********************************************************************
1148 ***********************************************************************/
1150 /* Function prototypes of this page. */
1152 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1156 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1157 int, XChar2b
*, int,
1159 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1160 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1161 static void x_append_glyph
P_ ((struct it
*));
1162 static void x_append_composite_glyph
P_ ((struct it
*));
1163 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1165 static void x_produce_glyphs
P_ ((struct it
*));
1166 static void x_produce_image_glyph
P_ ((struct it
*it
));
1169 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1170 is not contained in the font. */
1172 static INLINE XCharStruct
*
1173 x_per_char_metric (font
, char2b
)
1177 /* The result metric information. */
1178 XCharStruct
*pcm
= NULL
;
1180 xassert (font
&& char2b
);
1182 if (font
->per_char
!= NULL
)
1184 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1186 /* min_char_or_byte2 specifies the linear character index
1187 corresponding to the first element of the per_char array,
1188 max_char_or_byte2 is the index of the last character. A
1189 character with non-zero CHAR2B->byte1 is not in the font.
1190 A character with byte2 less than min_char_or_byte2 or
1191 greater max_char_or_byte2 is not in the font. */
1192 if (char2b
->byte1
== 0
1193 && char2b
->byte2
>= font
->min_char_or_byte2
1194 && char2b
->byte2
<= font
->max_char_or_byte2
)
1195 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1199 /* If either min_byte1 or max_byte1 are nonzero, both
1200 min_char_or_byte2 and max_char_or_byte2 are less than
1201 256, and the 2-byte character index values corresponding
1202 to the per_char array element N (counting from 0) are:
1204 byte1 = N/D + min_byte1
1205 byte2 = N\D + min_char_or_byte2
1209 D = max_char_or_byte2 - min_char_or_byte2 + 1
1210 / = integer division
1211 \ = integer modulus */
1212 if (char2b
->byte1
>= font
->min_byte1
1213 && char2b
->byte1
<= font
->max_byte1
1214 && char2b
->byte2
>= font
->min_char_or_byte2
1215 && char2b
->byte2
<= font
->max_char_or_byte2
)
1217 pcm
= (font
->per_char
1218 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1219 * (char2b
->byte1
- font
->min_byte1
))
1220 + (char2b
->byte2
- font
->min_char_or_byte2
));
1226 /* If the per_char pointer is null, all glyphs between the first
1227 and last character indexes inclusive have the same
1228 information, as given by both min_bounds and max_bounds. */
1229 if (char2b
->byte2
>= font
->min_char_or_byte2
1230 && char2b
->byte2
<= font
->max_char_or_byte2
)
1231 pcm
= &font
->max_bounds
;
1234 return ((pcm
== NULL
1235 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1240 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1241 the two-byte form of C. Encoding is returned in *CHAR2B. */
1244 x_encode_char (c
, char2b
, font_info
)
1247 struct font_info
*font_info
;
1249 int charset
= CHAR_CHARSET (c
);
1250 XFontStruct
*font
= font_info
->font
;
1252 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1253 This may be either a program in a special encoder language or a
1255 if (font_info
->font_encoder
)
1257 /* It's a program. */
1258 struct ccl_program
*ccl
= font_info
->font_encoder
;
1260 if (CHARSET_DIMENSION (charset
) == 1)
1262 ccl
->reg
[0] = charset
;
1263 ccl
->reg
[1] = char2b
->byte2
;
1268 ccl
->reg
[0] = charset
;
1269 ccl
->reg
[1] = char2b
->byte1
;
1270 ccl
->reg
[2] = char2b
->byte2
;
1273 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1275 /* We assume that MSBs are appropriately set/reset by CCL
1277 if (font
->max_byte1
== 0) /* 1-byte font */
1278 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1280 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1282 else if (font_info
->encoding
[charset
])
1284 /* Fixed encoding scheme. See fontset.h for the meaning of the
1285 encoding numbers. */
1286 int enc
= font_info
->encoding
[charset
];
1288 if ((enc
== 1 || enc
== 2)
1289 && CHARSET_DIMENSION (charset
) == 2)
1290 char2b
->byte1
|= 0x80;
1292 if (enc
== 1 || enc
== 3)
1293 char2b
->byte2
|= 0x80;
1298 /* Get face and two-byte form of character C in face FACE_ID on frame
1299 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1300 means we want to display multibyte text. DISPLAY_P non-zero means
1301 make sure that X resources for the face returned are allocated.
1302 Value is a pointer to a realized face that is ready for display if
1303 DISPLAY_P is non-zero. */
1305 static INLINE
struct face
*
1306 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
1310 int multibyte_p
, display_p
;
1312 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1316 /* Unibyte case. We don't have to encode, but we have to make
1317 sure to use a face suitable for unibyte. */
1320 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1321 face
= FACE_FROM_ID (f
, face_id
);
1323 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1325 /* Case of ASCII in a face known to fit ASCII. */
1331 int c1
, c2
, charset
;
1333 /* Split characters into bytes. If c2 is -1 afterwards, C is
1334 really a one-byte character so that byte1 is zero. */
1335 SPLIT_CHAR (c
, charset
, c1
, c2
);
1337 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1339 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1341 /* Maybe encode the character in *CHAR2B. */
1342 if (face
->font
!= NULL
)
1344 struct font_info
*font_info
1345 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1347 x_encode_char (c
, char2b
, font_info
);
1351 /* Make sure X resources of the face are allocated. */
1354 xassert (face
!= NULL
);
1355 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1362 /* Get face and two-byte form of character glyph GLYPH on frame F.
1363 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1364 a pointer to a realized face that is ready for display. */
1366 static INLINE
struct face
*
1367 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1369 struct glyph
*glyph
;
1375 xassert (glyph
->type
== CHAR_GLYPH
);
1376 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1381 if (!glyph
->multibyte_p
)
1383 /* Unibyte case. We don't have to encode, but we have to make
1384 sure to use a face suitable for unibyte. */
1386 char2b
->byte2
= glyph
->u
.ch
;
1388 else if (glyph
->u
.ch
< 128
1389 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1391 /* Case of ASCII in a face known to fit ASCII. */
1393 char2b
->byte2
= glyph
->u
.ch
;
1397 int c1
, c2
, charset
;
1399 /* Split characters into bytes. If c2 is -1 afterwards, C is
1400 really a one-byte character so that byte1 is zero. */
1401 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1403 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1405 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1407 /* Maybe encode the character in *CHAR2B. */
1408 if (charset
!= CHARSET_ASCII
)
1410 struct font_info
*font_info
1411 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1414 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1417 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1422 /* Make sure X resources of the face are allocated. */
1423 xassert (face
!= NULL
);
1424 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1429 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1430 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1436 struct glyph
*glyph
;
1437 enum glyph_row_area area
= it
->area
;
1439 xassert (it
->glyph_row
);
1440 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1442 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1443 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1445 glyph
->charpos
= CHARPOS (it
->position
);
1446 glyph
->object
= it
->object
;
1447 glyph
->pixel_width
= it
->pixel_width
;
1448 glyph
->voffset
= it
->voffset
;
1449 glyph
->type
= CHAR_GLYPH
;
1450 glyph
->multibyte_p
= it
->multibyte_p
;
1451 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1452 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1453 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1454 || it
->phys_descent
> it
->descent
);
1455 glyph
->padding_p
= 0;
1456 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1457 glyph
->face_id
= it
->face_id
;
1458 glyph
->u
.ch
= it
->char_to_display
;
1459 ++it
->glyph_row
->used
[area
];
1463 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1464 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1467 x_append_composite_glyph (it
)
1470 struct glyph
*glyph
;
1471 enum glyph_row_area area
= it
->area
;
1473 xassert (it
->glyph_row
);
1475 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1476 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1478 glyph
->charpos
= CHARPOS (it
->position
);
1479 glyph
->object
= it
->object
;
1480 glyph
->pixel_width
= it
->pixel_width
;
1481 glyph
->voffset
= it
->voffset
;
1482 glyph
->type
= COMPOSITE_GLYPH
;
1483 glyph
->multibyte_p
= it
->multibyte_p
;
1484 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1485 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1486 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1487 || it
->phys_descent
> it
->descent
);
1488 glyph
->padding_p
= 0;
1489 glyph
->glyph_not_available_p
= 0;
1490 glyph
->face_id
= it
->face_id
;
1491 glyph
->u
.cmp_id
= it
->cmp_id
;
1492 ++it
->glyph_row
->used
[area
];
1497 /* Change IT->ascent and IT->height according to the setting of
1501 take_vertical_position_into_account (it
)
1506 if (it
->voffset
< 0)
1507 /* Increase the ascent so that we can display the text higher
1509 it
->ascent
+= abs (it
->voffset
);
1511 /* Increase the descent so that we can display the text lower
1513 it
->descent
+= it
->voffset
;
1518 /* Produce glyphs/get display metrics for the image IT is loaded with.
1519 See the description of struct display_iterator in dispextern.h for
1520 an overview of struct display_iterator. */
1523 x_produce_image_glyph (it
)
1529 xassert (it
->what
== IT_IMAGE
);
1531 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1532 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1535 /* Make sure X resources of the face and image are loaded. */
1536 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1537 prepare_image_for_display (it
->f
, img
);
1539 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1540 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1541 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1545 if (face
->box
!= FACE_NO_BOX
)
1547 if (face
->box_line_width
> 0)
1549 it
->ascent
+= face
->box_line_width
;
1550 it
->descent
+= face
->box_line_width
;
1553 if (it
->start_of_box_run_p
)
1554 it
->pixel_width
+= abs (face
->box_line_width
);
1555 if (it
->end_of_box_run_p
)
1556 it
->pixel_width
+= abs (face
->box_line_width
);
1559 take_vertical_position_into_account (it
);
1563 struct glyph
*glyph
;
1564 enum glyph_row_area area
= it
->area
;
1566 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1567 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1569 glyph
->charpos
= CHARPOS (it
->position
);
1570 glyph
->object
= it
->object
;
1571 glyph
->pixel_width
= it
->pixel_width
;
1572 glyph
->voffset
= it
->voffset
;
1573 glyph
->type
= IMAGE_GLYPH
;
1574 glyph
->multibyte_p
= it
->multibyte_p
;
1575 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1576 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1577 glyph
->overlaps_vertically_p
= 0;
1578 glyph
->padding_p
= 0;
1579 glyph
->glyph_not_available_p
= 0;
1580 glyph
->face_id
= it
->face_id
;
1581 glyph
->u
.img_id
= img
->id
;
1582 ++it
->glyph_row
->used
[area
];
1588 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1589 of the glyph, WIDTH and HEIGHT are the width and height of the
1590 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1591 ascent of the glyph (0 <= ASCENT <= 1). */
1594 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1600 struct glyph
*glyph
;
1601 enum glyph_row_area area
= it
->area
;
1603 xassert (ascent
>= 0 && ascent
<= 1);
1605 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1606 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1608 glyph
->charpos
= CHARPOS (it
->position
);
1609 glyph
->object
= object
;
1610 glyph
->pixel_width
= width
;
1611 glyph
->voffset
= it
->voffset
;
1612 glyph
->type
= STRETCH_GLYPH
;
1613 glyph
->multibyte_p
= it
->multibyte_p
;
1614 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1615 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1616 glyph
->overlaps_vertically_p
= 0;
1617 glyph
->padding_p
= 0;
1618 glyph
->glyph_not_available_p
= 0;
1619 glyph
->face_id
= it
->face_id
;
1620 glyph
->u
.stretch
.ascent
= height
* ascent
;
1621 glyph
->u
.stretch
.height
= height
;
1622 ++it
->glyph_row
->used
[area
];
1627 /* Produce a stretch glyph for iterator IT. IT->object is the value
1628 of the glyph property displayed. The value must be a list
1629 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1632 1. `:width WIDTH' specifies that the space should be WIDTH *
1633 canonical char width wide. WIDTH may be an integer or floating
1636 2. `:relative-width FACTOR' specifies that the width of the stretch
1637 should be computed from the width of the first character having the
1638 `glyph' property, and should be FACTOR times that width.
1640 3. `:align-to HPOS' specifies that the space should be wide enough
1641 to reach HPOS, a value in canonical character units.
1643 Exactly one of the above pairs must be present.
1645 4. `:height HEIGHT' specifies that the height of the stretch produced
1646 should be HEIGHT, measured in canonical character units.
1648 5. `:relative-height FACTOR' specifies that the height of the
1649 stretch should be FACTOR times the height of the characters having
1652 Either none or exactly one of 4 or 5 must be present.
1654 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1655 of the stretch should be used for the ascent of the stretch.
1656 ASCENT must be in the range 0 <= ASCENT <= 100. */
1659 ((INTEGERP (X) || FLOATP (X)) \
1665 x_produce_stretch_glyph (it
)
1668 /* (space :width WIDTH :height HEIGHT. */
1670 extern Lisp_Object Qspace
;
1672 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1673 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1674 extern Lisp_Object QCalign_to
;
1675 Lisp_Object prop
, plist
;
1676 double width
= 0, height
= 0, ascent
= 0;
1677 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1678 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1680 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1682 /* List should start with `space'. */
1683 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1684 plist
= XCDR (it
->object
);
1686 /* Compute the width of the stretch. */
1687 if (prop
= Fplist_get (plist
, QCwidth
),
1689 /* Absolute width `:width WIDTH' specified and valid. */
1690 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1691 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1694 /* Relative width `:relative-width FACTOR' specified and valid.
1695 Compute the width of the characters having the `glyph'
1698 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1701 if (it
->multibyte_p
)
1703 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1704 - IT_BYTEPOS (*it
));
1705 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1708 it2
.c
= *p
, it2
.len
= 1;
1710 it2
.glyph_row
= NULL
;
1711 it2
.what
= IT_CHARACTER
;
1712 x_produce_glyphs (&it2
);
1713 width
= NUMVAL (prop
) * it2
.pixel_width
;
1715 else if (prop
= Fplist_get (plist
, QCalign_to
),
1717 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1719 /* Nothing specified -> width defaults to canonical char width. */
1720 width
= CANON_X_UNIT (it
->f
);
1722 /* Compute height. */
1723 if (prop
= Fplist_get (plist
, QCheight
),
1725 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1726 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1728 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1730 height
= FONT_HEIGHT (font
);
1732 /* Compute percentage of height used for ascent. If
1733 `:ascent ASCENT' is present and valid, use that. Otherwise,
1734 derive the ascent from the font in use. */
1735 if (prop
= Fplist_get (plist
, QCascent
),
1736 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1737 ascent
= NUMVAL (prop
) / 100.0;
1739 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1748 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1749 if (!STRINGP (object
))
1750 object
= it
->w
->buffer
;
1751 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1754 it
->pixel_width
= width
;
1755 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1756 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1759 if (face
->box
!= FACE_NO_BOX
)
1761 if (face
->box_line_width
> 0)
1763 it
->ascent
+= face
->box_line_width
;
1764 it
->descent
+= face
->box_line_width
;
1767 if (it
->start_of_box_run_p
)
1768 it
->pixel_width
+= abs (face
->box_line_width
);
1769 if (it
->end_of_box_run_p
)
1770 it
->pixel_width
+= abs (face
->box_line_width
);
1773 take_vertical_position_into_account (it
);
1776 /* Return proper value to be used as baseline offset of font that has
1777 ASCENT and DESCENT to draw characters by the font at the vertical
1778 center of the line of frame F.
1780 Here, out task is to find the value of BOFF in the following figure;
1782 -------------------------+-----------+-
1783 -+-+---------+-+ | |
1785 | | | | F_ASCENT F_HEIGHT
1788 | | |-|-+------+-----------|------- baseline
1790 | |---------|-+-+ | |
1792 -+-+---------+-+ F_DESCENT |
1793 -------------------------+-----------+-
1795 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1796 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1797 DESCENT = FONT->descent
1798 HEIGHT = FONT_HEIGHT (FONT)
1799 F_DESCENT = (F->output_data.x->font->descent
1800 - F->output_data.x->baseline_offset)
1801 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1804 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1806 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1807 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1808 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1810 /* Produce glyphs/get display metrics for the display element IT is
1811 loaded with. See the description of struct display_iterator in
1812 dispextern.h for an overview of struct display_iterator. */
1815 x_produce_glyphs (it
)
1818 it
->glyph_not_available_p
= 0;
1820 if (it
->what
== IT_CHARACTER
)
1824 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1826 int font_not_found_p
;
1827 struct font_info
*font_info
;
1828 int boff
; /* baseline offset */
1829 /* We may change it->multibyte_p upon unibyte<->multibyte
1830 conversion. So, save the current value now and restore it
1833 Note: It seems that we don't have to record multibyte_p in
1834 struct glyph because the character code itself tells if or
1835 not the character is multibyte. Thus, in the future, we must
1836 consider eliminating the field `multibyte_p' in the struct
1838 int saved_multibyte_p
= it
->multibyte_p
;
1840 /* Maybe translate single-byte characters to multibyte, or the
1842 it
->char_to_display
= it
->c
;
1843 if (!ASCII_BYTE_P (it
->c
))
1845 if (unibyte_display_via_language_environment
1846 && SINGLE_BYTE_CHAR_P (it
->c
)
1848 || !NILP (Vnonascii_translation_table
)))
1850 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1851 it
->multibyte_p
= 1;
1852 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1853 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1855 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1856 && !it
->multibyte_p
)
1858 it
->multibyte_p
= 1;
1859 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1860 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1864 /* Get font to use. Encode IT->char_to_display. */
1865 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1866 it
->face_id
, &char2b
,
1867 it
->multibyte_p
, 0);
1870 /* When no suitable font found, use the default font. */
1871 font_not_found_p
= font
== NULL
;
1872 if (font_not_found_p
)
1874 font
= FRAME_FONT (it
->f
);
1875 boff
= it
->f
->output_data
.x
->baseline_offset
;
1880 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1881 boff
= font_info
->baseline_offset
;
1882 if (font_info
->vertical_centering
)
1883 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1886 if (it
->char_to_display
>= ' '
1887 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1889 /* Either unibyte or ASCII. */
1894 pcm
= x_per_char_metric (font
, &char2b
);
1895 it
->ascent
= font
->ascent
+ boff
;
1896 it
->descent
= font
->descent
- boff
;
1900 it
->phys_ascent
= pcm
->ascent
+ boff
;
1901 it
->phys_descent
= pcm
->descent
- boff
;
1902 it
->pixel_width
= pcm
->width
;
1906 it
->glyph_not_available_p
= 1;
1907 it
->phys_ascent
= font
->ascent
+ boff
;
1908 it
->phys_descent
= font
->descent
- boff
;
1909 it
->pixel_width
= FONT_WIDTH (font
);
1912 /* If this is a space inside a region of text with
1913 `space-width' property, change its width. */
1914 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1916 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1918 /* If face has a box, add the box thickness to the character
1919 height. If character has a box line to the left and/or
1920 right, add the box line width to the character's width. */
1921 if (face
->box
!= FACE_NO_BOX
)
1923 int thick
= face
->box_line_width
;
1927 it
->ascent
+= thick
;
1928 it
->descent
+= thick
;
1933 if (it
->start_of_box_run_p
)
1934 it
->pixel_width
+= thick
;
1935 if (it
->end_of_box_run_p
)
1936 it
->pixel_width
+= thick
;
1939 /* If face has an overline, add the height of the overline
1940 (1 pixel) and a 1 pixel margin to the character height. */
1941 if (face
->overline_p
)
1944 take_vertical_position_into_account (it
);
1946 /* If we have to actually produce glyphs, do it. */
1951 /* Translate a space with a `space-width' property
1952 into a stretch glyph. */
1953 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1954 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1955 it
->ascent
+ it
->descent
, ascent
);
1958 x_append_glyph (it
);
1960 /* If characters with lbearing or rbearing are displayed
1961 in this line, record that fact in a flag of the
1962 glyph row. This is used to optimize X output code. */
1963 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1964 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1967 else if (it
->char_to_display
== '\n')
1969 /* A newline has no width but we need the height of the line. */
1970 it
->pixel_width
= 0;
1972 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1973 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1975 if (face
->box
!= FACE_NO_BOX
1976 && face
->box_line_width
> 0)
1978 it
->ascent
+= face
->box_line_width
;
1979 it
->descent
+= face
->box_line_width
;
1982 else if (it
->char_to_display
== '\t')
1984 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1985 int x
= it
->current_x
+ it
->continuation_lines_width
;
1986 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1988 /* If the distance from the current position to the next tab
1989 stop is less than a canonical character width, use the
1990 tab stop after that. */
1991 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1992 next_tab_x
+= tab_width
;
1994 it
->pixel_width
= next_tab_x
- x
;
1996 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1997 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
2001 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2002 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2003 it
->ascent
+ it
->descent
, ascent
);
2008 /* A multi-byte character. Assume that the display width of the
2009 character is the width of the character multiplied by the
2010 width of the font. */
2012 /* If we found a font, this font should give us the right
2013 metrics. If we didn't find a font, use the frame's
2014 default font and calculate the width of the character
2015 from the charset width; this is what old redisplay code
2017 pcm
= x_per_char_metric (font
, &char2b
);
2018 if (font_not_found_p
|| !pcm
)
2020 int charset
= CHAR_CHARSET (it
->char_to_display
);
2022 it
->glyph_not_available_p
= 1;
2023 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2024 * CHARSET_WIDTH (charset
));
2025 it
->phys_ascent
= font
->ascent
+ boff
;
2026 it
->phys_descent
= font
->descent
- boff
;
2030 it
->pixel_width
= pcm
->width
;
2031 it
->phys_ascent
= pcm
->ascent
+ boff
;
2032 it
->phys_descent
= pcm
->descent
- boff
;
2034 && (pcm
->lbearing
< 0
2035 || pcm
->rbearing
> pcm
->width
))
2036 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2039 it
->ascent
= font
->ascent
+ boff
;
2040 it
->descent
= font
->descent
- boff
;
2041 if (face
->box
!= FACE_NO_BOX
)
2043 int thick
= face
->box_line_width
;
2047 it
->ascent
+= thick
;
2048 it
->descent
+= thick
;
2053 if (it
->start_of_box_run_p
)
2054 it
->pixel_width
+= thick
;
2055 if (it
->end_of_box_run_p
)
2056 it
->pixel_width
+= thick
;
2059 /* If face has an overline, add the height of the overline
2060 (1 pixel) and a 1 pixel margin to the character height. */
2061 if (face
->overline_p
)
2064 take_vertical_position_into_account (it
);
2067 x_append_glyph (it
);
2069 it
->multibyte_p
= saved_multibyte_p
;
2071 else if (it
->what
== IT_COMPOSITION
)
2073 /* Note: A composition is represented as one glyph in the
2074 glyph matrix. There are no padding glyphs. */
2077 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2079 int font_not_found_p
;
2080 struct font_info
*font_info
;
2081 int boff
; /* baseline offset */
2082 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2084 /* Maybe translate single-byte characters to multibyte. */
2085 it
->char_to_display
= it
->c
;
2086 if (unibyte_display_via_language_environment
2087 && SINGLE_BYTE_CHAR_P (it
->c
)
2090 && !NILP (Vnonascii_translation_table
))))
2092 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2095 /* Get face and font to use. Encode IT->char_to_display. */
2096 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2097 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2098 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2099 it
->face_id
, &char2b
, it
->multibyte_p
, 0);
2102 /* When no suitable font found, use the default font. */
2103 font_not_found_p
= font
== NULL
;
2104 if (font_not_found_p
)
2106 font
= FRAME_FONT (it
->f
);
2107 boff
= it
->f
->output_data
.x
->baseline_offset
;
2112 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2113 boff
= font_info
->baseline_offset
;
2114 if (font_info
->vertical_centering
)
2115 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2118 /* There are no padding glyphs, so there is only one glyph to
2119 produce for the composition. Important is that pixel_width,
2120 ascent and descent are the values of what is drawn by
2121 draw_glyphs (i.e. the values of the overall glyphs composed). */
2124 /* If we have not yet calculated pixel size data of glyphs of
2125 the composition for the current face font, calculate them
2126 now. Theoretically, we have to check all fonts for the
2127 glyphs, but that requires much time and memory space. So,
2128 here we check only the font of the first glyph. This leads
2129 to incorrect display very rarely, and C-l (recenter) can
2130 correct the display anyway. */
2131 if (cmp
->font
!= (void *) font
)
2133 /* Ascent and descent of the font of the first character of
2134 this composition (adjusted by baseline offset). Ascent
2135 and descent of overall glyphs should not be less than
2136 them respectively. */
2137 int font_ascent
= font
->ascent
+ boff
;
2138 int font_descent
= font
->descent
- boff
;
2139 /* Bounding box of the overall glyphs. */
2140 int leftmost
, rightmost
, lowest
, highest
;
2141 int i
, width
, ascent
, descent
;
2143 cmp
->font
= (void *) font
;
2145 /* Initialize the bounding box. */
2147 && (pcm
= x_per_char_metric (font
, &char2b
)))
2150 ascent
= pcm
->ascent
;
2151 descent
= pcm
->descent
;
2155 width
= FONT_WIDTH (font
);
2156 ascent
= font
->ascent
;
2157 descent
= font
->descent
;
2161 lowest
= - descent
+ boff
;
2162 highest
= ascent
+ boff
;
2166 && font_info
->default_ascent
2167 && CHAR_TABLE_P (Vuse_default_ascent
)
2168 && !NILP (Faref (Vuse_default_ascent
,
2169 make_number (it
->char_to_display
))))
2170 highest
= font_info
->default_ascent
+ boff
;
2172 /* Draw the first glyph at the normal position. It may be
2173 shifted to right later if some other glyphs are drawn at
2175 cmp
->offsets
[0] = 0;
2176 cmp
->offsets
[1] = boff
;
2178 /* Set cmp->offsets for the remaining glyphs. */
2179 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2181 int left
, right
, btm
, top
;
2182 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2183 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2185 face
= FACE_FROM_ID (it
->f
, face_id
);
2186 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2187 it
->multibyte_p
, 0);
2191 font
= FRAME_FONT (it
->f
);
2192 boff
= it
->f
->output_data
.x
->baseline_offset
;
2198 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2199 boff
= font_info
->baseline_offset
;
2200 if (font_info
->vertical_centering
)
2201 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2205 && (pcm
= x_per_char_metric (font
, &char2b
)))
2208 ascent
= pcm
->ascent
;
2209 descent
= pcm
->descent
;
2213 width
= FONT_WIDTH (font
);
2218 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2220 /* Relative composition with or without
2222 left
= (leftmost
+ rightmost
- width
) / 2;
2223 btm
= - descent
+ boff
;
2224 if (font_info
&& font_info
->relative_compose
2225 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2226 || NILP (Faref (Vignore_relative_composition
,
2227 make_number (ch
)))))
2230 if (- descent
>= font_info
->relative_compose
)
2231 /* One extra pixel between two glyphs. */
2233 else if (ascent
<= 0)
2234 /* One extra pixel between two glyphs. */
2235 btm
= lowest
- 1 - ascent
- descent
;
2240 /* A composition rule is specified by an integer
2241 value that encodes global and new reference
2242 points (GREF and NREF). GREF and NREF are
2243 specified by numbers as below:
2251 ---3---4---5--- baseline
2253 6---7---8 -- descent
2255 int rule
= COMPOSITION_RULE (cmp
, i
);
2256 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2258 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2259 grefx
= gref
% 3, nrefx
= nref
% 3;
2260 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2263 + grefx
* (rightmost
- leftmost
) / 2
2264 - nrefx
* width
/ 2);
2265 btm
= ((grefy
== 0 ? highest
2267 : grefy
== 2 ? lowest
2268 : (highest
+ lowest
) / 2)
2269 - (nrefy
== 0 ? ascent
+ descent
2270 : nrefy
== 1 ? descent
- boff
2272 : (ascent
+ descent
) / 2));
2275 cmp
->offsets
[i
* 2] = left
;
2276 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2278 /* Update the bounding box of the overall glyphs. */
2279 right
= left
+ width
;
2280 top
= btm
+ descent
+ ascent
;
2281 if (left
< leftmost
)
2283 if (right
> rightmost
)
2291 /* If there are glyphs whose x-offsets are negative,
2292 shift all glyphs to the right and make all x-offsets
2296 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2297 cmp
->offsets
[i
* 2] -= leftmost
;
2298 rightmost
-= leftmost
;
2301 cmp
->pixel_width
= rightmost
;
2302 cmp
->ascent
= highest
;
2303 cmp
->descent
= - lowest
;
2304 if (cmp
->ascent
< font_ascent
)
2305 cmp
->ascent
= font_ascent
;
2306 if (cmp
->descent
< font_descent
)
2307 cmp
->descent
= font_descent
;
2310 it
->pixel_width
= cmp
->pixel_width
;
2311 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2312 it
->descent
= it
->phys_descent
= cmp
->descent
;
2314 if (face
->box
!= FACE_NO_BOX
)
2316 int thick
= face
->box_line_width
;
2320 it
->ascent
+= thick
;
2321 it
->descent
+= thick
;
2326 if (it
->start_of_box_run_p
)
2327 it
->pixel_width
+= thick
;
2328 if (it
->end_of_box_run_p
)
2329 it
->pixel_width
+= thick
;
2332 /* If face has an overline, add the height of the overline
2333 (1 pixel) and a 1 pixel margin to the character height. */
2334 if (face
->overline_p
)
2337 take_vertical_position_into_account (it
);
2340 x_append_composite_glyph (it
);
2342 else if (it
->what
== IT_IMAGE
)
2343 x_produce_image_glyph (it
);
2344 else if (it
->what
== IT_STRETCH
)
2345 x_produce_stretch_glyph (it
);
2347 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2348 because this isn't true for images with `:ascent 100'. */
2349 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2350 if (it
->area
== TEXT_AREA
)
2351 it
->current_x
+= it
->pixel_width
;
2353 it
->descent
+= it
->extra_line_spacing
;
2355 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2356 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2357 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2358 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2362 /* Estimate the pixel height of the mode or top line on frame F.
2363 FACE_ID specifies what line's height to estimate. */
2366 x_estimate_mode_line_height (f
, face_id
)
2368 enum face_id face_id
;
2370 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2372 /* This function is called so early when Emacs starts that the face
2373 cache and mode line face are not yet initialized. */
2374 if (FRAME_FACE_CACHE (f
))
2376 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2380 height
= FONT_HEIGHT (face
->font
);
2381 if (face
->box_line_width
> 0)
2382 height
+= 2 * face
->box_line_width
;
2390 /***********************************************************************
2392 ***********************************************************************/
2394 /* A sequence of glyphs to be drawn in the same face.
2396 This data structure is not really completely X specific, so it
2397 could possibly, at least partially, be useful for other systems. It
2398 is currently not part of the external redisplay interface because
2399 it's not clear what other systems will need. */
2403 /* X-origin of the string. */
2406 /* Y-origin and y-position of the base line of this string. */
2409 /* The width of the string, not including a face extension. */
2412 /* The width of the string, including a face extension. */
2413 int background_width
;
2415 /* The height of this string. This is the height of the line this
2416 string is drawn in, and can be different from the height of the
2417 font the string is drawn in. */
2420 /* Number of pixels this string overwrites in front of its x-origin.
2421 This number is zero if the string has an lbearing >= 0; it is
2422 -lbearing, if the string has an lbearing < 0. */
2425 /* Number of pixels this string overwrites past its right-most
2426 nominal x-position, i.e. x + width. Zero if the string's
2427 rbearing is <= its nominal width, rbearing - width otherwise. */
2430 /* The frame on which the glyph string is drawn. */
2433 /* The window on which the glyph string is drawn. */
2436 /* X display and window for convenience. */
2440 /* The glyph row for which this string was built. It determines the
2441 y-origin and height of the string. */
2442 struct glyph_row
*row
;
2444 /* The area within row. */
2445 enum glyph_row_area area
;
2447 /* Characters to be drawn, and number of characters. */
2451 /* A face-override for drawing cursors, mouse face and similar. */
2452 enum draw_glyphs_face hl
;
2454 /* Face in which this string is to be drawn. */
2457 /* Font in which this string is to be drawn. */
2460 /* Font info for this string. */
2461 struct font_info
*font_info
;
2463 /* Non-null means this string describes (part of) a composition.
2464 All characters from char2b are drawn composed. */
2465 struct composition
*cmp
;
2467 /* Index of this glyph string's first character in the glyph
2468 definition of CMP. If this is zero, this glyph string describes
2469 the first character of a composition. */
2472 /* 1 means this glyph strings face has to be drawn to the right end
2473 of the window's drawing area. */
2474 unsigned extends_to_end_of_line_p
: 1;
2476 /* 1 means the background of this string has been drawn. */
2477 unsigned background_filled_p
: 1;
2479 /* 1 means glyph string must be drawn with 16-bit functions. */
2480 unsigned two_byte_p
: 1;
2482 /* 1 means that the original font determined for drawing this glyph
2483 string could not be loaded. The member `font' has been set to
2484 the frame's default font in this case. */
2485 unsigned font_not_found_p
: 1;
2487 /* 1 means that the face in which this glyph string is drawn has a
2489 unsigned stippled_p
: 1;
2491 /* 1 means only the foreground of this glyph string must be drawn,
2492 and we should use the physical height of the line this glyph
2493 string appears in as clip rect. */
2494 unsigned for_overlaps_p
: 1;
2496 /* The GC to use for drawing this glyph string. */
2499 /* A pointer to the first glyph in the string. This glyph
2500 corresponds to char2b[0]. Needed to draw rectangles if
2501 font_not_found_p is 1. */
2502 struct glyph
*first_glyph
;
2504 /* Image, if any. */
2507 struct glyph_string
*next
, *prev
;
2514 x_dump_glyph_string (s
)
2515 struct glyph_string
*s
;
2517 fprintf (stderr
, "glyph string\n");
2518 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2519 s
->x
, s
->y
, s
->width
, s
->height
);
2520 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2521 fprintf (stderr
, " hl = %d\n", s
->hl
);
2522 fprintf (stderr
, " left overhang = %d, right = %d\n",
2523 s
->left_overhang
, s
->right_overhang
);
2524 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2525 fprintf (stderr
, " extends to end of line = %d\n",
2526 s
->extends_to_end_of_line_p
);
2527 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2528 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2531 #endif /* GLYPH_DEBUG */
2535 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2536 struct glyph_string
**,
2537 struct glyph_string
*,
2538 struct glyph_string
*));
2539 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2540 struct glyph_string
**,
2541 struct glyph_string
*,
2542 struct glyph_string
*));
2543 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2544 struct glyph_string
**,
2545 struct glyph_string
*));
2546 static int x_left_overwritten
P_ ((struct glyph_string
*));
2547 static int x_left_overwriting
P_ ((struct glyph_string
*));
2548 static int x_right_overwritten
P_ ((struct glyph_string
*));
2549 static int x_right_overwriting
P_ ((struct glyph_string
*));
2550 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2552 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2553 XChar2b
*, struct window
*,
2555 enum glyph_row_area
, int,
2556 enum draw_glyphs_face
));
2557 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2558 enum glyph_row_area
, int, int,
2559 enum draw_glyphs_face
, int));
2560 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2561 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2562 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2564 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2565 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2566 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2567 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2568 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2569 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2570 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2571 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2572 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2574 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2575 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2576 unsigned long *, double, int));
2577 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2578 double, int, unsigned long));
2579 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2580 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2581 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2582 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2583 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2584 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2585 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2587 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2588 int, int, int, int, XRectangle
*));
2589 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2590 int, int, int, XRectangle
*));
2591 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2592 enum glyph_row_area
));
2593 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2595 enum glyph_row_area
, int, int));
2598 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2602 /* Append the list of glyph strings with head H and tail T to the list
2603 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2606 x_append_glyph_string_lists (head
, tail
, h
, t
)
2607 struct glyph_string
**head
, **tail
;
2608 struct glyph_string
*h
, *t
;
2622 /* Prepend the list of glyph strings with head H and tail T to the
2623 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2627 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2628 struct glyph_string
**head
, **tail
;
2629 struct glyph_string
*h
, *t
;
2643 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2644 Set *HEAD and *TAIL to the resulting list. */
2647 x_append_glyph_string (head
, tail
, s
)
2648 struct glyph_string
**head
, **tail
;
2649 struct glyph_string
*s
;
2651 s
->next
= s
->prev
= NULL
;
2652 x_append_glyph_string_lists (head
, tail
, s
, s
);
2656 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2661 struct glyph_string
*s
;
2663 if (s
->font
== FRAME_FONT (s
->f
)
2664 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2665 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2667 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2670 /* Cursor on non-default face: must merge. */
2674 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2675 xgcv
.foreground
= s
->face
->background
;
2677 /* If the glyph would be invisible, try a different foreground. */
2678 if (xgcv
.foreground
== xgcv
.background
)
2679 xgcv
.foreground
= s
->face
->foreground
;
2680 if (xgcv
.foreground
== xgcv
.background
)
2681 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2682 if (xgcv
.foreground
== xgcv
.background
)
2683 xgcv
.foreground
= s
->face
->foreground
;
2685 /* Make sure the cursor is distinct from text in this face. */
2686 if (xgcv
.background
== s
->face
->background
2687 && xgcv
.foreground
== s
->face
->foreground
)
2689 xgcv
.background
= s
->face
->foreground
;
2690 xgcv
.foreground
= s
->face
->background
;
2693 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2694 xgcv
.font
= s
->font
->fid
;
2695 xgcv
.graphics_exposures
= False
;
2696 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2698 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2699 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2702 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2703 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2705 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2710 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2713 x_set_mouse_face_gc (s
)
2714 struct glyph_string
*s
;
2719 /* What face has to be used last for the mouse face? */
2720 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2721 face
= FACE_FROM_ID (s
->f
, face_id
);
2723 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2725 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2726 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2728 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2729 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2730 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2732 /* If font in this face is same as S->font, use it. */
2733 if (s
->font
== s
->face
->font
)
2734 s
->gc
= s
->face
->gc
;
2737 /* Otherwise construct scratch_cursor_gc with values from FACE
2742 xgcv
.background
= s
->face
->background
;
2743 xgcv
.foreground
= s
->face
->foreground
;
2744 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2745 xgcv
.font
= s
->font
->fid
;
2746 xgcv
.graphics_exposures
= False
;
2747 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2749 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2750 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2753 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2754 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2756 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2759 xassert (s
->gc
!= 0);
2763 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2764 Faces to use in the mode line have already been computed when the
2765 matrix was built, so there isn't much to do, here. */
2768 x_set_mode_line_face_gc (s
)
2769 struct glyph_string
*s
;
2771 s
->gc
= s
->face
->gc
;
2775 /* Set S->gc of glyph string S for drawing that glyph string. Set
2776 S->stippled_p to a non-zero value if the face of S has a stipple
2780 x_set_glyph_string_gc (s
)
2781 struct glyph_string
*s
;
2783 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2785 if (s
->hl
== DRAW_NORMAL_TEXT
)
2787 s
->gc
= s
->face
->gc
;
2788 s
->stippled_p
= s
->face
->stipple
!= 0;
2790 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2792 x_set_mode_line_face_gc (s
);
2793 s
->stippled_p
= s
->face
->stipple
!= 0;
2795 else if (s
->hl
== DRAW_CURSOR
)
2797 x_set_cursor_gc (s
);
2800 else if (s
->hl
== DRAW_MOUSE_FACE
)
2802 x_set_mouse_face_gc (s
);
2803 s
->stippled_p
= s
->face
->stipple
!= 0;
2805 else if (s
->hl
== DRAW_IMAGE_RAISED
2806 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2808 s
->gc
= s
->face
->gc
;
2809 s
->stippled_p
= s
->face
->stipple
!= 0;
2813 s
->gc
= s
->face
->gc
;
2814 s
->stippled_p
= s
->face
->stipple
!= 0;
2817 /* GC must have been set. */
2818 xassert (s
->gc
!= 0);
2822 /* Return in *R the clipping rectangle for glyph string S. */
2825 x_get_glyph_string_clip_rect (s
, r
)
2826 struct glyph_string
*s
;
2829 if (s
->row
->full_width_p
)
2831 /* Draw full-width. X coordinates are relative to S->w->left. */
2832 int canon_x
= CANON_X_UNIT (s
->f
);
2834 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2835 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2837 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2839 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2840 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2844 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2846 /* Unless displaying a mode or menu bar line, which are always
2847 fully visible, clip to the visible part of the row. */
2848 if (s
->w
->pseudo_window_p
)
2849 r
->height
= s
->row
->visible_height
;
2851 r
->height
= s
->height
;
2855 /* This is a text line that may be partially visible. */
2856 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2857 r
->width
= window_box_width (s
->w
, s
->area
);
2858 r
->height
= s
->row
->visible_height
;
2861 /* If S draws overlapping rows, it's sufficient to use the top and
2862 bottom of the window for clipping because this glyph string
2863 intentionally draws over other lines. */
2864 if (s
->for_overlaps_p
)
2866 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2867 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2871 /* Don't use S->y for clipping because it doesn't take partially
2872 visible lines into account. For example, it can be negative for
2873 partially visible lines at the top of a window. */
2874 if (!s
->row
->full_width_p
2875 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2876 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2878 r
->y
= max (0, s
->row
->y
);
2880 /* If drawing a tool-bar window, draw it over the internal border
2881 at the top of the window. */
2882 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2883 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2886 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2890 /* Set clipping for output of glyph string S. S may be part of a mode
2891 line or menu if we don't have X toolkit support. */
2894 x_set_glyph_string_clipping (s
)
2895 struct glyph_string
*s
;
2898 x_get_glyph_string_clip_rect (s
, &r
);
2899 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2903 /* Compute left and right overhang of glyph string S. If S is a glyph
2904 string for a composition, assume overhangs don't exist. */
2907 x_compute_glyph_string_overhangs (s
)
2908 struct glyph_string
*s
;
2911 && s
->first_glyph
->type
== CHAR_GLYPH
)
2914 int direction
, font_ascent
, font_descent
;
2915 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2916 &font_ascent
, &font_descent
, &cs
);
2917 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2918 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2923 /* Compute overhangs and x-positions for glyph string S and its
2924 predecessors, or successors. X is the starting x-position for S.
2925 BACKWARD_P non-zero means process predecessors. */
2928 x_compute_overhangs_and_x (s
, x
, backward_p
)
2929 struct glyph_string
*s
;
2937 x_compute_glyph_string_overhangs (s
);
2947 x_compute_glyph_string_overhangs (s
);
2956 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2957 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2958 assumed to be zero. */
2961 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2962 struct glyph
*glyph
;
2968 if (glyph
->type
== CHAR_GLYPH
)
2972 struct font_info
*font_info
;
2976 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2978 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2980 && (pcm
= x_per_char_metric (font
, &char2b
)))
2982 if (pcm
->rbearing
> pcm
->width
)
2983 *right
= pcm
->rbearing
- pcm
->width
;
2984 if (pcm
->lbearing
< 0)
2985 *left
= -pcm
->lbearing
;
2991 /* Return the index of the first glyph preceding glyph string S that
2992 is overwritten by S because of S's left overhang. Value is -1
2993 if no glyphs are overwritten. */
2996 x_left_overwritten (s
)
2997 struct glyph_string
*s
;
3001 if (s
->left_overhang
)
3004 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3005 int first
= s
->first_glyph
- glyphs
;
3007 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3008 x
-= glyphs
[i
].pixel_width
;
3019 /* Return the index of the first glyph preceding glyph string S that
3020 is overwriting S because of its right overhang. Value is -1 if no
3021 glyph in front of S overwrites S. */
3024 x_left_overwriting (s
)
3025 struct glyph_string
*s
;
3028 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3029 int first
= s
->first_glyph
- glyphs
;
3033 for (i
= first
- 1; i
>= 0; --i
)
3036 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3039 x
-= glyphs
[i
].pixel_width
;
3046 /* Return the index of the last glyph following glyph string S that is
3047 not overwritten by S because of S's right overhang. Value is -1 if
3048 no such glyph is found. */
3051 x_right_overwritten (s
)
3052 struct glyph_string
*s
;
3056 if (s
->right_overhang
)
3059 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3060 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3061 int end
= s
->row
->used
[s
->area
];
3063 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3064 x
+= glyphs
[i
].pixel_width
;
3073 /* Return the index of the last glyph following glyph string S that
3074 overwrites S because of its left overhang. Value is negative
3075 if no such glyph is found. */
3078 x_right_overwriting (s
)
3079 struct glyph_string
*s
;
3082 int end
= s
->row
->used
[s
->area
];
3083 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3084 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3088 for (i
= first
; i
< end
; ++i
)
3091 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3094 x
+= glyphs
[i
].pixel_width
;
3101 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3104 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3105 struct glyph_string
*s
;
3109 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3110 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3111 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3112 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3116 /* Draw the background of glyph_string S. If S->background_filled_p
3117 is non-zero don't draw it. FORCE_P non-zero means draw the
3118 background even if it wouldn't be drawn normally. This is used
3119 when a string preceding S draws into the background of S, or S
3120 contains the first component of a composition. */
3123 x_draw_glyph_string_background (s
, force_p
)
3124 struct glyph_string
*s
;
3127 /* Nothing to do if background has already been drawn or if it
3128 shouldn't be drawn in the first place. */
3129 if (!s
->background_filled_p
)
3131 int box_line_width
= max (s
->face
->box_line_width
, 0);
3135 /* Fill background with a stipple pattern. */
3136 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3137 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3138 s
->y
+ box_line_width
,
3139 s
->background_width
,
3140 s
->height
- 2 * box_line_width
);
3141 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3142 s
->background_filled_p
= 1;
3144 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3145 || s
->font_not_found_p
3146 || s
->extends_to_end_of_line_p
3149 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3150 s
->background_width
,
3151 s
->height
- 2 * box_line_width
);
3152 s
->background_filled_p
= 1;
3158 /* Draw the foreground of glyph string S. */
3161 x_draw_glyph_string_foreground (s
)
3162 struct glyph_string
*s
;
3166 /* If first glyph of S has a left box line, start drawing the text
3167 of S to the right of that box line. */
3168 if (s
->face
->box
!= FACE_NO_BOX
3169 && s
->first_glyph
->left_box_line_p
)
3170 x
= s
->x
+ abs (s
->face
->box_line_width
);
3174 /* Draw characters of S as rectangles if S's font could not be
3176 if (s
->font_not_found_p
)
3178 for (i
= 0; i
< s
->nchars
; ++i
)
3180 struct glyph
*g
= s
->first_glyph
+ i
;
3181 XDrawRectangle (s
->display
, s
->window
,
3182 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3184 x
+= g
->pixel_width
;
3189 char *char1b
= (char *) s
->char2b
;
3190 int boff
= s
->font_info
->baseline_offset
;
3192 if (s
->font_info
->vertical_centering
)
3193 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3195 /* If we can use 8-bit functions, condense S->char2b. */
3197 for (i
= 0; i
< s
->nchars
; ++i
)
3198 char1b
[i
] = s
->char2b
[i
].byte2
;
3200 /* Draw text with XDrawString if background has already been
3201 filled. Otherwise, use XDrawImageString. (Note that
3202 XDrawImageString is usually faster than XDrawString.) Always
3203 use XDrawImageString when drawing the cursor so that there is
3204 no chance that characters under a box cursor are invisible. */
3205 if (s
->for_overlaps_p
3206 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3208 /* Draw characters with 16-bit or 8-bit functions. */
3210 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3211 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3213 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3214 s
->ybase
- boff
, char1b
, s
->nchars
);
3219 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3220 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3222 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3223 s
->ybase
- boff
, char1b
, s
->nchars
);
3226 if (s
->face
->overstrike
)
3228 /* For overstriking (to simulate bold-face), draw the
3229 characters again shifted to the right by one pixel. */
3231 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
+ 1,
3232 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3234 XDrawString (s
->display
, s
->window
, s
->gc
, x
+ 1,
3235 s
->ybase
- boff
, char1b
, s
->nchars
);
3240 /* Draw the foreground of composite glyph string S. */
3243 x_draw_composite_glyph_string_foreground (s
)
3244 struct glyph_string
*s
;
3248 /* If first glyph of S has a left box line, start drawing the text
3249 of S to the right of that box line. */
3250 if (s
->face
->box
!= FACE_NO_BOX
3251 && s
->first_glyph
->left_box_line_p
)
3252 x
= s
->x
+ abs (s
->face
->box_line_width
);
3256 /* S is a glyph string for a composition. S->gidx is the index of
3257 the first character drawn for glyphs of this composition.
3258 S->gidx == 0 means we are drawing the very first character of
3259 this composition. */
3261 /* Draw a rectangle for the composition if the font for the very
3262 first character of the composition could not be loaded. */
3263 if (s
->font_not_found_p
)
3266 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3267 s
->width
- 1, s
->height
- 1);
3271 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3273 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3274 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3275 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3277 if (s
->face
->overstrike
)
3278 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3279 x
+ s
->cmp
->offsets
[s
->gidx
* 2] + 1,
3280 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3287 #ifdef USE_X_TOOLKIT
3289 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3290 static Boolean cvt_string_to_pixel
P_ ((Display
*, XrmValue
*, Cardinal
*,
3291 XrmValue
*, XrmValue
*, XtPointer
*));
3292 static void cvt_pixel_dtor
P_ ((XtAppContext
, XrmValue
*, XtPointer
,
3293 XrmValue
*, Cardinal
*));
3296 /* Return the frame on which widget WIDGET is used.. Abort if frame
3297 cannot be determined. */
3299 static struct frame
*
3300 x_frame_of_widget (widget
)
3303 struct x_display_info
*dpyinfo
;
3307 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3309 /* Find the top-level shell of the widget. Note that this function
3310 can be called when the widget is not yet realized, so XtWindow
3311 (widget) == 0. That's the reason we can't simply use
3312 x_any_window_to_frame. */
3313 while (!XtIsTopLevelShell (widget
))
3314 widget
= XtParent (widget
);
3316 /* Look for a frame with that top-level widget. Allocate the color
3317 on that frame to get the right gamma correction value. */
3318 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3319 if (GC_FRAMEP (XCAR (tail
))
3320 && (f
= XFRAME (XCAR (tail
)),
3321 (f
->output_data
.nothing
!= 1
3322 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3323 && f
->output_data
.x
->widget
== widget
)
3330 /* Allocate the color COLOR->pixel on the screen and display of
3331 widget WIDGET in colormap CMAP. If an exact match cannot be
3332 allocated, try the nearest color available. Value is non-zero
3333 if successful. This is called from lwlib. */
3336 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3341 struct frame
*f
= x_frame_of_widget (widget
);
3342 return x_alloc_nearest_color (f
, cmap
, color
);
3346 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3347 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3348 If this produces the same color as PIXEL, try a color where all RGB
3349 values have DELTA added. Return the allocated color in *PIXEL.
3350 DISPLAY is the X display, CMAP is the colormap to operate on.
3351 Value is non-zero if successful. */
3354 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3358 unsigned long *pixel
;
3362 struct frame
*f
= x_frame_of_widget (widget
);
3363 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3367 /* Structure specifying which arguments should be passed by Xt to
3368 cvt_string_to_pixel. We want the widget's screen and colormap. */
3370 static XtConvertArgRec cvt_string_to_pixel_args
[] =
3372 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.screen
),
3374 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.colormap
),
3379 /* The address of this variable is returned by
3380 cvt_string_to_pixel. */
3382 static Pixel cvt_string_to_pixel_value
;
3385 /* Convert a color name to a pixel color.
3387 DPY is the display we are working on.
3389 ARGS is an array of *NARGS XrmValue structures holding additional
3390 information about the widget for which the conversion takes place.
3391 The contents of this array are determined by the specification
3392 in cvt_string_to_pixel_args.
3394 FROM is a pointer to an XrmValue which points to the color name to
3395 convert. TO is an XrmValue in which to return the pixel color.
3397 CLOSURE_RET is a pointer to user-data, in which we record if
3398 we allocated the color or not.
3400 Value is True if successful, False otherwise. */
3403 cvt_string_to_pixel (dpy
, args
, nargs
, from
, to
, closure_ret
)
3407 XrmValue
*from
, *to
;
3408 XtPointer
*closure_ret
;
3418 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3419 "wrongParameters", "cvt_string_to_pixel",
3421 "Screen and colormap args required", NULL
, NULL
);
3425 screen
= *(Screen
**) args
[0].addr
;
3426 cmap
= *(Colormap
*) args
[1].addr
;
3427 color_name
= (String
) from
->addr
;
3429 if (strcmp (color_name
, XtDefaultBackground
) == 0)
3431 *closure_ret
= (XtPointer
) False
;
3432 pixel
= WhitePixelOfScreen (screen
);
3434 else if (strcmp (color_name
, XtDefaultForeground
) == 0)
3436 *closure_ret
= (XtPointer
) False
;
3437 pixel
= BlackPixelOfScreen (screen
);
3439 else if (XParseColor (dpy
, cmap
, color_name
, &color
)
3440 && x_alloc_nearest_color_1 (dpy
, cmap
, &color
))
3442 pixel
= color
.pixel
;
3443 *closure_ret
= (XtPointer
) True
;
3448 Cardinal nparams
= 1;
3450 params
[0] = color_name
;
3451 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3452 "badValue", "cvt_string_to_pixel",
3453 "XtToolkitError", "Invalid color `%s'",
3458 if (to
->addr
!= NULL
)
3460 if (to
->size
< sizeof (Pixel
))
3462 to
->size
= sizeof (Pixel
);
3466 *(Pixel
*) to
->addr
= pixel
;
3470 cvt_string_to_pixel_value
= pixel
;
3471 to
->addr
= (XtPointer
) &cvt_string_to_pixel_value
;
3474 to
->size
= sizeof (Pixel
);
3479 /* Free a pixel color which was previously allocated via
3480 cvt_string_to_pixel. This is registered as the destructor
3481 for this type of resource via XtSetTypeConverter.
3483 APP is the application context in which we work.
3485 TO is a pointer to an XrmValue holding the color to free.
3486 CLOSURE is the value we stored in CLOSURE_RET for this color
3487 in cvt_string_to_pixel.
3489 ARGS and NARGS are like for cvt_string_to_pixel. */
3492 cvt_pixel_dtor (app
, to
, closure
, args
, nargs
)
3501 XtAppWarningMsg (app
, "wrongParameters", "cvt_pixel_dtor",
3503 "Screen and colormap arguments required",
3506 else if (closure
!= NULL
)
3508 /* We did allocate the pixel, so free it. */
3509 Screen
*screen
= *(Screen
**) args
[0].addr
;
3510 Colormap cmap
= *(Colormap
*) args
[1].addr
;
3511 x_free_dpy_colors (DisplayOfScreen (screen
), screen
, cmap
,
3512 (Pixel
*) to
->addr
, 1);
3517 #endif /* USE_X_TOOLKIT */
3520 /* Value is an array of XColor structures for the contents of the
3521 color map of display DPY. Set *NCELLS to the size of the array.
3522 Note that this probably shouldn't be called for large color maps,
3523 say a 24-bit TrueColor map. */
3525 static const XColor
*
3526 x_color_cells (dpy
, ncells
)
3530 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3532 if (dpyinfo
->color_cells
== NULL
)
3534 Screen
*screen
= dpyinfo
->screen
;
3537 dpyinfo
->ncolor_cells
3538 = XDisplayCells (dpy
, XScreenNumberOfScreen (screen
));
3539 dpyinfo
->color_cells
3540 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3541 * sizeof *dpyinfo
->color_cells
);
3543 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3544 dpyinfo
->color_cells
[i
].pixel
= i
;
3546 XQueryColors (dpy
, dpyinfo
->cmap
,
3547 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3550 *ncells
= dpyinfo
->ncolor_cells
;
3551 return dpyinfo
->color_cells
;
3555 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3556 colors in COLORS. Use cached information, if available. */
3559 x_query_colors (f
, colors
, ncolors
)
3564 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3566 if (dpyinfo
->color_cells
)
3569 for (i
= 0; i
< ncolors
; ++i
)
3571 unsigned long pixel
= colors
[i
].pixel
;
3572 xassert (pixel
< dpyinfo
->ncolor_cells
);
3573 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3574 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3578 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3582 /* On frame F, translate pixel color to RGB values for the color in
3583 COLOR. Use cached information, if available. */
3586 x_query_color (f
, color
)
3590 x_query_colors (f
, color
, 1);
3594 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
3595 exact match can't be allocated, try the nearest color available.
3596 Value is non-zero if successful. Set *COLOR to the color
3600 x_alloc_nearest_color_1 (dpy
, cmap
, color
)
3607 rc
= XAllocColor (dpy
, cmap
, color
);
3610 /* If we got to this point, the colormap is full, so we're going
3611 to try to get the next closest color. The algorithm used is
3612 a least-squares matching, which is what X uses for closest
3613 color matching with StaticColor visuals. */
3615 unsigned long nearest_delta
= ~0;
3617 const XColor
*cells
= x_color_cells (dpy
, &ncells
);
3619 for (nearest
= i
= 0; i
< ncells
; ++i
)
3621 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3622 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3623 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3624 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3626 if (delta
< nearest_delta
)
3629 nearest_delta
= delta
;
3633 color
->red
= cells
[nearest
].red
;
3634 color
->green
= cells
[nearest
].green
;
3635 color
->blue
= cells
[nearest
].blue
;
3636 rc
= XAllocColor (dpy
, cmap
, color
);
3640 /* If allocation succeeded, and the allocated pixel color is not
3641 equal to a cached pixel color recorded earlier, there was a
3642 change in the colormap, so clear the color cache. */
3643 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3644 XColor
*cached_color
;
3646 if (dpyinfo
->color_cells
3647 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3648 (cached_color
->red
!= color
->red
3649 || cached_color
->blue
!= color
->blue
3650 || cached_color
->green
!= color
->green
)))
3652 xfree (dpyinfo
->color_cells
);
3653 dpyinfo
->color_cells
= NULL
;
3654 dpyinfo
->ncolor_cells
= 0;
3658 #ifdef DEBUG_X_COLORS
3660 register_color (color
->pixel
);
3661 #endif /* DEBUG_X_COLORS */
3667 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
3668 exact match can't be allocated, try the nearest color available.
3669 Value is non-zero if successful. Set *COLOR to the color
3673 x_alloc_nearest_color (f
, cmap
, color
)
3678 gamma_correct (f
, color
);
3679 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f
), cmap
, color
);
3683 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3684 It's necessary to do this instead of just using PIXEL directly to
3685 get color reference counts right. */
3688 x_copy_color (f
, pixel
)
3690 unsigned long pixel
;
3694 color
.pixel
= pixel
;
3696 x_query_color (f
, &color
);
3697 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3699 #ifdef DEBUG_X_COLORS
3700 register_color (pixel
);
3706 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3707 It's necessary to do this instead of just using PIXEL directly to
3708 get color reference counts right. */
3711 x_copy_dpy_color (dpy
, cmap
, pixel
)
3714 unsigned long pixel
;
3718 color
.pixel
= pixel
;
3720 XQueryColor (dpy
, cmap
, &color
);
3721 XAllocColor (dpy
, cmap
, &color
);
3723 #ifdef DEBUG_X_COLORS
3724 register_color (pixel
);
3730 /* Brightness beyond which a color won't have its highlight brightness
3733 Nominally, highlight colors for `3d' faces are calculated by
3734 brightening an object's color by a constant scale factor, but this
3735 doesn't yield good results for dark colors, so for colors who's
3736 brightness is less than this value (on a scale of 0-65535) have an
3737 use an additional additive factor.
3739 The value here is set so that the default menu-bar/mode-line color
3740 (grey75) will not have its highlights changed at all. */
3741 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
3744 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3745 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3746 If this produces the same color as PIXEL, try a color where all RGB
3747 values have DELTA added. Return the allocated color in *PIXEL.
3748 DISPLAY is the X display, CMAP is the colormap to operate on.
3749 Value is non-zero if successful. */
3752 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3756 unsigned long *pixel
;
3764 /* Get RGB color values. */
3765 color
.pixel
= *pixel
;
3766 x_query_color (f
, &color
);
3768 /* Change RGB values by specified FACTOR. Avoid overflow! */
3769 xassert (factor
>= 0);
3770 new.red
= min (0xffff, factor
* color
.red
);
3771 new.green
= min (0xffff, factor
* color
.green
);
3772 new.blue
= min (0xffff, factor
* color
.blue
);
3774 /* Calculate brightness of COLOR. */
3775 bright
= (2 * color
.red
+ 3 * color
.green
+ color
.blue
) / 6;
3777 /* We only boost colors that are darker than
3778 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3779 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3780 /* Make an additive adjustment to NEW, because it's dark enough so
3781 that scaling by FACTOR alone isn't enough. */
3783 /* How far below the limit this color is (0 - 1, 1 being darker). */
3784 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3785 /* The additive adjustment. */
3786 int min_delta
= delta
* dimness
* factor
/ 2;
3790 new.red
= max (0, new.red
- min_delta
);
3791 new.green
= max (0, new.green
- min_delta
);
3792 new.blue
= max (0, new.blue
- min_delta
);
3796 new.red
= min (0xffff, min_delta
+ new.red
);
3797 new.green
= min (0xffff, min_delta
+ new.green
);
3798 new.blue
= min (0xffff, min_delta
+ new.blue
);
3802 /* Try to allocate the color. */
3803 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3806 if (new.pixel
== *pixel
)
3808 /* If we end up with the same color as before, try adding
3809 delta to the RGB values. */
3810 x_free_colors (f
, &new.pixel
, 1);
3812 new.red
= min (0xffff, delta
+ color
.red
);
3813 new.green
= min (0xffff, delta
+ color
.green
);
3814 new.blue
= min (0xffff, delta
+ color
.blue
);
3815 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3826 /* Set up the foreground color for drawing relief lines of glyph
3827 string S. RELIEF is a pointer to a struct relief containing the GC
3828 with which lines will be drawn. Use a color that is FACTOR or
3829 DELTA lighter or darker than the relief's background which is found
3830 in S->f->output_data.x->relief_background. If such a color cannot
3831 be allocated, use DEFAULT_PIXEL, instead. */
3834 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3836 struct relief
*relief
;
3839 unsigned long default_pixel
;
3842 struct x_output
*di
= f
->output_data
.x
;
3843 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3844 unsigned long pixel
;
3845 unsigned long background
= di
->relief_background
;
3846 Colormap cmap
= FRAME_X_COLORMAP (f
);
3847 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3848 Display
*dpy
= FRAME_X_DISPLAY (f
);
3850 xgcv
.graphics_exposures
= False
;
3851 xgcv
.line_width
= 1;
3853 /* Free previously allocated color. The color cell will be reused
3854 when it has been freed as many times as it was allocated, so this
3855 doesn't affect faces using the same colors. */
3857 && relief
->allocated_p
)
3859 x_free_colors (f
, &relief
->pixel
, 1);
3860 relief
->allocated_p
= 0;
3863 /* Allocate new color. */
3864 xgcv
.foreground
= default_pixel
;
3866 if (dpyinfo
->n_planes
!= 1
3867 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3869 relief
->allocated_p
= 1;
3870 xgcv
.foreground
= relief
->pixel
= pixel
;
3873 if (relief
->gc
== 0)
3875 xgcv
.stipple
= dpyinfo
->gray
;
3877 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3880 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3884 /* Set up colors for the relief lines around glyph string S. */
3887 x_setup_relief_colors (s
)
3888 struct glyph_string
*s
;
3890 struct x_output
*di
= s
->f
->output_data
.x
;
3891 unsigned long color
;
3893 if (s
->face
->use_box_color_for_shadows_p
)
3894 color
= s
->face
->box_color
;
3895 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3897 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3898 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3903 /* Get the background color of the face. */
3904 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3905 color
= xgcv
.background
;
3908 if (di
->white_relief
.gc
== 0
3909 || color
!= di
->relief_background
)
3911 di
->relief_background
= color
;
3912 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3913 WHITE_PIX_DEFAULT (s
->f
));
3914 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3915 BLACK_PIX_DEFAULT (s
->f
));
3920 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3921 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3922 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3923 relief. LEFT_P non-zero means draw a relief on the left side of
3924 the rectangle. RIGHT_P non-zero means draw a relief on the right
3925 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3929 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3930 raised_p
, left_p
, right_p
, clip_rect
)
3932 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
, raised_p
;
3933 XRectangle
*clip_rect
;
3935 Display
*dpy
= FRAME_X_DISPLAY (f
);
3936 Window window
= FRAME_X_WINDOW (f
);
3941 gc
= f
->output_data
.x
->white_relief
.gc
;
3943 gc
= f
->output_data
.x
->black_relief
.gc
;
3944 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3947 for (i
= 0; i
< width
; ++i
)
3948 XDrawLine (dpy
, window
, gc
,
3949 left_x
+ i
* left_p
, top_y
+ i
,
3950 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3954 for (i
= 0; i
< width
; ++i
)
3955 XDrawLine (dpy
, window
, gc
,
3956 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3958 XSetClipMask (dpy
, gc
, None
);
3960 gc
= f
->output_data
.x
->black_relief
.gc
;
3962 gc
= f
->output_data
.x
->white_relief
.gc
;
3963 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3966 for (i
= 0; i
< width
; ++i
)
3967 XDrawLine (dpy
, window
, gc
,
3968 left_x
+ i
* left_p
, bottom_y
- i
,
3969 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3973 for (i
= 0; i
< width
; ++i
)
3974 XDrawLine (dpy
, window
, gc
,
3975 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3977 XSetClipMask (dpy
, gc
, None
);
3981 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3982 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3983 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3984 left side of the rectangle. RIGHT_P non-zero means draw a line
3985 on the right side of the rectangle. CLIP_RECT is the clipping
3986 rectangle to use when drawing. */
3989 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3990 left_p
, right_p
, clip_rect
)
3991 struct glyph_string
*s
;
3992 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3993 XRectangle
*clip_rect
;
3997 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3998 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3999 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
4002 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4003 left_x
, top_y
, right_x
- left_x
+ 1, width
);
4007 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4008 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
4011 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4012 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
4016 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4017 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
4019 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4020 XSetClipMask (s
->display
, s
->gc
, None
);
4024 /* Draw a box around glyph string S. */
4027 x_draw_glyph_string_box (s
)
4028 struct glyph_string
*s
;
4030 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4031 int left_p
, right_p
;
4032 struct glyph
*last_glyph
;
4033 XRectangle clip_rect
;
4035 last_x
= window_box_right (s
->w
, s
->area
);
4036 if (s
->row
->full_width_p
4037 && !s
->w
->pseudo_window_p
)
4039 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4040 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4041 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4044 /* The glyph that may have a right box line. */
4045 last_glyph
= (s
->cmp
|| s
->img
4047 : s
->first_glyph
+ s
->nchars
- 1);
4049 width
= abs (s
->face
->box_line_width
);
4050 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4052 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4054 : min (last_x
, s
->x
+ s
->background_width
) - 1);
4056 bottom_y
= top_y
+ s
->height
- 1;
4058 left_p
= (s
->first_glyph
->left_box_line_p
4059 || (s
->hl
== DRAW_MOUSE_FACE
4061 || s
->prev
->hl
!= s
->hl
)));
4062 right_p
= (last_glyph
->right_box_line_p
4063 || (s
->hl
== DRAW_MOUSE_FACE
4065 || s
->next
->hl
!= s
->hl
)));
4067 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4069 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4070 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4071 left_p
, right_p
, &clip_rect
);
4074 x_setup_relief_colors (s
);
4075 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4076 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4081 /* Draw foreground of image glyph string S. */
4084 x_draw_image_foreground (s
)
4085 struct glyph_string
*s
;
4088 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4090 /* If first glyph of S has a left box line, start drawing it to the
4091 right of that line. */
4092 if (s
->face
->box
!= FACE_NO_BOX
4093 && s
->first_glyph
->left_box_line_p
)
4094 x
= s
->x
+ abs (s
->face
->box_line_width
);
4098 /* If there is a margin around the image, adjust x- and y-position
4100 x
+= s
->img
->hmargin
;
4101 y
+= s
->img
->vmargin
;
4107 /* We can't set both a clip mask and use XSetClipRectangles
4108 because the latter also sets a clip mask. We also can't
4109 trust on the shape extension to be available
4110 (XShapeCombineRegion). So, compute the rectangle to draw
4112 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4115 XRectangle clip_rect
, image_rect
, r
;
4117 xgcv
.clip_mask
= s
->img
->mask
;
4118 xgcv
.clip_x_origin
= x
;
4119 xgcv
.clip_y_origin
= y
;
4120 xgcv
.function
= GXcopy
;
4121 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4123 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4126 image_rect
.width
= s
->img
->width
;
4127 image_rect
.height
= s
->img
->height
;
4128 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4129 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4130 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4134 XRectangle clip_rect
, image_rect
, r
;
4136 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4139 image_rect
.width
= s
->img
->width
;
4140 image_rect
.height
= s
->img
->height
;
4141 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4142 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4143 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4145 /* When the image has a mask, we can expect that at
4146 least part of a mouse highlight or a block cursor will
4147 be visible. If the image doesn't have a mask, make
4148 a block cursor visible by drawing a rectangle around
4149 the image. I believe it's looking better if we do
4150 nothing here for mouse-face. */
4151 if (s
->hl
== DRAW_CURSOR
)
4153 int r
= s
->img
->relief
;
4155 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4156 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4161 /* Draw a rectangle if image could not be loaded. */
4162 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4163 s
->img
->width
- 1, s
->img
->height
- 1);
4167 /* Draw a relief around the image glyph string S. */
4170 x_draw_image_relief (s
)
4171 struct glyph_string
*s
;
4173 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4176 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4178 /* If first glyph of S has a left box line, start drawing it to the
4179 right of that line. */
4180 if (s
->face
->box
!= FACE_NO_BOX
4181 && s
->first_glyph
->left_box_line_p
)
4182 x
= s
->x
+ abs (s
->face
->box_line_width
);
4186 /* If there is a margin around the image, adjust x- and y-position
4188 x
+= s
->img
->hmargin
;
4189 y
+= s
->img
->vmargin
;
4191 if (s
->hl
== DRAW_IMAGE_SUNKEN
4192 || s
->hl
== DRAW_IMAGE_RAISED
)
4194 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4195 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4199 thick
= abs (s
->img
->relief
);
4200 raised_p
= s
->img
->relief
> 0;
4205 x1
= x
+ s
->img
->width
+ thick
- 1;
4206 y1
= y
+ s
->img
->height
+ thick
- 1;
4208 x_setup_relief_colors (s
);
4209 x_get_glyph_string_clip_rect (s
, &r
);
4210 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4214 /* Draw the foreground of image glyph string S to PIXMAP. */
4217 x_draw_image_foreground_1 (s
, pixmap
)
4218 struct glyph_string
*s
;
4222 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4224 /* If first glyph of S has a left box line, start drawing it to the
4225 right of that line. */
4226 if (s
->face
->box
!= FACE_NO_BOX
4227 && s
->first_glyph
->left_box_line_p
)
4228 x
= abs (s
->face
->box_line_width
);
4232 /* If there is a margin around the image, adjust x- and y-position
4234 x
+= s
->img
->hmargin
;
4235 y
+= s
->img
->vmargin
;
4241 /* We can't set both a clip mask and use XSetClipRectangles
4242 because the latter also sets a clip mask. We also can't
4243 trust on the shape extension to be available
4244 (XShapeCombineRegion). So, compute the rectangle to draw
4246 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4250 xgcv
.clip_mask
= s
->img
->mask
;
4251 xgcv
.clip_x_origin
= x
;
4252 xgcv
.clip_y_origin
= y
;
4253 xgcv
.function
= GXcopy
;
4254 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4256 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4257 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4258 XSetClipMask (s
->display
, s
->gc
, None
);
4262 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4263 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4265 /* When the image has a mask, we can expect that at
4266 least part of a mouse highlight or a block cursor will
4267 be visible. If the image doesn't have a mask, make
4268 a block cursor visible by drawing a rectangle around
4269 the image. I believe it's looking better if we do
4270 nothing here for mouse-face. */
4271 if (s
->hl
== DRAW_CURSOR
)
4273 int r
= s
->img
->relief
;
4275 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4276 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4281 /* Draw a rectangle if image could not be loaded. */
4282 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4283 s
->img
->width
- 1, s
->img
->height
- 1);
4287 /* Draw part of the background of glyph string S. X, Y, W, and H
4288 give the rectangle to draw. */
4291 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4292 struct glyph_string
*s
;
4297 /* Fill background with a stipple pattern. */
4298 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4299 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4300 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4303 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4307 /* Draw image glyph string S.
4310 s->x +-------------------------
4313 | +-------------------------
4316 | | +-------------------
4322 x_draw_image_glyph_string (s
)
4323 struct glyph_string
*s
;
4326 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4327 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4329 Pixmap pixmap
= None
;
4331 height
= s
->height
- 2 * box_line_vwidth
;
4333 /* Fill background with face under the image. Do it only if row is
4334 taller than image or if image has a clip mask to reduce
4336 s
->stippled_p
= s
->face
->stipple
!= 0;
4337 if (height
> s
->img
->height
4341 || s
->img
->pixmap
== 0
4342 || s
->width
!= s
->background_width
)
4344 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4345 x
= s
->x
+ box_line_hwidth
;
4349 y
= s
->y
+ box_line_vwidth
;
4353 /* Create a pixmap as large as the glyph string. Fill it
4354 with the background color. Copy the image to it, using
4355 its mask. Copy the temporary pixmap to the display. */
4356 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4357 int depth
= DefaultDepthOfScreen (screen
);
4359 /* Create a pixmap as large as the glyph string. */
4360 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4361 s
->background_width
,
4364 /* Don't clip in the following because we're working on the
4366 XSetClipMask (s
->display
, s
->gc
, None
);
4368 /* Fill the pixmap with the background color/stipple. */
4371 /* Fill background with a stipple pattern. */
4372 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4373 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4374 0, 0, s
->background_width
, s
->height
);
4375 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4380 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4382 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4383 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4384 0, 0, s
->background_width
, s
->height
);
4385 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4389 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4391 s
->background_filled_p
= 1;
4394 /* Draw the foreground. */
4397 x_draw_image_foreground_1 (s
, pixmap
);
4398 x_set_glyph_string_clipping (s
);
4399 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4400 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4401 XFreePixmap (s
->display
, pixmap
);
4404 x_draw_image_foreground (s
);
4406 /* If we must draw a relief around the image, do it. */
4408 || s
->hl
== DRAW_IMAGE_RAISED
4409 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4410 x_draw_image_relief (s
);
4414 /* Draw stretch glyph string S. */
4417 x_draw_stretch_glyph_string (s
)
4418 struct glyph_string
*s
;
4420 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4421 s
->stippled_p
= s
->face
->stipple
!= 0;
4423 if (s
->hl
== DRAW_CURSOR
4424 && !x_stretch_cursor_p
)
4426 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4427 as wide as the stretch glyph. */
4428 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4431 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4433 /* Clear rest using the GC of the original non-cursor face. */
4434 if (width
< s
->background_width
)
4436 int x
= s
->x
+ width
, y
= s
->y
;
4437 int w
= s
->background_width
- width
, h
= s
->height
;
4441 if (s
->row
->mouse_face_p
4442 && cursor_in_mouse_face_p (s
->w
))
4444 x_set_mouse_face_gc (s
);
4450 x_get_glyph_string_clip_rect (s
, &r
);
4451 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4453 if (s
->face
->stipple
)
4455 /* Fill background with a stipple pattern. */
4456 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4457 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4458 XSetFillStyle (s
->display
, gc
, FillSolid
);
4463 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4464 XSetForeground (s
->display
, gc
, xgcv
.background
);
4465 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4466 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4470 else if (!s
->background_filled_p
)
4471 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4474 s
->background_filled_p
= 1;
4478 /* Draw glyph string S. */
4481 x_draw_glyph_string (s
)
4482 struct glyph_string
*s
;
4484 int relief_drawn_p
= 0;
4486 /* If S draws into the background of its successor, draw the
4487 background of the successor first so that S can draw into it.
4488 This makes S->next use XDrawString instead of XDrawImageString. */
4489 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4491 xassert (s
->next
->img
== NULL
);
4492 x_set_glyph_string_gc (s
->next
);
4493 x_set_glyph_string_clipping (s
->next
);
4494 x_draw_glyph_string_background (s
->next
, 1);
4497 /* Set up S->gc, set clipping and draw S. */
4498 x_set_glyph_string_gc (s
);
4500 /* Draw relief (if any) in advance for char/composition so that the
4501 glyph string can be drawn over it. */
4502 if (!s
->for_overlaps_p
4503 && s
->face
->box
!= FACE_NO_BOX
4504 && (s
->first_glyph
->type
== CHAR_GLYPH
4505 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4508 x_set_glyph_string_clipping (s
);
4509 x_draw_glyph_string_background (s
, 1);
4510 x_draw_glyph_string_box (s
);
4511 x_set_glyph_string_clipping (s
);
4515 x_set_glyph_string_clipping (s
);
4517 switch (s
->first_glyph
->type
)
4520 x_draw_image_glyph_string (s
);
4524 x_draw_stretch_glyph_string (s
);
4528 if (s
->for_overlaps_p
)
4529 s
->background_filled_p
= 1;
4531 x_draw_glyph_string_background (s
, 0);
4532 x_draw_glyph_string_foreground (s
);
4535 case COMPOSITE_GLYPH
:
4536 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4537 s
->background_filled_p
= 1;
4539 x_draw_glyph_string_background (s
, 1);
4540 x_draw_composite_glyph_string_foreground (s
);
4547 if (!s
->for_overlaps_p
)
4549 /* Draw underline. */
4550 if (s
->face
->underline_p
)
4552 unsigned long tem
, h
;
4555 /* Get the underline thickness. Default is 1 pixel. */
4556 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4559 /* Get the underline position. This is the recommended
4560 vertical offset in pixels from the baseline to the top of
4561 the underline. This is a signed value according to the
4562 specs, and its default is
4564 ROUND ((maximum descent) / 2), with
4565 ROUND(x) = floor (x + 0.5) */
4567 if (x_use_underline_position_properties
4568 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4569 y
= s
->ybase
+ (long) tem
;
4570 else if (s
->face
->font
)
4571 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4573 y
= s
->y
+ s
->height
- h
;
4575 if (s
->face
->underline_defaulted_p
)
4576 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4577 s
->x
, y
, s
->width
, h
);
4581 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4582 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4583 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4584 s
->x
, y
, s
->width
, h
);
4585 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4589 /* Draw overline. */
4590 if (s
->face
->overline_p
)
4592 unsigned long dy
= 0, h
= 1;
4594 if (s
->face
->overline_color_defaulted_p
)
4595 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4600 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4601 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4602 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4604 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4608 /* Draw strike-through. */
4609 if (s
->face
->strike_through_p
)
4611 unsigned long h
= 1;
4612 unsigned long dy
= (s
->height
- h
) / 2;
4614 if (s
->face
->strike_through_color_defaulted_p
)
4615 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4620 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4621 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4622 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4624 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4628 /* Draw relief if not yet drawn. */
4629 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4630 x_draw_glyph_string_box (s
);
4633 /* Reset clipping. */
4634 XSetClipMask (s
->display
, s
->gc
, None
);
4638 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4639 struct face
**, int));
4642 /* Fill glyph string S with composition components specified by S->cmp.
4644 FACES is an array of faces for all components of this composition.
4645 S->gidx is the index of the first component for S.
4646 OVERLAPS_P non-zero means S should draw the foreground only, and
4647 use its physical height for clipping.
4649 Value is the index of a component not in S. */
4652 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4653 struct glyph_string
*s
;
4654 struct face
**faces
;
4661 s
->for_overlaps_p
= overlaps_p
;
4663 s
->face
= faces
[s
->gidx
];
4664 s
->font
= s
->face
->font
;
4665 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4667 /* For all glyphs of this composition, starting at the offset
4668 S->gidx, until we reach the end of the definition or encounter a
4669 glyph that requires the different face, add it to S. */
4671 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4674 /* All glyph strings for the same composition has the same width,
4675 i.e. the width set for the first component of the composition. */
4677 s
->width
= s
->first_glyph
->pixel_width
;
4679 /* If the specified font could not be loaded, use the frame's
4680 default font, but record the fact that we couldn't load it in
4681 the glyph string so that we can draw rectangles for the
4682 characters of the glyph string. */
4683 if (s
->font
== NULL
)
4685 s
->font_not_found_p
= 1;
4686 s
->font
= FRAME_FONT (s
->f
);
4689 /* Adjust base line for subscript/superscript text. */
4690 s
->ybase
+= s
->first_glyph
->voffset
;
4692 xassert (s
->face
&& s
->face
->gc
);
4694 /* This glyph string must always be drawn with 16-bit functions. */
4697 return s
->gidx
+ s
->nchars
;
4701 /* Fill glyph string S from a sequence of character glyphs.
4703 FACE_ID is the face id of the string. START is the index of the
4704 first glyph to consider, END is the index of the last + 1.
4705 OVERLAPS_P non-zero means S should draw the foreground only, and
4706 use its physical height for clipping.
4708 Value is the index of the first glyph not in S. */
4711 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4712 struct glyph_string
*s
;
4714 int start
, end
, overlaps_p
;
4716 struct glyph
*glyph
, *last
;
4718 int glyph_not_available_p
;
4720 xassert (s
->f
== XFRAME (s
->w
->frame
));
4721 xassert (s
->nchars
== 0);
4722 xassert (start
>= 0 && end
> start
);
4724 s
->for_overlaps_p
= overlaps_p
,
4725 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4726 last
= s
->row
->glyphs
[s
->area
] + end
;
4727 voffset
= glyph
->voffset
;
4729 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4732 && glyph
->type
== CHAR_GLYPH
4733 && glyph
->voffset
== voffset
4734 /* Same face id implies same font, nowadays. */
4735 && glyph
->face_id
== face_id
4736 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4740 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4741 s
->char2b
+ s
->nchars
,
4743 s
->two_byte_p
= two_byte_p
;
4745 xassert (s
->nchars
<= end
- start
);
4746 s
->width
+= glyph
->pixel_width
;
4750 s
->font
= s
->face
->font
;
4751 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4753 /* If the specified font could not be loaded, use the frame's font,
4754 but record the fact that we couldn't load it in
4755 S->font_not_found_p so that we can draw rectangles for the
4756 characters of the glyph string. */
4757 if (s
->font
== NULL
|| glyph_not_available_p
)
4759 s
->font_not_found_p
= 1;
4760 s
->font
= FRAME_FONT (s
->f
);
4763 /* Adjust base line for subscript/superscript text. */
4764 s
->ybase
+= voffset
;
4766 xassert (s
->face
&& s
->face
->gc
);
4767 return glyph
- s
->row
->glyphs
[s
->area
];
4771 /* Fill glyph string S from image glyph S->first_glyph. */
4774 x_fill_image_glyph_string (s
)
4775 struct glyph_string
*s
;
4777 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4778 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4780 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4781 s
->font
= s
->face
->font
;
4782 s
->width
= s
->first_glyph
->pixel_width
;
4784 /* Adjust base line for subscript/superscript text. */
4785 s
->ybase
+= s
->first_glyph
->voffset
;
4789 /* Fill glyph string S from a sequence of stretch glyphs.
4791 ROW is the glyph row in which the glyphs are found, AREA is the
4792 area within the row. START is the index of the first glyph to
4793 consider, END is the index of the last + 1.
4795 Value is the index of the first glyph not in S. */
4798 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4799 struct glyph_string
*s
;
4800 struct glyph_row
*row
;
4801 enum glyph_row_area area
;
4804 struct glyph
*glyph
, *last
;
4805 int voffset
, face_id
;
4807 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4809 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4810 last
= s
->row
->glyphs
[s
->area
] + end
;
4811 face_id
= glyph
->face_id
;
4812 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4813 s
->font
= s
->face
->font
;
4814 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4815 s
->width
= glyph
->pixel_width
;
4816 voffset
= glyph
->voffset
;
4820 && glyph
->type
== STRETCH_GLYPH
4821 && glyph
->voffset
== voffset
4822 && glyph
->face_id
== face_id
);
4824 s
->width
+= glyph
->pixel_width
;
4826 /* Adjust base line for subscript/superscript text. */
4827 s
->ybase
+= voffset
;
4829 /* The case that face->gc == 0 is handled when drawing the glyph
4830 string by calling PREPARE_FACE_FOR_DISPLAY. */
4832 return glyph
- s
->row
->glyphs
[s
->area
];
4836 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4837 of XChar2b structures for S; it can't be allocated in
4838 x_init_glyph_string because it must be allocated via `alloca'. W
4839 is the window on which S is drawn. ROW and AREA are the glyph row
4840 and area within the row from which S is constructed. START is the
4841 index of the first glyph structure covered by S. HL is a
4842 face-override for drawing S. */
4845 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4846 struct glyph_string
*s
;
4849 struct glyph_row
*row
;
4850 enum glyph_row_area area
;
4852 enum draw_glyphs_face hl
;
4854 bzero (s
, sizeof *s
);
4856 s
->f
= XFRAME (w
->frame
);
4857 s
->display
= FRAME_X_DISPLAY (s
->f
);
4858 s
->window
= FRAME_X_WINDOW (s
->f
);
4863 s
->first_glyph
= row
->glyphs
[area
] + start
;
4864 s
->height
= row
->height
;
4865 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4867 /* Display the internal border below the tool-bar window. */
4868 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4869 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4871 s
->ybase
= s
->y
+ row
->ascent
;
4875 /* Set background width of glyph string S. START is the index of the
4876 first glyph following S. LAST_X is the right-most x-position + 1
4877 in the drawing area. */
4880 x_set_glyph_string_background_width (s
, start
, last_x
)
4881 struct glyph_string
*s
;
4885 /* If the face of this glyph string has to be drawn to the end of
4886 the drawing area, set S->extends_to_end_of_line_p. */
4887 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4889 if (start
== s
->row
->used
[s
->area
]
4890 && s
->area
== TEXT_AREA
4891 && ((s
->hl
== DRAW_NORMAL_TEXT
4892 && (s
->row
->fill_line_p
4893 || s
->face
->background
!= default_face
->background
4894 || s
->face
->stipple
!= default_face
->stipple
4895 || s
->row
->mouse_face_p
))
4896 || s
->hl
== DRAW_MOUSE_FACE
4897 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4898 && s
->row
->fill_line_p
)))
4899 s
->extends_to_end_of_line_p
= 1;
4901 /* If S extends its face to the end of the line, set its
4902 background_width to the distance to the right edge of the drawing
4904 if (s
->extends_to_end_of_line_p
)
4905 s
->background_width
= last_x
- s
->x
+ 1;
4907 s
->background_width
= s
->width
;
4911 /* Add a glyph string for a stretch glyph to the list of strings
4912 between HEAD and TAIL. START is the index of the stretch glyph in
4913 row area AREA of glyph row ROW. END is the index of the last glyph
4914 in that glyph row area. X is the current output position assigned
4915 to the new glyph string constructed. HL overrides that face of the
4916 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4917 is the right-most x-position of the drawing area. */
4919 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4920 and below -- keep them on one line. */
4921 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4924 s = (struct glyph_string *) alloca (sizeof *s); \
4925 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4926 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4927 x_append_glyph_string (&HEAD, &TAIL, s); \
4933 /* Add a glyph string for an image glyph to the list of strings
4934 between HEAD and TAIL. START is the index of the image glyph in
4935 row area AREA of glyph row ROW. END is the index of the last glyph
4936 in that glyph row area. X is the current output position assigned
4937 to the new glyph string constructed. HL overrides that face of the
4938 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4939 is the right-most x-position of the drawing area. */
4941 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4944 s = (struct glyph_string *) alloca (sizeof *s); \
4945 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4946 x_fill_image_glyph_string (s); \
4947 x_append_glyph_string (&HEAD, &TAIL, s); \
4954 /* Add a glyph string for a sequence of character glyphs to the list
4955 of strings between HEAD and TAIL. START is the index of the first
4956 glyph in row area AREA of glyph row ROW that is part of the new
4957 glyph string. END is the index of the last glyph in that glyph row
4958 area. X is the current output position assigned to the new glyph
4959 string constructed. HL overrides that face of the glyph; e.g. it
4960 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4961 right-most x-position of the drawing area. */
4963 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4969 c = (ROW)->glyphs[AREA][START].u.ch; \
4970 face_id = (ROW)->glyphs[AREA][START].face_id; \
4972 s = (struct glyph_string *) alloca (sizeof *s); \
4973 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4974 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4975 x_append_glyph_string (&HEAD, &TAIL, s); \
4977 START = x_fill_glyph_string (s, face_id, START, END, \
4983 /* Add a glyph string for a composite sequence to the list of strings
4984 between HEAD and TAIL. START is the index of the first glyph in
4985 row area AREA of glyph row ROW that is part of the new glyph
4986 string. END is the index of the last glyph in that glyph row area.
4987 X is the current output position assigned to the new glyph string
4988 constructed. HL overrides that face of the glyph; e.g. it is
4989 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4990 x-position of the drawing area. */
4992 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4994 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4995 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4996 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4997 struct composition *cmp = composition_table[cmp_id]; \
4998 int glyph_len = cmp->glyph_len; \
5000 struct face **faces; \
5001 struct glyph_string *first_s = NULL; \
5004 base_face = base_face->ascii_face; \
5005 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5006 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5007 /* At first, fill in `char2b' and `faces'. */ \
5008 for (n = 0; n < glyph_len; n++) \
5010 int c = COMPOSITION_GLYPH (cmp, n); \
5011 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5012 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5013 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5014 this_face_id, char2b + n, 1, 1); \
5017 /* Make glyph_strings for each glyph sequence that is drawable by \
5018 the same face, and append them to HEAD/TAIL. */ \
5019 for (n = 0; n < cmp->glyph_len;) \
5021 s = (struct glyph_string *) alloca (sizeof *s); \
5022 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5023 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5031 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5039 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5040 of AREA of glyph row ROW on window W between indices START and END.
5041 HL overrides the face for drawing glyph strings, e.g. it is
5042 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5043 x-positions of the drawing area.
5045 This is an ugly monster macro construct because we must use alloca
5046 to allocate glyph strings (because x_draw_glyphs can be called
5049 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5052 HEAD = TAIL = NULL; \
5053 while (START < END) \
5055 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5056 switch (first_glyph->type) \
5059 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5060 TAIL, HL, X, LAST_X, \
5064 case COMPOSITE_GLYPH: \
5065 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5066 HEAD, TAIL, HL, X, LAST_X,\
5070 case STRETCH_GLYPH: \
5071 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5072 HEAD, TAIL, HL, X, LAST_X); \
5076 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5077 TAIL, HL, X, LAST_X); \
5084 x_set_glyph_string_background_width (s, START, LAST_X); \
5091 /* Draw glyphs between START and END in AREA of ROW on window W,
5092 starting at x-position X. X is relative to AREA in W. HL is a
5093 face-override with the following meaning:
5095 DRAW_NORMAL_TEXT draw normally
5096 DRAW_CURSOR draw in cursor face
5097 DRAW_MOUSE_FACE draw in mouse face.
5098 DRAW_INVERSE_VIDEO draw in mode line face
5099 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5100 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5102 If OVERLAPS_P is non-zero, draw only the foreground of characters
5103 and clip to the physical height of ROW.
5105 Value is the x-position reached, relative to AREA of W. */
5108 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5111 struct glyph_row
*row
;
5112 enum glyph_row_area area
;
5114 enum draw_glyphs_face hl
;
5117 struct glyph_string
*head
, *tail
;
5118 struct glyph_string
*s
;
5119 int last_x
, area_width
;
5123 /* Let's rather be paranoid than getting a SEGV. */
5124 end
= min (end
, row
->used
[area
]);
5125 start
= max (0, start
);
5126 start
= min (end
, start
);
5128 /* Translate X to frame coordinates. Set last_x to the right
5129 end of the drawing area. */
5130 if (row
->full_width_p
)
5132 /* X is relative to the left edge of W, without scroll bars
5134 struct frame
*f
= XFRAME (w
->frame
);
5135 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5138 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5139 last_x
= window_left_x
+ area_width
;
5141 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5143 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5144 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5150 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5151 last_x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5155 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5156 area_width
= window_box_width (w
, area
);
5157 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5160 /* Build a doubly-linked list of glyph_string structures between
5161 head and tail from what we have to draw. Note that the macro
5162 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5163 the reason we use a separate variable `i'. */
5165 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5168 x_reached
= tail
->x
+ tail
->background_width
;
5172 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5173 the row, redraw some glyphs in front or following the glyph
5174 strings built above. */
5175 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5178 struct glyph_string
*h
, *t
;
5180 /* Compute overhangs for all glyph strings. */
5181 for (s
= head
; s
; s
= s
->next
)
5182 x_compute_glyph_string_overhangs (s
);
5184 /* Prepend glyph strings for glyphs in front of the first glyph
5185 string that are overwritten because of the first glyph
5186 string's left overhang. The background of all strings
5187 prepended must be drawn because the first glyph string
5189 i
= x_left_overwritten (head
);
5193 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5194 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5197 x_compute_overhangs_and_x (t
, head
->x
, 1);
5198 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5201 /* Prepend glyph strings for glyphs in front of the first glyph
5202 string that overwrite that glyph string because of their
5203 right overhang. For these strings, only the foreground must
5204 be drawn, because it draws over the glyph string at `head'.
5205 The background must not be drawn because this would overwrite
5206 right overhangs of preceding glyphs for which no glyph
5208 i
= x_left_overwriting (head
);
5211 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5212 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5214 for (s
= h
; s
; s
= s
->next
)
5215 s
->background_filled_p
= 1;
5216 x_compute_overhangs_and_x (t
, head
->x
, 1);
5217 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5220 /* Append glyphs strings for glyphs following the last glyph
5221 string tail that are overwritten by tail. The background of
5222 these strings has to be drawn because tail's foreground draws
5224 i
= x_right_overwritten (tail
);
5227 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5228 DRAW_NORMAL_TEXT
, x
, last_x
,
5230 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5231 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5234 /* Append glyph strings for glyphs following the last glyph
5235 string tail that overwrite tail. The foreground of such
5236 glyphs has to be drawn because it writes into the background
5237 of tail. The background must not be drawn because it could
5238 paint over the foreground of following glyphs. */
5239 i
= x_right_overwriting (tail
);
5242 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5243 DRAW_NORMAL_TEXT
, x
, last_x
,
5245 for (s
= h
; s
; s
= s
->next
)
5246 s
->background_filled_p
= 1;
5247 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5248 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5252 /* Draw all strings. */
5253 for (s
= head
; s
; s
= s
->next
)
5254 x_draw_glyph_string (s
);
5256 if (area
== TEXT_AREA
5257 && !row
->full_width_p
5258 /* When drawing overlapping rows, only the glyph strings'
5259 foreground is drawn, which doesn't erase a cursor
5263 int x0
= head
? head
->x
: x
;
5264 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5266 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5267 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5269 if (XFASTINT (w
->left_margin_width
) != 0)
5271 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5272 x0
-= left_area_width
;
5273 x1
-= left_area_width
;
5276 notice_overwritten_cursor (w
, area
, x0
, x1
,
5277 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5280 /* Value is the x-position up to which drawn, relative to AREA of W.
5281 This doesn't include parts drawn because of overhangs. */
5282 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5283 if (!row
->full_width_p
)
5285 if (area
> LEFT_MARGIN_AREA
&& XFASTINT (w
->left_margin_width
) != 0)
5286 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5287 if (area
> TEXT_AREA
)
5288 x_reached
-= window_box_width (w
, TEXT_AREA
);
5295 /* Fix the display of area AREA of overlapping row ROW in window W. */
5298 x_fix_overlapping_area (w
, row
, area
)
5300 struct glyph_row
*row
;
5301 enum glyph_row_area area
;
5307 if (area
== LEFT_MARGIN_AREA
)
5309 else if (area
== TEXT_AREA
)
5310 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5312 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5313 + window_box_width (w
, TEXT_AREA
));
5315 for (i
= 0; i
< row
->used
[area
];)
5317 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5319 int start
= i
, start_x
= x
;
5323 x
+= row
->glyphs
[area
][i
].pixel_width
;
5326 while (i
< row
->used
[area
]
5327 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5329 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5330 DRAW_NORMAL_TEXT
, 1);
5334 x
+= row
->glyphs
[area
][i
].pixel_width
;
5343 /* Output LEN glyphs starting at START at the nominal cursor position.
5344 Advance the nominal cursor over the text. The global variable
5345 updated_window contains the window being updated, updated_row is
5346 the glyph row being updated, and updated_area is the area of that
5347 row being updated. */
5350 x_write_glyphs (start
, len
)
5351 struct glyph
*start
;
5356 xassert (updated_window
&& updated_row
);
5361 hpos
= start
- updated_row
->glyphs
[updated_area
];
5362 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5363 updated_row
, updated_area
,
5365 DRAW_NORMAL_TEXT
, 0);
5367 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
5368 if (updated_area
== TEXT_AREA
5369 && updated_window
->phys_cursor_on_p
5370 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
5371 && updated_window
->phys_cursor
.hpos
>= hpos
5372 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
5373 updated_window
->phys_cursor_on_p
= 0;
5377 /* Advance the output cursor. */
5378 output_cursor
.hpos
+= len
;
5379 output_cursor
.x
= x
;
5383 /* Insert LEN glyphs from START at the nominal cursor position. */
5386 x_insert_glyphs (start
, len
)
5387 struct glyph
*start
;
5392 int line_height
, shift_by_width
, shifted_region_width
;
5393 struct glyph_row
*row
;
5394 struct glyph
*glyph
;
5395 int frame_x
, frame_y
, hpos
;
5397 xassert (updated_window
&& updated_row
);
5400 f
= XFRAME (WINDOW_FRAME (w
));
5402 /* Get the height of the line we are in. */
5404 line_height
= row
->height
;
5406 /* Get the width of the glyphs to insert. */
5408 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5409 shift_by_width
+= glyph
->pixel_width
;
5411 /* Get the width of the region to shift right. */
5412 shifted_region_width
= (window_box_width (w
, updated_area
)
5417 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5418 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5419 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5420 f
->output_data
.x
->normal_gc
,
5422 shifted_region_width
, line_height
,
5423 frame_x
+ shift_by_width
, frame_y
);
5425 /* Write the glyphs. */
5426 hpos
= start
- row
->glyphs
[updated_area
];
5427 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5428 DRAW_NORMAL_TEXT
, 0);
5430 /* Advance the output cursor. */
5431 output_cursor
.hpos
+= len
;
5432 output_cursor
.x
+= shift_by_width
;
5437 /* Delete N glyphs at the nominal cursor position. Not implemented
5448 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
5449 If they are <= 0, this is probably an error. */
5452 x_clear_area (dpy
, window
, x
, y
, width
, height
, exposures
)
5459 xassert (width
> 0 && height
> 0);
5460 XClearArea (dpy
, window
, x
, y
, width
, height
, exposures
);
5464 /* Erase the current text line from the nominal cursor position
5465 (inclusive) to pixel column TO_X (exclusive). The idea is that
5466 everything from TO_X onward is already erased.
5468 TO_X is a pixel position relative to updated_area of
5469 updated_window. TO_X == -1 means clear to the end of this area. */
5472 x_clear_end_of_line (to_x
)
5476 struct window
*w
= updated_window
;
5477 int max_x
, min_y
, max_y
;
5478 int from_x
, from_y
, to_y
;
5480 xassert (updated_window
&& updated_row
);
5481 f
= XFRAME (w
->frame
);
5483 if (updated_row
->full_width_p
)
5485 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5486 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5487 && !w
->pseudo_window_p
)
5488 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5491 max_x
= window_box_width (w
, updated_area
);
5492 max_y
= window_text_bottom_y (w
);
5494 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5495 of window. For TO_X > 0, truncate to end of drawing area. */
5501 to_x
= min (to_x
, max_x
);
5503 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5505 /* Notice if the cursor will be cleared by this operation. */
5506 if (!updated_row
->full_width_p
)
5507 notice_overwritten_cursor (w
, updated_area
,
5508 output_cursor
.x
, -1,
5510 MATRIX_ROW_BOTTOM_Y (updated_row
));
5512 from_x
= output_cursor
.x
;
5514 /* Translate to frame coordinates. */
5515 if (updated_row
->full_width_p
)
5517 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5518 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5522 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5523 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5526 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5527 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5528 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5530 /* Prevent inadvertently clearing to end of the X window. */
5531 if (to_x
> from_x
&& to_y
> from_y
)
5534 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5535 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5542 /* Clear entire frame. If updating_frame is non-null, clear that
5543 frame. Otherwise clear the selected frame. */
5553 f
= SELECTED_FRAME ();
5555 /* Clearing the frame will erase any cursor, so mark them all as no
5557 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5558 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5559 output_cursor
.x
= -1;
5561 /* We don't set the output cursor here because there will always
5562 follow an explicit cursor_to. */
5564 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5566 /* We have to clear the scroll bars, too. If we have changed
5567 colors or something like that, then they should be notified. */
5568 x_scroll_bar_clear (f
);
5570 XFlush (FRAME_X_DISPLAY (f
));
5576 /* Invert the middle quarter of the frame for .15 sec. */
5578 /* We use the select system call to do the waiting, so we have to make
5579 sure it's available. If it isn't, we just won't do visual bells. */
5581 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5584 /* Subtract the `struct timeval' values X and Y, storing the result in
5585 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5588 timeval_subtract (result
, x
, y
)
5589 struct timeval
*result
, x
, y
;
5591 /* Perform the carry for the later subtraction by updating y. This
5592 is safer because on some systems the tv_sec member is unsigned. */
5593 if (x
.tv_usec
< y
.tv_usec
)
5595 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5596 y
.tv_usec
-= 1000000 * nsec
;
5600 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5602 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5603 y
.tv_usec
+= 1000000 * nsec
;
5607 /* Compute the time remaining to wait. tv_usec is certainly
5609 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5610 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5612 /* Return indication of whether the result should be considered
5614 return x
.tv_sec
< y
.tv_sec
;
5626 /* Create a GC that will use the GXxor function to flip foreground
5627 pixels into background pixels. */
5631 values
.function
= GXxor
;
5632 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5633 ^ f
->output_data
.x
->background_pixel
);
5635 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5636 GCFunction
| GCForeground
, &values
);
5640 /* Get the height not including a menu bar widget. */
5641 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5642 /* Height of each line to flash. */
5643 int flash_height
= FRAME_LINE_HEIGHT (f
);
5644 /* These will be the left and right margins of the rectangles. */
5645 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5646 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5650 /* Don't flash the area between a scroll bar and the frame
5651 edge it is next to. */
5652 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5654 case vertical_scroll_bar_left
:
5655 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5658 case vertical_scroll_bar_right
:
5659 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5666 width
= flash_right
- flash_left
;
5668 /* If window is tall, flash top and bottom line. */
5669 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5671 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5673 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5674 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5675 width
, flash_height
);
5676 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5678 (height
- flash_height
5679 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5680 width
, flash_height
);
5683 /* If it is short, flash it all. */
5684 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5685 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5686 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5691 struct timeval wakeup
;
5693 EMACS_GET_TIME (wakeup
);
5695 /* Compute time to wait until, propagating carry from usecs. */
5696 wakeup
.tv_usec
+= 150000;
5697 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5698 wakeup
.tv_usec
%= 1000000;
5700 /* Keep waiting until past the time wakeup or any input gets
5702 while (! detect_input_pending ())
5704 struct timeval current
;
5705 struct timeval timeout
;
5707 EMACS_GET_TIME (current
);
5709 /* Break if result would be negative. */
5710 if (timeval_subtract (¤t
, wakeup
, current
))
5713 /* How long `select' should wait. */
5715 timeout
.tv_usec
= 10000;
5717 /* Try to wait that long--but we might wake up sooner. */
5718 select (0, NULL
, NULL
, NULL
, &timeout
);
5722 /* If window is tall, flash top and bottom line. */
5723 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5725 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5727 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5728 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5729 width
, flash_height
);
5730 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5732 (height
- flash_height
5733 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5734 width
, flash_height
);
5737 /* If it is short, flash it all. */
5738 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5739 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5740 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5742 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5750 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5753 /* Make audible bell. */
5758 struct frame
*f
= SELECTED_FRAME ();
5760 if (FRAME_X_DISPLAY (f
))
5762 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5769 XBell (FRAME_X_DISPLAY (f
), 0);
5770 XFlush (FRAME_X_DISPLAY (f
));
5777 /* Specify how many text lines, from the top of the window,
5778 should be affected by insert-lines and delete-lines operations.
5779 This, and those operations, are used only within an update
5780 that is bounded by calls to x_update_begin and x_update_end. */
5783 XTset_terminal_window (n
)
5786 /* This function intentionally left blank. */
5791 /***********************************************************************
5793 ***********************************************************************/
5795 /* Perform an insert-lines or delete-lines operation, inserting N
5796 lines or deleting -N lines at vertical position VPOS. */
5799 x_ins_del_lines (vpos
, n
)
5806 /* Scroll part of the display as described by RUN. */
5809 x_scroll_run (w
, run
)
5813 struct frame
*f
= XFRAME (w
->frame
);
5814 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5816 /* Get frame-relative bounding box of the text display area of W,
5817 without mode lines. Include in this box the left and right
5819 window_box (w
, -1, &x
, &y
, &width
, &height
);
5820 width
+= FRAME_X_FRINGE_WIDTH (f
);
5821 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5823 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5824 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5825 bottom_y
= y
+ height
;
5829 /* Scrolling up. Make sure we don't copy part of the mode
5830 line at the bottom. */
5831 if (from_y
+ run
->height
> bottom_y
)
5832 height
= bottom_y
- from_y
;
5834 height
= run
->height
;
5838 /* Scolling down. Make sure we don't copy over the mode line.
5840 if (to_y
+ run
->height
> bottom_y
)
5841 height
= bottom_y
- to_y
;
5843 height
= run
->height
;
5848 /* Cursor off. Will be switched on again in x_update_window_end. */
5852 XCopyArea (FRAME_X_DISPLAY (f
),
5853 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5854 f
->output_data
.x
->normal_gc
,
5864 /***********************************************************************
5866 ***********************************************************************/
5868 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5869 corner of the exposed rectangle. W and H are width and height of
5870 the exposed area. All are pixel values. W or H zero means redraw
5871 the entire frame. */
5874 expose_frame (f
, x
, y
, w
, h
)
5879 int mouse_face_overwritten_p
= 0;
5881 TRACE ((stderr
, "expose_frame "));
5883 /* No need to redraw if frame will be redrawn soon. */
5884 if (FRAME_GARBAGED_P (f
))
5886 TRACE ((stderr
, " garbaged\n"));
5890 /* If basic faces haven't been realized yet, there is no point in
5891 trying to redraw anything. This can happen when we get an expose
5892 event while Emacs is starting, e.g. by moving another window. */
5893 if (FRAME_FACE_CACHE (f
) == NULL
5894 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5896 TRACE ((stderr
, " no faces\n"));
5900 if (w
== 0 || h
== 0)
5903 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5904 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5914 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5915 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5917 if (WINDOWP (f
->tool_bar_window
))
5918 mouse_face_overwritten_p
5919 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5921 #ifndef USE_X_TOOLKIT
5922 if (WINDOWP (f
->menu_bar_window
))
5923 mouse_face_overwritten_p
5924 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
5925 #endif /* not USE_X_TOOLKIT */
5927 /* Some window managers support a focus-follows-mouse style with
5928 delayed raising of frames. Imagine a partially obscured frame,
5929 and moving the mouse into partially obscured mouse-face on that
5930 frame. The visible part of the mouse-face will be highlighted,
5931 then the WM raises the obscured frame. With at least one WM, KDE
5932 2.1, Emacs is not getting any event for the raising of the frame
5933 (even tried with SubstructureRedirectMask), only Expose events.
5934 These expose events will draw text normally, i.e. not
5935 highlighted. Which means we must redo the highlight here.
5936 Subsume it under ``we love X''. --gerd 2001-08-15 */
5937 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5939 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5940 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5942 int x
= dpyinfo
->mouse_face_mouse_x
;
5943 int y
= dpyinfo
->mouse_face_mouse_y
;
5944 clear_mouse_face (dpyinfo
);
5945 note_mouse_highlight (f
, x
, y
);
5951 /* Redraw (parts) of all windows in the window tree rooted at W that
5952 intersect R. R contains frame pixel coordinates. Value is
5953 non-zero if the exposure overwrites mouse-face. */
5956 expose_window_tree (w
, r
)
5960 struct frame
*f
= XFRAME (w
->frame
);
5961 int mouse_face_overwritten_p
= 0;
5963 while (w
&& !FRAME_GARBAGED_P (f
))
5965 if (!NILP (w
->hchild
))
5966 mouse_face_overwritten_p
5967 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5968 else if (!NILP (w
->vchild
))
5969 mouse_face_overwritten_p
5970 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5972 mouse_face_overwritten_p
|= expose_window (w
, r
);
5974 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5977 return mouse_face_overwritten_p
;
5981 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5982 which intersects rectangle R. R is in window-relative coordinates. */
5985 expose_area (w
, row
, r
, area
)
5987 struct glyph_row
*row
;
5989 enum glyph_row_area area
;
5991 struct glyph
*first
= row
->glyphs
[area
];
5992 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5994 int first_x
, start_x
, x
;
5996 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5997 /* If row extends face to end of line write the whole line. */
5998 x_draw_glyphs (w
, 0, row
, area
, 0, row
->used
[area
],
5999 DRAW_NORMAL_TEXT
, 0);
6002 /* Set START_X to the window-relative start position for drawing glyphs of
6003 AREA. The first glyph of the text area can be partially visible.
6004 The first glyphs of other areas cannot. */
6005 if (area
== LEFT_MARGIN_AREA
)
6007 else if (area
== TEXT_AREA
)
6008 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6010 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6011 + window_box_width (w
, TEXT_AREA
));
6014 /* Find the first glyph that must be redrawn. */
6016 && x
+ first
->pixel_width
< r
->x
)
6018 x
+= first
->pixel_width
;
6022 /* Find the last one. */
6026 && x
< r
->x
+ r
->width
)
6028 x
+= last
->pixel_width
;
6034 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6035 first
- row
->glyphs
[area
],
6036 last
- row
->glyphs
[area
],
6037 DRAW_NORMAL_TEXT
, 0);
6042 /* Redraw the parts of the glyph row ROW on window W intersecting
6043 rectangle R. R is in window-relative coordinates. Value is
6044 non-zero if mouse-face was overwritten. */
6047 expose_line (w
, row
, r
)
6049 struct glyph_row
*row
;
6052 xassert (row
->enabled_p
);
6054 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6055 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6056 DRAW_NORMAL_TEXT
, 0);
6059 if (row
->used
[LEFT_MARGIN_AREA
])
6060 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6061 if (row
->used
[TEXT_AREA
])
6062 expose_area (w
, row
, r
, TEXT_AREA
);
6063 if (row
->used
[RIGHT_MARGIN_AREA
])
6064 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6065 x_draw_row_fringe_bitmaps (w
, row
);
6068 return row
->mouse_face_p
;
6072 /* Return non-zero if W's cursor intersects rectangle R. */
6075 x_phys_cursor_in_rect_p (w
, r
)
6079 XRectangle cr
, result
;
6080 struct glyph
*cursor_glyph
;
6082 cursor_glyph
= get_phys_cursor_glyph (w
);
6085 cr
.x
= w
->phys_cursor
.x
;
6086 cr
.y
= w
->phys_cursor
.y
;
6087 cr
.width
= cursor_glyph
->pixel_width
;
6088 cr
.height
= w
->phys_cursor_height
;
6089 return x_intersect_rectangles (&cr
, r
, &result
);
6096 /* Redraw those parts of glyphs rows during expose event handling that
6097 overlap other rows. Redrawing of an exposed line writes over parts
6098 of lines overlapping that exposed line; this function fixes that.
6100 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
6101 row in W's current matrix that is exposed and overlaps other rows.
6102 LAST_OVERLAPPING_ROW is the last such row. */
6105 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
6107 struct glyph_row
*first_overlapping_row
;
6108 struct glyph_row
*last_overlapping_row
;
6110 struct glyph_row
*row
;
6112 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
6113 if (row
->overlapping_p
)
6115 xassert (row
->enabled_p
&& !row
->mode_line_p
);
6117 if (row
->used
[LEFT_MARGIN_AREA
])
6118 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
6120 if (row
->used
[TEXT_AREA
])
6121 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
6123 if (row
->used
[RIGHT_MARGIN_AREA
])
6124 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
6129 /* Redraw the part of window W intersection rectangle FR. Pixel
6130 coordinates in FR are frame-relative. Call this function with
6131 input blocked. Value is non-zero if the exposure overwrites
6135 expose_window (w
, fr
)
6139 struct frame
*f
= XFRAME (w
->frame
);
6141 int mouse_face_overwritten_p
= 0;
6143 /* If window is not yet fully initialized, do nothing. This can
6144 happen when toolkit scroll bars are used and a window is split.
6145 Reconfiguring the scroll bar will generate an expose for a newly
6147 if (w
->current_matrix
== NULL
)
6150 /* When we're currently updating the window, display and current
6151 matrix usually don't agree. Arrange for a thorough display
6153 if (w
== updated_window
)
6155 SET_FRAME_GARBAGED (f
);
6159 /* Frame-relative pixel rectangle of W. */
6160 wr
.x
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6161 wr
.y
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6162 wr
.width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6163 wr
.height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6165 if (x_intersect_rectangles (fr
, &wr
, &r
))
6167 int yb
= window_text_bottom_y (w
);
6168 struct glyph_row
*row
;
6169 int cursor_cleared_p
;
6170 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
6172 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6173 r
.x
, r
.y
, r
.width
, r
.height
));
6175 /* Convert to window coordinates. */
6176 r
.x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.x
);
6177 r
.y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.y
);
6179 /* Turn off the cursor. */
6180 if (!w
->pseudo_window_p
6181 && x_phys_cursor_in_rect_p (w
, &r
))
6184 cursor_cleared_p
= 1;
6187 cursor_cleared_p
= 0;
6189 /* Update lines intersecting rectangle R. */
6190 first_overlapping_row
= last_overlapping_row
= NULL
;
6191 for (row
= w
->current_matrix
->rows
;
6196 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6198 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
6199 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
6200 || (r
.y
>= y0
&& r
.y
< y1
)
6201 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
6203 if (row
->overlapping_p
)
6205 if (first_overlapping_row
== NULL
)
6206 first_overlapping_row
= row
;
6207 last_overlapping_row
= row
;
6210 if (expose_line (w
, row
, &r
))
6211 mouse_face_overwritten_p
= 1;
6218 /* Display the mode line if there is one. */
6219 if (WINDOW_WANTS_MODELINE_P (w
)
6220 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6222 && row
->y
< r
.y
+ r
.height
)
6224 if (expose_line (w
, row
, &r
))
6225 mouse_face_overwritten_p
= 1;
6228 if (!w
->pseudo_window_p
)
6230 /* Fix the display of overlapping rows. */
6231 if (first_overlapping_row
)
6232 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
6234 /* Draw border between windows. */
6235 x_draw_vertical_border (w
);
6237 /* Turn the cursor on again. */
6238 if (cursor_cleared_p
)
6239 x_update_window_cursor (w
, 1);
6243 return mouse_face_overwritten_p
;
6247 /* Determine the intersection of two rectangles R1 and R2. Return
6248 the intersection in *RESULT. Value is non-zero if RESULT is not
6252 x_intersect_rectangles (r1
, r2
, result
)
6253 XRectangle
*r1
, *r2
, *result
;
6255 XRectangle
*left
, *right
;
6256 XRectangle
*upper
, *lower
;
6257 int intersection_p
= 0;
6259 /* Rearrange so that R1 is the left-most rectangle. */
6261 left
= r1
, right
= r2
;
6263 left
= r2
, right
= r1
;
6265 /* X0 of the intersection is right.x0, if this is inside R1,
6266 otherwise there is no intersection. */
6267 if (right
->x
<= left
->x
+ left
->width
)
6269 result
->x
= right
->x
;
6271 /* The right end of the intersection is the minimum of the
6272 the right ends of left and right. */
6273 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
6276 /* Same game for Y. */
6278 upper
= r1
, lower
= r2
;
6280 upper
= r2
, lower
= r1
;
6282 /* The upper end of the intersection is lower.y0, if this is inside
6283 of upper. Otherwise, there is no intersection. */
6284 if (lower
->y
<= upper
->y
+ upper
->height
)
6286 result
->y
= lower
->y
;
6288 /* The lower end of the intersection is the minimum of the lower
6289 ends of upper and lower. */
6290 result
->height
= (min (lower
->y
+ lower
->height
,
6291 upper
->y
+ upper
->height
)
6297 return intersection_p
;
6308 /* We used to only do this if Vx_no_window_manager was non-nil, but
6309 the ICCCM (section 4.1.6) says that the window's border pixmap
6310 and border pixel are window attributes which are "private to the
6311 client", so we can always change it to whatever we want. */
6313 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6314 f
->output_data
.x
->border_pixel
);
6316 x_update_cursor (f
, 1);
6320 frame_unhighlight (f
)
6323 /* We used to only do this if Vx_no_window_manager was non-nil, but
6324 the ICCCM (section 4.1.6) says that the window's border pixmap
6325 and border pixel are window attributes which are "private to the
6326 client", so we can always change it to whatever we want. */
6328 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6329 f
->output_data
.x
->border_tile
);
6331 x_update_cursor (f
, 1);
6334 /* The focus has changed. Update the frames as necessary to reflect
6335 the new situation. Note that we can't change the selected frame
6336 here, because the Lisp code we are interrupting might become confused.
6337 Each event gets marked with the frame in which it occurred, so the
6338 Lisp code can tell when the switch took place by examining the events. */
6341 x_new_focus_frame (dpyinfo
, frame
)
6342 struct x_display_info
*dpyinfo
;
6343 struct frame
*frame
;
6345 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6347 if (frame
!= dpyinfo
->x_focus_frame
)
6349 /* Set this before calling other routines, so that they see
6350 the correct value of x_focus_frame. */
6351 dpyinfo
->x_focus_frame
= frame
;
6353 if (old_focus
&& old_focus
->auto_lower
)
6354 x_lower_frame (old_focus
);
6357 selected_frame
= frame
;
6358 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6360 Fselect_window (selected_frame
->selected_window
);
6361 choose_minibuf_frame ();
6364 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6365 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6367 pending_autoraise_frame
= 0;
6370 x_frame_rehighlight (dpyinfo
);
6373 /* Handle FocusIn and FocusOut state changes for FRAME.
6374 If FRAME has focus and there exists more than one frame, puts
6375 a FOCUS_IN_EVENT into BUFP.
6376 Returns number of events inserted into BUFP. */
6379 x_focus_changed (type
, state
, dpyinfo
, frame
, bufp
, numchars
)
6382 struct x_display_info
*dpyinfo
;
6383 struct frame
*frame
;
6384 struct input_event
*bufp
;
6389 if (type
== FocusIn
)
6391 if (dpyinfo
->x_focus_event_frame
!= frame
)
6393 x_new_focus_frame (dpyinfo
, frame
);
6394 dpyinfo
->x_focus_event_frame
= frame
;
6396 /* Don't stop displaying the initial startup message
6397 for a switch-frame event we don't need. */
6399 && GC_NILP (Vterminal_frame
)
6400 && GC_CONSP (Vframe_list
)
6401 && !GC_NILP (XCDR (Vframe_list
)))
6403 bufp
->kind
= FOCUS_IN_EVENT
;
6404 XSETFRAME (bufp
->frame_or_window
, frame
);
6412 frame
->output_data
.x
->focus_state
|= state
;
6415 if (FRAME_XIC (frame
))
6416 XSetICFocus (FRAME_XIC (frame
));
6419 else if (type
== FocusOut
)
6421 frame
->output_data
.x
->focus_state
&= ~state
;
6423 if (dpyinfo
->x_focus_event_frame
== frame
)
6425 dpyinfo
->x_focus_event_frame
= 0;
6426 x_new_focus_frame (dpyinfo
, 0);
6430 if (FRAME_XIC (frame
))
6431 XUnsetICFocus (FRAME_XIC (frame
));
6438 /* The focus may have changed. Figure out if it is a real focus change,
6439 by checking both FocusIn/Out and Enter/LeaveNotify events.
6441 Returns number of events inserted into BUFP. */
6444 x_detect_focus_change (dpyinfo
, event
, bufp
, numchars
)
6445 struct x_display_info
*dpyinfo
;
6447 struct input_event
*bufp
;
6450 struct frame
*frame
;
6453 frame
= x_top_window_to_frame (dpyinfo
, event
->xany
.window
);
6454 if (! frame
) return nr_events
;
6456 switch (event
->type
)
6460 if (event
->xcrossing
.detail
!= NotifyInferior
6461 && event
->xcrossing
.focus
6462 && ! (frame
->output_data
.x
->focus_state
& FOCUS_EXPLICIT
))
6463 nr_events
= x_focus_changed ((event
->type
== EnterNotify
6464 ? FocusIn
: FocusOut
),
6474 nr_events
= x_focus_changed (event
->type
,
6475 (event
->xfocus
.detail
== NotifyPointer
6476 ? FOCUS_IMPLICIT
: FOCUS_EXPLICIT
),
6488 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6491 x_mouse_leave (dpyinfo
)
6492 struct x_display_info
*dpyinfo
;
6494 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6497 /* The focus has changed, or we have redirected a frame's focus to
6498 another frame (this happens when a frame uses a surrogate
6499 mini-buffer frame). Shift the highlight as appropriate.
6501 The FRAME argument doesn't necessarily have anything to do with which
6502 frame is being highlighted or un-highlighted; we only use it to find
6503 the appropriate X display info. */
6506 XTframe_rehighlight (frame
)
6507 struct frame
*frame
;
6509 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6513 x_frame_rehighlight (dpyinfo
)
6514 struct x_display_info
*dpyinfo
;
6516 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6518 if (dpyinfo
->x_focus_frame
)
6520 dpyinfo
->x_highlight_frame
6521 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6522 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6523 : dpyinfo
->x_focus_frame
);
6524 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6526 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6527 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6531 dpyinfo
->x_highlight_frame
= 0;
6533 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6536 frame_unhighlight (old_highlight
);
6537 if (dpyinfo
->x_highlight_frame
)
6538 frame_highlight (dpyinfo
->x_highlight_frame
);
6544 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6546 /* Initialize mode_switch_bit and modifier_meaning. */
6548 x_find_modifier_meanings (dpyinfo
)
6549 struct x_display_info
*dpyinfo
;
6551 int min_code
, max_code
;
6554 XModifierKeymap
*mods
;
6556 dpyinfo
->meta_mod_mask
= 0;
6557 dpyinfo
->shift_lock_mask
= 0;
6558 dpyinfo
->alt_mod_mask
= 0;
6559 dpyinfo
->super_mod_mask
= 0;
6560 dpyinfo
->hyper_mod_mask
= 0;
6563 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6565 min_code
= dpyinfo
->display
->min_keycode
;
6566 max_code
= dpyinfo
->display
->max_keycode
;
6569 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6570 min_code
, max_code
- min_code
+ 1,
6572 mods
= XGetModifierMapping (dpyinfo
->display
);
6574 /* Scan the modifier table to see which modifier bits the Meta and
6575 Alt keysyms are on. */
6577 int row
, col
; /* The row and column in the modifier table. */
6579 for (row
= 3; row
< 8; row
++)
6580 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6583 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6585 /* Zeroes are used for filler. Skip them. */
6589 /* Are any of this keycode's keysyms a meta key? */
6593 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6595 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6601 dpyinfo
->meta_mod_mask
|= (1 << row
);
6606 dpyinfo
->alt_mod_mask
|= (1 << row
);
6611 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6616 dpyinfo
->super_mod_mask
|= (1 << row
);
6620 /* Ignore this if it's not on the lock modifier. */
6621 if ((1 << row
) == LockMask
)
6622 dpyinfo
->shift_lock_mask
= LockMask
;
6630 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6631 if (! dpyinfo
->meta_mod_mask
)
6633 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6634 dpyinfo
->alt_mod_mask
= 0;
6637 /* If some keys are both alt and meta,
6638 make them just meta, not alt. */
6639 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6641 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6644 XFree ((char *) syms
);
6645 XFreeModifiermap (mods
);
6648 /* Convert between the modifier bits X uses and the modifier bits
6652 x_x_to_emacs_modifiers (dpyinfo
, state
)
6653 struct x_display_info
*dpyinfo
;
6656 EMACS_UINT mod_meta
= meta_modifier
;
6657 EMACS_UINT mod_alt
= alt_modifier
;
6658 EMACS_UINT mod_hyper
= hyper_modifier
;
6659 EMACS_UINT mod_super
= super_modifier
;
6662 tem
= Fget (Vx_alt_keysym
, Qmodifier_value
);
6663 if (! EQ (tem
, Qnil
)) mod_alt
= XUINT (tem
);
6664 tem
= Fget (Vx_meta_keysym
, Qmodifier_value
);
6665 if (! EQ (tem
, Qnil
)) mod_meta
= XUINT (tem
);
6666 tem
= Fget (Vx_hyper_keysym
, Qmodifier_value
);
6667 if (! EQ (tem
, Qnil
)) mod_hyper
= XUINT (tem
);
6668 tem
= Fget (Vx_super_keysym
, Qmodifier_value
);
6669 if (! EQ (tem
, Qnil
)) mod_super
= XUINT (tem
);
6672 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6673 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6674 | ((state
& dpyinfo
->meta_mod_mask
) ? mod_meta
: 0)
6675 | ((state
& dpyinfo
->alt_mod_mask
) ? mod_alt
: 0)
6676 | ((state
& dpyinfo
->super_mod_mask
) ? mod_super
: 0)
6677 | ((state
& dpyinfo
->hyper_mod_mask
) ? mod_hyper
: 0));
6681 x_emacs_to_x_modifiers (dpyinfo
, state
)
6682 struct x_display_info
*dpyinfo
;
6685 EMACS_UINT mod_meta
= meta_modifier
;
6686 EMACS_UINT mod_alt
= alt_modifier
;
6687 EMACS_UINT mod_hyper
= hyper_modifier
;
6688 EMACS_UINT mod_super
= super_modifier
;
6692 tem
= Fget (Vx_alt_keysym
, Qmodifier_value
);
6693 if (! EQ (tem
, Qnil
)) mod_alt
= XUINT (tem
);
6694 tem
= Fget (Vx_meta_keysym
, Qmodifier_value
);
6695 if (! EQ (tem
, Qnil
)) mod_meta
= XUINT (tem
);
6696 tem
= Fget (Vx_hyper_keysym
, Qmodifier_value
);
6697 if (! EQ (tem
, Qnil
)) mod_hyper
= XUINT (tem
);
6698 tem
= Fget (Vx_super_keysym
, Qmodifier_value
);
6699 if (! EQ (tem
, Qnil
)) mod_super
= XUINT (tem
);
6702 return ( ((state
& mod_alt
) ? dpyinfo
->alt_mod_mask
: 0)
6703 | ((state
& mod_super
) ? dpyinfo
->super_mod_mask
: 0)
6704 | ((state
& mod_hyper
) ? dpyinfo
->hyper_mod_mask
: 0)
6705 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6706 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6707 | ((state
& mod_meta
) ? dpyinfo
->meta_mod_mask
: 0));
6710 /* Convert a keysym to its name. */
6713 x_get_keysym_name (keysym
)
6719 value
= XKeysymToString (keysym
);
6727 /* Mouse clicks and mouse movement. Rah. */
6729 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6730 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6731 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6732 not force the value into range. */
6735 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6737 register int pix_x
, pix_y
;
6738 register int *x
, *y
;
6742 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6743 even for negative values. */
6745 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6747 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6749 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6750 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6754 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6755 bounds
->height
= f
->output_data
.x
->line_height
;
6756 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6757 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6764 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6765 pix_x
= FRAME_WINDOW_WIDTH (f
);
6769 else if (pix_y
> f
->height
)
6778 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6779 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6780 can't tell the positions because W's display is not up to date,
6784 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6787 int *frame_x
, *frame_y
;
6791 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6792 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6794 if (display_completed
)
6796 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6797 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6798 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6804 *frame_x
+= glyph
->pixel_width
;
6812 *frame_y
= *frame_x
= 0;
6816 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6817 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6822 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6824 If the event is a button press, then note that we have grabbed
6828 construct_mouse_click (result
, event
, f
)
6829 struct input_event
*result
;
6830 XButtonEvent
*event
;
6833 /* Make the event type NO_EVENT; we'll change that when we decide
6835 result
->kind
= MOUSE_CLICK_EVENT
;
6836 result
->code
= event
->button
- Button1
;
6837 result
->timestamp
= event
->time
;
6838 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6840 | (event
->type
== ButtonRelease
6844 XSETINT (result
->x
, event
->x
);
6845 XSETINT (result
->y
, event
->y
);
6846 XSETFRAME (result
->frame_or_window
, f
);
6852 /* Function to report a mouse movement to the mainstream Emacs code.
6853 The input handler calls this.
6855 We have received a mouse movement event, which is given in *event.
6856 If the mouse is over a different glyph than it was last time, tell
6857 the mainstream emacs code by setting mouse_moved. If not, ask for
6858 another motion event, so we can check again the next time it moves. */
6860 static XMotionEvent last_mouse_motion_event
;
6861 static Lisp_Object last_mouse_motion_frame
;
6864 note_mouse_movement (frame
, event
)
6866 XMotionEvent
*event
;
6868 last_mouse_movement_time
= event
->time
;
6869 last_mouse_motion_event
= *event
;
6870 XSETFRAME (last_mouse_motion_frame
, frame
);
6872 if (event
->window
!= FRAME_X_WINDOW (frame
))
6874 frame
->mouse_moved
= 1;
6875 last_mouse_scroll_bar
= Qnil
;
6876 note_mouse_highlight (frame
, -1, -1);
6879 /* Has the mouse moved off the glyph it was on at the last sighting? */
6880 else if (event
->x
< last_mouse_glyph
.x
6881 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6882 || event
->y
< last_mouse_glyph
.y
6883 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6885 frame
->mouse_moved
= 1;
6886 last_mouse_scroll_bar
= Qnil
;
6887 note_mouse_highlight (frame
, event
->x
, event
->y
);
6892 /************************************************************************
6894 ************************************************************************/
6896 /* Find the glyph under window-relative coordinates X/Y in window W.
6897 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6898 strings. Return in *HPOS and *VPOS the row and column number of
6899 the glyph found. Return in *AREA the glyph area containing X.
6900 Value is a pointer to the glyph found or null if X/Y is not on
6901 text, or we can't tell because W's current matrix is not up to
6904 static struct glyph
*
6905 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6908 int *hpos
, *vpos
, *area
;
6911 struct glyph
*glyph
, *end
;
6912 struct glyph_row
*row
= NULL
;
6913 int x0
, i
, left_area_width
;
6915 /* Find row containing Y. Give up if some row is not enabled. */
6916 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6918 row
= MATRIX_ROW (w
->current_matrix
, i
);
6919 if (!row
->enabled_p
)
6921 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6928 /* Give up if Y is not in the window. */
6929 if (i
== w
->current_matrix
->nrows
)
6932 /* Get the glyph area containing X. */
6933 if (w
->pseudo_window_p
)
6940 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6941 if (x
< left_area_width
)
6943 *area
= LEFT_MARGIN_AREA
;
6946 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6949 x0
= row
->x
+ left_area_width
;
6953 *area
= RIGHT_MARGIN_AREA
;
6954 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6958 /* Find glyph containing X. */
6959 glyph
= row
->glyphs
[*area
];
6960 end
= glyph
+ row
->used
[*area
];
6963 if (x
< x0
+ glyph
->pixel_width
)
6965 if (w
->pseudo_window_p
)
6967 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6971 x0
+= glyph
->pixel_width
;
6978 *hpos
= glyph
- row
->glyphs
[*area
];
6983 /* Convert frame-relative x/y to coordinates relative to window W.
6984 Takes pseudo-windows into account. */
6987 frame_to_window_pixel_xy (w
, x
, y
)
6991 if (w
->pseudo_window_p
)
6993 /* A pseudo-window is always full-width, and starts at the
6994 left edge of the frame, plus a frame border. */
6995 struct frame
*f
= XFRAME (w
->frame
);
6996 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6997 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
7001 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
7002 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
7007 /* Take proper action when mouse has moved to the mode or header line
7008 or marginal area of window W, x-position X and y-position Y. Area
7009 is 1, 3, 6 or 7 for the mode line, header line, left and right
7010 marginal area respectively. X is relative to the start of the text
7011 display area of W, so the width of bitmap areas and scroll bars
7012 must be subtracted to get a position relative to the start of the
7016 note_mode_line_or_margin_highlight (w
, x
, y
, portion
)
7020 struct frame
*f
= XFRAME (w
->frame
);
7021 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7022 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
7024 Lisp_Object string
, help
, map
, pos
;
7026 if (portion
== 1 || portion
== 3)
7027 string
= mode_line_string (w
, x
, y
, portion
== 1, &charpos
);
7029 string
= marginal_area_string (w
, x
, y
, portion
, &charpos
);
7031 if (STRINGP (string
))
7033 pos
= make_number (charpos
);
7035 /* If we're on a string with `help-echo' text property, arrange
7036 for the help to be displayed. This is done by setting the
7037 global variable help_echo to the help string. */
7038 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
7042 XSETWINDOW (help_echo_window
, w
);
7043 help_echo_object
= string
;
7044 help_echo_pos
= charpos
;
7047 /* Change the mouse pointer according to what is under X/Y. */
7048 map
= Fget_text_property (pos
, Qlocal_map
, string
);
7050 map
= Fget_text_property (pos
, Qkeymap
, string
);
7052 cursor
= f
->output_data
.x
->nontext_cursor
;
7055 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7059 /* Take proper action when the mouse has moved to position X, Y on
7060 frame F as regards highlighting characters that have mouse-face
7061 properties. Also de-highlighting chars where the mouse was before.
7062 X and Y can be negative or out of range. */
7065 note_mouse_highlight (f
, x
, y
)
7069 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7073 Cursor cursor
= None
;
7076 /* When a menu is active, don't highlight because this looks odd. */
7077 #ifdef USE_X_TOOLKIT
7078 if (popup_activated ())
7082 if (NILP (Vmouse_highlight
)
7083 || !f
->glyphs_initialized_p
)
7086 dpyinfo
->mouse_face_mouse_x
= x
;
7087 dpyinfo
->mouse_face_mouse_y
= y
;
7088 dpyinfo
->mouse_face_mouse_frame
= f
;
7090 if (dpyinfo
->mouse_face_defer
)
7095 dpyinfo
->mouse_face_deferred_gc
= 1;
7099 /* Which window is that in? */
7100 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7102 /* If we were displaying active text in another window, clear that. */
7103 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7104 clear_mouse_face (dpyinfo
);
7106 /* Not on a window -> return. */
7107 if (!WINDOWP (window
))
7110 /* Convert to window-relative pixel coordinates. */
7111 w
= XWINDOW (window
);
7112 frame_to_window_pixel_xy (w
, &x
, &y
);
7114 /* Handle tool-bar window differently since it doesn't display a
7116 if (EQ (window
, f
->tool_bar_window
))
7118 note_tool_bar_highlight (f
, x
, y
);
7122 /* Mouse is on the mode, header line or margin? */
7123 if (portion
== 1 || portion
== 3 || portion
== 6 || portion
== 7)
7125 note_mode_line_or_margin_highlight (w
, x
, y
, portion
);
7130 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7132 cursor
= f
->output_data
.x
->text_cursor
;
7134 /* Are we in a window whose display is up to date?
7135 And verify the buffer's text has not changed. */
7136 b
= XBUFFER (w
->buffer
);
7137 if (/* Within text portion of the window. */
7139 && EQ (w
->window_end_valid
, w
->buffer
)
7140 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7141 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7143 int hpos
, vpos
, pos
, i
, area
;
7144 struct glyph
*glyph
;
7146 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7147 Lisp_Object
*overlay_vec
= NULL
;
7149 struct buffer
*obuf
;
7150 int obegv
, ozv
, same_region
;
7152 /* Find the glyph under X/Y. */
7153 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7155 /* Clear mouse face if X/Y not over text. */
7157 || area
!= TEXT_AREA
7158 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7160 if (clear_mouse_face (dpyinfo
))
7165 pos
= glyph
->charpos
;
7166 object
= glyph
->object
;
7167 if (!STRINGP (object
) && !BUFFERP (object
))
7170 /* If we get an out-of-range value, return now; avoid an error. */
7171 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7174 /* Make the window's buffer temporarily current for
7175 overlays_at and compute_char_face. */
7176 obuf
= current_buffer
;
7183 /* Is this char mouse-active or does it have help-echo? */
7184 position
= make_number (pos
);
7186 if (BUFFERP (object
))
7188 /* Put all the overlays we want in a vector in overlay_vec.
7189 Store the length in len. If there are more than 10, make
7190 enough space for all, and try again. */
7192 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7193 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7194 if (noverlays
> len
)
7197 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7198 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7201 /* Sort overlays into increasing priority order. */
7202 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7207 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7208 && vpos
>= dpyinfo
->mouse_face_beg_row
7209 && vpos
<= dpyinfo
->mouse_face_end_row
7210 && (vpos
> dpyinfo
->mouse_face_beg_row
7211 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7212 && (vpos
< dpyinfo
->mouse_face_end_row
7213 || hpos
< dpyinfo
->mouse_face_end_col
7214 || dpyinfo
->mouse_face_past_end
));
7219 /* Check mouse-face highlighting. */
7221 /* If there exists an overlay with mouse-face overlapping
7222 the one we are currently highlighting, we have to
7223 check if we enter the overlapping overlay, and then
7224 highlight only that. */
7225 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7226 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7228 /* Find the highest priority overlay that has a mouse-face
7231 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7233 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7234 if (!NILP (mouse_face
))
7235 overlay
= overlay_vec
[i
];
7238 /* If we're actually highlighting the same overlay as
7239 before, there's no need to do that again. */
7241 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7242 goto check_help_echo
;
7244 dpyinfo
->mouse_face_overlay
= overlay
;
7246 /* Clear the display of the old active region, if any. */
7247 if (clear_mouse_face (dpyinfo
))
7250 /* If no overlay applies, get a text property. */
7252 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7254 /* Handle the overlay case. */
7255 if (!NILP (overlay
))
7257 /* Find the range of text around this char that
7258 should be active. */
7259 Lisp_Object before
, after
;
7262 before
= Foverlay_start (overlay
);
7263 after
= Foverlay_end (overlay
);
7264 /* Record this as the current active region. */
7265 fast_find_position (w
, XFASTINT (before
),
7266 &dpyinfo
->mouse_face_beg_col
,
7267 &dpyinfo
->mouse_face_beg_row
,
7268 &dpyinfo
->mouse_face_beg_x
,
7269 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7271 dpyinfo
->mouse_face_past_end
7272 = !fast_find_position (w
, XFASTINT (after
),
7273 &dpyinfo
->mouse_face_end_col
,
7274 &dpyinfo
->mouse_face_end_row
,
7275 &dpyinfo
->mouse_face_end_x
,
7276 &dpyinfo
->mouse_face_end_y
, Qnil
);
7277 dpyinfo
->mouse_face_window
= window
;
7278 dpyinfo
->mouse_face_face_id
7279 = face_at_buffer_position (w
, pos
, 0, 0,
7281 !dpyinfo
->mouse_face_hidden
);
7283 /* Display it as active. */
7284 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7287 /* Handle the text property case. */
7288 else if (!NILP (mouse_face
) && BUFFERP (object
))
7290 /* Find the range of text around this char that
7291 should be active. */
7292 Lisp_Object before
, after
, beginning
, end
;
7295 beginning
= Fmarker_position (w
->start
);
7296 end
= make_number (BUF_Z (XBUFFER (object
))
7297 - XFASTINT (w
->window_end_pos
));
7299 = Fprevious_single_property_change (make_number (pos
+ 1),
7303 = Fnext_single_property_change (position
, Qmouse_face
,
7306 /* Record this as the current active region. */
7307 fast_find_position (w
, XFASTINT (before
),
7308 &dpyinfo
->mouse_face_beg_col
,
7309 &dpyinfo
->mouse_face_beg_row
,
7310 &dpyinfo
->mouse_face_beg_x
,
7311 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7312 dpyinfo
->mouse_face_past_end
7313 = !fast_find_position (w
, XFASTINT (after
),
7314 &dpyinfo
->mouse_face_end_col
,
7315 &dpyinfo
->mouse_face_end_row
,
7316 &dpyinfo
->mouse_face_end_x
,
7317 &dpyinfo
->mouse_face_end_y
, Qnil
);
7318 dpyinfo
->mouse_face_window
= window
;
7320 if (BUFFERP (object
))
7321 dpyinfo
->mouse_face_face_id
7322 = face_at_buffer_position (w
, pos
, 0, 0,
7324 !dpyinfo
->mouse_face_hidden
);
7326 /* Display it as active. */
7327 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7330 else if (!NILP (mouse_face
) && STRINGP (object
))
7335 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7338 e
= Fnext_single_property_change (position
, Qmouse_face
,
7341 b
= make_number (0);
7343 e
= make_number (SCHARS (object
) - 1);
7344 fast_find_string_pos (w
, XINT (b
), object
,
7345 &dpyinfo
->mouse_face_beg_col
,
7346 &dpyinfo
->mouse_face_beg_row
,
7347 &dpyinfo
->mouse_face_beg_x
,
7348 &dpyinfo
->mouse_face_beg_y
, 0);
7349 fast_find_string_pos (w
, XINT (e
), object
,
7350 &dpyinfo
->mouse_face_end_col
,
7351 &dpyinfo
->mouse_face_end_row
,
7352 &dpyinfo
->mouse_face_end_x
,
7353 &dpyinfo
->mouse_face_end_y
, 1);
7354 dpyinfo
->mouse_face_past_end
= 0;
7355 dpyinfo
->mouse_face_window
= window
;
7356 dpyinfo
->mouse_face_face_id
7357 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7359 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7362 else if (STRINGP (object
) && NILP (mouse_face
))
7364 /* A string which doesn't have mouse-face, but
7365 the text ``under'' it might have. */
7366 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7367 int start
= MATRIX_ROW_START_CHARPOS (r
);
7369 pos
= string_buffer_position (w
, object
, start
);
7371 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7375 if (!NILP (mouse_face
) && !NILP (overlay
))
7377 Lisp_Object before
= Foverlay_start (overlay
);
7378 Lisp_Object after
= Foverlay_end (overlay
);
7381 /* Note that we might not be able to find position
7382 BEFORE in the glyph matrix if the overlay is
7383 entirely covered by a `display' property. In
7384 this case, we overshoot. So let's stop in
7385 the glyph matrix before glyphs for OBJECT. */
7386 fast_find_position (w
, XFASTINT (before
),
7387 &dpyinfo
->mouse_face_beg_col
,
7388 &dpyinfo
->mouse_face_beg_row
,
7389 &dpyinfo
->mouse_face_beg_x
,
7390 &dpyinfo
->mouse_face_beg_y
,
7393 dpyinfo
->mouse_face_past_end
7394 = !fast_find_position (w
, XFASTINT (after
),
7395 &dpyinfo
->mouse_face_end_col
,
7396 &dpyinfo
->mouse_face_end_row
,
7397 &dpyinfo
->mouse_face_end_x
,
7398 &dpyinfo
->mouse_face_end_y
,
7400 dpyinfo
->mouse_face_window
= window
;
7401 dpyinfo
->mouse_face_face_id
7402 = face_at_buffer_position (w
, pos
, 0, 0,
7404 !dpyinfo
->mouse_face_hidden
);
7406 /* Display it as active. */
7407 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7415 /* Look for a `help-echo' property. */
7417 Lisp_Object help
, overlay
;
7419 /* Check overlays first. */
7420 help
= overlay
= Qnil
;
7421 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7423 overlay
= overlay_vec
[i
];
7424 help
= Foverlay_get (overlay
, Qhelp_echo
);
7430 help_echo_window
= window
;
7431 help_echo_object
= overlay
;
7432 help_echo_pos
= pos
;
7436 Lisp_Object object
= glyph
->object
;
7437 int charpos
= glyph
->charpos
;
7439 /* Try text properties. */
7440 if (STRINGP (object
)
7442 && charpos
< SCHARS (object
))
7444 help
= Fget_text_property (make_number (charpos
),
7445 Qhelp_echo
, object
);
7448 /* If the string itself doesn't specify a help-echo,
7449 see if the buffer text ``under'' it does. */
7451 = MATRIX_ROW (w
->current_matrix
, vpos
);
7452 int start
= MATRIX_ROW_START_CHARPOS (r
);
7453 int pos
= string_buffer_position (w
, object
, start
);
7456 help
= Fget_char_property (make_number (pos
),
7457 Qhelp_echo
, w
->buffer
);
7466 else if (BUFFERP (object
)
7469 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7475 help_echo_window
= window
;
7476 help_echo_object
= object
;
7477 help_echo_pos
= charpos
;
7484 current_buffer
= obuf
;
7490 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7494 redo_mouse_highlight ()
7496 if (!NILP (last_mouse_motion_frame
)
7497 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7498 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7499 last_mouse_motion_event
.x
,
7500 last_mouse_motion_event
.y
);
7505 /***********************************************************************
7507 ***********************************************************************/
7509 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7510 struct glyph
**, int *, int *, int *));
7512 /* Tool-bar item index of the item on which a mouse button was pressed
7515 static int last_tool_bar_item
;
7518 /* Get information about the tool-bar item at position X/Y on frame F.
7519 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7520 the current matrix of the tool-bar window of F, or NULL if not
7521 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7522 item in F->tool_bar_items. Value is
7524 -1 if X/Y is not on a tool-bar item
7525 0 if X/Y is on the same item that was highlighted before.
7529 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7532 struct glyph
**glyph
;
7533 int *hpos
, *vpos
, *prop_idx
;
7535 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7536 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7539 /* Find the glyph under X/Y. */
7540 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7544 /* Get the start of this tool-bar item's properties in
7545 f->tool_bar_items. */
7546 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7549 /* Is mouse on the highlighted item? */
7550 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7551 && *vpos
>= dpyinfo
->mouse_face_beg_row
7552 && *vpos
<= dpyinfo
->mouse_face_end_row
7553 && (*vpos
> dpyinfo
->mouse_face_beg_row
7554 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7555 && (*vpos
< dpyinfo
->mouse_face_end_row
7556 || *hpos
< dpyinfo
->mouse_face_end_col
7557 || dpyinfo
->mouse_face_past_end
))
7564 /* Handle mouse button event on the tool-bar of frame F, at
7565 frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress
7569 x_handle_tool_bar_click (f
, button_event
)
7571 XButtonEvent
*button_event
;
7573 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7574 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7575 int hpos
, vpos
, prop_idx
;
7576 struct glyph
*glyph
;
7577 Lisp_Object enabled_p
;
7578 int x
= button_event
->x
;
7579 int y
= button_event
->y
;
7581 /* If not on the highlighted tool-bar item, return. */
7582 frame_to_window_pixel_xy (w
, &x
, &y
);
7583 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7586 /* If item is disabled, do nothing. */
7587 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7588 if (NILP (enabled_p
))
7591 if (button_event
->type
== ButtonPress
)
7593 /* Show item in pressed state. */
7594 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7595 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7596 last_tool_bar_item
= prop_idx
;
7600 Lisp_Object key
, frame
;
7601 struct input_event event
;
7603 /* Show item in released state. */
7604 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7605 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7607 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7609 XSETFRAME (frame
, f
);
7610 event
.kind
= TOOL_BAR_EVENT
;
7611 event
.frame_or_window
= frame
;
7613 kbd_buffer_store_event (&event
);
7615 event
.kind
= TOOL_BAR_EVENT
;
7616 event
.frame_or_window
= frame
;
7618 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7619 button_event
->state
);
7620 kbd_buffer_store_event (&event
);
7621 last_tool_bar_item
= -1;
7626 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7627 tool-bar window-relative coordinates X/Y. Called from
7628 note_mouse_highlight. */
7631 note_tool_bar_highlight (f
, x
, y
)
7635 Lisp_Object window
= f
->tool_bar_window
;
7636 struct window
*w
= XWINDOW (window
);
7637 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7639 struct glyph
*glyph
;
7640 struct glyph_row
*row
;
7642 Lisp_Object enabled_p
;
7644 enum draw_glyphs_face draw
;
7645 int mouse_down_p
, rc
;
7647 /* Function note_mouse_highlight is called with negative x(y
7648 values when mouse moves outside of the frame. */
7649 if (x
<= 0 || y
<= 0)
7651 clear_mouse_face (dpyinfo
);
7655 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7658 /* Not on tool-bar item. */
7659 clear_mouse_face (dpyinfo
);
7665 clear_mouse_face (dpyinfo
);
7667 /* Mouse is down, but on different tool-bar item? */
7668 mouse_down_p
= (dpyinfo
->grabbed
7669 && f
== last_mouse_frame
7670 && FRAME_LIVE_P (f
));
7672 && last_tool_bar_item
!= prop_idx
)
7675 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7676 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7678 /* If tool-bar item is not enabled, don't highlight it. */
7679 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7680 if (!NILP (enabled_p
))
7682 /* Compute the x-position of the glyph. In front and past the
7683 image is a space. We include this is the highlighted area. */
7684 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7685 for (i
= x
= 0; i
< hpos
; ++i
)
7686 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7688 /* Record this as the current active region. */
7689 dpyinfo
->mouse_face_beg_col
= hpos
;
7690 dpyinfo
->mouse_face_beg_row
= vpos
;
7691 dpyinfo
->mouse_face_beg_x
= x
;
7692 dpyinfo
->mouse_face_beg_y
= row
->y
;
7693 dpyinfo
->mouse_face_past_end
= 0;
7695 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7696 dpyinfo
->mouse_face_end_row
= vpos
;
7697 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7698 dpyinfo
->mouse_face_end_y
= row
->y
;
7699 dpyinfo
->mouse_face_window
= window
;
7700 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7702 /* Display it as active. */
7703 show_mouse_face (dpyinfo
, draw
);
7704 dpyinfo
->mouse_face_image_state
= draw
;
7709 /* Set help_echo to a help string to display for this tool-bar item.
7710 XTread_socket does the rest. */
7711 help_echo_object
= help_echo_window
= Qnil
;
7713 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7714 if (NILP (help_echo
))
7715 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7720 /* Find the glyph matrix position of buffer position CHARPOS in window
7721 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7722 current glyphs must be up to date. If CHARPOS is above window
7723 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7724 of last line in W. In the row containing CHARPOS, stop before glyphs
7725 having STOP as object. */
7727 #if 0 /* This is a version of fast_find_position that's more correct
7728 in the presence of hscrolling, for example. I didn't install
7729 it right away because the problem fixed is minor, it failed
7730 in 20.x as well, and I think it's too risky to install
7731 so near the release of 21.1. 2001-09-25 gerd. */
7734 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7737 int *hpos
, *vpos
, *x
, *y
;
7740 struct glyph_row
*row
, *first
;
7741 struct glyph
*glyph
, *end
;
7742 int i
, past_end
= 0;
7744 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7745 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7748 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7750 *x
= *y
= *hpos
= *vpos
= 0;
7755 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7762 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7764 glyph
= row
->glyphs
[TEXT_AREA
];
7765 end
= glyph
+ row
->used
[TEXT_AREA
];
7767 /* Skip over glyphs not having an object at the start of the row.
7768 These are special glyphs like truncation marks on terminal
7770 if (row
->displays_text_p
)
7772 && INTEGERP (glyph
->object
)
7773 && !EQ (stop
, glyph
->object
)
7774 && glyph
->charpos
< 0)
7776 *x
+= glyph
->pixel_width
;
7781 && !INTEGERP (glyph
->object
)
7782 && !EQ (stop
, glyph
->object
)
7783 && (!BUFFERP (glyph
->object
)
7784 || glyph
->charpos
< charpos
))
7786 *x
+= glyph
->pixel_width
;
7790 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7797 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7800 int *hpos
, *vpos
, *x
, *y
;
7805 int maybe_next_line_p
= 0;
7806 int line_start_position
;
7807 int yb
= window_text_bottom_y (w
);
7808 struct glyph_row
*row
, *best_row
;
7809 int row_vpos
, best_row_vpos
;
7812 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7813 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7817 if (row
->used
[TEXT_AREA
])
7818 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7820 line_start_position
= 0;
7822 if (line_start_position
> pos
)
7824 /* If the position sought is the end of the buffer,
7825 don't include the blank lines at the bottom of the window. */
7826 else if (line_start_position
== pos
7827 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7829 maybe_next_line_p
= 1;
7832 else if (line_start_position
> 0)
7835 best_row_vpos
= row_vpos
;
7838 if (row
->y
+ row
->height
>= yb
)
7845 /* Find the right column within BEST_ROW. */
7847 current_x
= best_row
->x
;
7848 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7850 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7851 int charpos
= glyph
->charpos
;
7853 if (BUFFERP (glyph
->object
))
7858 *vpos
= best_row_vpos
;
7863 else if (charpos
> pos
)
7866 else if (EQ (glyph
->object
, stop
))
7871 current_x
+= glyph
->pixel_width
;
7874 /* If we're looking for the end of the buffer,
7875 and we didn't find it in the line we scanned,
7876 use the start of the following line. */
7877 if (maybe_next_line_p
)
7882 current_x
= best_row
->x
;
7885 *vpos
= best_row_vpos
;
7886 *hpos
= lastcol
+ 1;
7895 /* Find the position of the glyph for position POS in OBJECT in
7896 window W's current matrix, and return in *X, *Y the pixel
7897 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
7899 RIGHT_P non-zero means return the position of the right edge of the
7900 glyph, RIGHT_P zero means return the left edge position.
7902 If no glyph for POS exists in the matrix, return the position of
7903 the glyph with the next smaller position that is in the matrix, if
7904 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7905 exists in the matrix, return the position of the glyph with the
7906 next larger position in OBJECT.
7908 Value is non-zero if a glyph was found. */
7911 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7915 int *hpos
, *vpos
, *x
, *y
;
7918 int yb
= window_text_bottom_y (w
);
7919 struct glyph_row
*r
;
7920 struct glyph
*best_glyph
= NULL
;
7921 struct glyph_row
*best_row
= NULL
;
7924 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7925 r
->enabled_p
&& r
->y
< yb
;
7928 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7929 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7932 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7933 if (EQ (g
->object
, object
))
7935 if (g
->charpos
== pos
)
7942 else if (best_glyph
== NULL
7943 || ((abs (g
->charpos
- pos
)
7944 < abs (best_glyph
->charpos
- pos
))
7947 : g
->charpos
> pos
)))
7961 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7965 *x
+= best_glyph
->pixel_width
;
7970 *vpos
= best_row
- w
->current_matrix
->rows
;
7973 return best_glyph
!= NULL
;
7977 /* Display the active region described by mouse_face_*
7978 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7981 show_mouse_face (dpyinfo
, draw
)
7982 struct x_display_info
*dpyinfo
;
7983 enum draw_glyphs_face draw
;
7985 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7986 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7988 if (/* If window is in the process of being destroyed, don't bother
7990 w
->current_matrix
!= NULL
7991 /* Don't update mouse highlight if hidden */
7992 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7993 /* Recognize when we are called to operate on rows that don't exist
7994 anymore. This can happen when a window is split. */
7995 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7997 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7998 struct glyph_row
*row
, *first
, *last
;
8000 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
8001 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
8003 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
8005 int start_hpos
, end_hpos
, start_x
;
8007 /* For all but the first row, the highlight starts at column 0. */
8010 start_hpos
= dpyinfo
->mouse_face_beg_col
;
8011 start_x
= dpyinfo
->mouse_face_beg_x
;
8020 end_hpos
= dpyinfo
->mouse_face_end_col
;
8022 end_hpos
= row
->used
[TEXT_AREA
];
8024 if (end_hpos
> start_hpos
)
8026 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
8027 start_hpos
, end_hpos
, draw
, 0);
8030 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8034 /* When we've written over the cursor, arrange for it to
8035 be displayed again. */
8036 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8037 x_display_cursor (w
, 1,
8038 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8039 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8042 /* Change the mouse cursor. */
8043 if (draw
== DRAW_NORMAL_TEXT
)
8044 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8045 f
->output_data
.x
->text_cursor
);
8046 else if (draw
== DRAW_MOUSE_FACE
)
8047 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8048 f
->output_data
.x
->cross_cursor
);
8050 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8051 f
->output_data
.x
->nontext_cursor
);
8054 /* Clear out the mouse-highlighted active region.
8055 Redraw it un-highlighted first. Value is non-zero if mouse
8056 face was actually drawn unhighlighted. */
8059 clear_mouse_face (dpyinfo
)
8060 struct x_display_info
*dpyinfo
;
8064 if (!NILP (dpyinfo
->mouse_face_window
))
8066 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8070 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8071 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8072 dpyinfo
->mouse_face_window
= Qnil
;
8073 dpyinfo
->mouse_face_overlay
= Qnil
;
8078 /* Clear any mouse-face on window W. This function is part of the
8079 redisplay interface, and is called from try_window_id and similar
8080 functions to ensure the mouse-highlight is off. */
8083 x_clear_mouse_face (w
)
8086 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
8090 XSETWINDOW (window
, w
);
8091 if (EQ (window
, dpyinfo
->mouse_face_window
))
8092 clear_mouse_face (dpyinfo
);
8097 /* Just discard the mouse face information for frame F, if any.
8098 This is used when the size of F is changed. */
8101 cancel_mouse_face (f
)
8105 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8107 window
= dpyinfo
->mouse_face_window
;
8108 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8110 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8111 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8112 dpyinfo
->mouse_face_window
= Qnil
;
8117 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
8120 /* Try to determine frame pixel position and size of the glyph under
8121 frame pixel coordinates X/Y on frame F . Return the position and
8122 size in *RECT. Value is non-zero if we could compute these
8126 glyph_rect (f
, x
, y
, rect
)
8132 int part
, found
= 0;
8134 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8137 struct window
*w
= XWINDOW (window
);
8138 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8139 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8141 frame_to_window_pixel_xy (w
, &x
, &y
);
8143 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
8146 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8147 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8150 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
8153 rect
->width
= g
->pixel_width
;
8154 rect
->height
= r
->height
;
8155 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8156 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8166 /* Return the current position of the mouse.
8167 *FP should be a frame which indicates which display to ask about.
8169 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
8170 and *PART to the frame, window, and scroll bar part that the mouse
8171 is over. Set *X and *Y to the portion and whole of the mouse's
8172 position on the scroll bar.
8174 If the mouse movement started elsewhere, set *FP to the frame the
8175 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
8178 Set *TIME to the server time-stamp for the time at which the mouse
8179 was at this position.
8181 Don't store anything if we don't have a valid set of values to report.
8183 This clears the mouse_moved flag, so we can wait for the next mouse
8187 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8190 Lisp_Object
*bar_window
;
8191 enum scroll_bar_part
*part
;
8193 unsigned long *time
;
8199 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8200 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8206 Window dummy_window
;
8209 Lisp_Object frame
, tail
;
8211 /* Clear the mouse-moved flag for every frame on this display. */
8212 FOR_EACH_FRAME (tail
, frame
)
8213 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
8214 XFRAME (frame
)->mouse_moved
= 0;
8216 last_mouse_scroll_bar
= Qnil
;
8218 /* Figure out which root window we're on. */
8219 XQueryPointer (FRAME_X_DISPLAY (*fp
),
8220 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
8222 /* The root window which contains the pointer. */
8225 /* Trash which we can't trust if the pointer is on
8226 a different screen. */
8229 /* The position on that root window. */
8232 /* More trash we can't trust. */
8235 /* Modifier keys and pointer buttons, about which
8237 (unsigned int *) &dummy
);
8239 /* Now we have a position on the root; find the innermost window
8240 containing the pointer. */
8244 int parent_x
= 0, parent_y
= 0;
8249 /* XTranslateCoordinates can get errors if the window
8250 structure is changing at the same time this function
8251 is running. So at least we must not crash from them. */
8253 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
8255 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
8256 && FRAME_LIVE_P (last_mouse_frame
))
8258 /* If mouse was grabbed on a frame, give coords for that frame
8259 even if the mouse is now outside it. */
8260 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8262 /* From-window, to-window. */
8263 root
, FRAME_X_WINDOW (last_mouse_frame
),
8265 /* From-position, to-position. */
8266 root_x
, root_y
, &win_x
, &win_y
,
8270 f1
= last_mouse_frame
;
8276 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8278 /* From-window, to-window. */
8281 /* From-position, to-position. */
8282 root_x
, root_y
, &win_x
, &win_y
,
8287 if (child
== None
|| child
== win
)
8295 /* Now we know that:
8296 win is the innermost window containing the pointer
8297 (XTC says it has no child containing the pointer),
8298 win_x and win_y are the pointer's position in it
8299 (XTC did this the last time through), and
8300 parent_x and parent_y are the pointer's position in win's parent.
8301 (They are what win_x and win_y were when win was child.
8302 If win is the root window, it has no parent, and
8303 parent_{x,y} are invalid, but that's okay, because we'll
8304 never use them in that case.) */
8306 /* Is win one of our frames? */
8307 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
8309 #ifdef USE_X_TOOLKIT
8310 /* If we end up with the menu bar window, say it's not
8313 && f1
->output_data
.x
->menubar_widget
8314 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
8316 #endif /* USE_X_TOOLKIT */
8319 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
8322 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
8324 /* If not, is it one of our scroll bars? */
8327 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
8331 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8337 if (f1
== 0 && insist
> 0)
8338 f1
= SELECTED_FRAME ();
8342 /* Ok, we found a frame. Store all the values.
8343 last_mouse_glyph is a rectangle used to reduce the
8344 generation of mouse events. To not miss any motion
8345 events, we must divide the frame into rectangles of the
8346 size of the smallest character that could be displayed
8347 on it, i.e. into the same rectangles that matrices on
8348 the frame are divided into. */
8350 int width
, height
, gx
, gy
;
8353 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
8354 last_mouse_glyph
= rect
;
8357 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8358 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8362 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8363 round down even for negative values. */
8368 gx
= (gx
+ width
- 1) / width
* width
;
8369 gy
= (gy
+ height
- 1) / height
* height
;
8371 last_mouse_glyph
.width
= width
;
8372 last_mouse_glyph
.height
= height
;
8373 last_mouse_glyph
.x
= gx
;
8374 last_mouse_glyph
.y
= gy
;
8380 XSETINT (*x
, win_x
);
8381 XSETINT (*y
, win_y
);
8382 *time
= last_mouse_movement_time
;
8391 #ifdef USE_X_TOOLKIT
8393 /* Atimer callback function for TIMER. Called every 0.1s to process
8394 Xt timeouts, if needed. We must avoid calling XtAppPending as
8395 much as possible because that function does an implicit XFlush
8396 that slows us down. */
8399 x_process_timeouts (timer
)
8400 struct atimer
*timer
;
8402 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
8405 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
8406 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
8411 #endif /* USE_X_TOOLKIT */
8414 /* Scroll bar support. */
8416 /* Given an X window ID, find the struct scroll_bar which manages it.
8417 This can be called in GC, so we have to make sure to strip off mark
8420 static struct scroll_bar
*
8421 x_window_to_scroll_bar (window_id
)
8426 for (tail
= Vframe_list
;
8427 XGCTYPE (tail
) == Lisp_Cons
;
8430 Lisp_Object frame
, bar
, condemned
;
8432 frame
= XCAR (tail
);
8433 /* All elements of Vframe_list should be frames. */
8434 if (! GC_FRAMEP (frame
))
8437 /* Scan this frame's scroll bar list for a scroll bar with the
8439 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
8440 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
8441 /* This trick allows us to search both the ordinary and
8442 condemned scroll bar lists with one loop. */
8443 ! GC_NILP (bar
) || (bar
= condemned
,
8446 bar
= XSCROLL_BAR (bar
)->next
)
8447 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
8448 return XSCROLL_BAR (bar
);
8455 #if defined USE_LUCID
8457 /* Return the Lucid menu bar WINDOW is part of. Return null
8458 if WINDOW is not part of a menu bar. */
8461 x_window_to_menu_bar (window
)
8466 for (tail
= Vframe_list
;
8467 XGCTYPE (tail
) == Lisp_Cons
;
8470 Lisp_Object frame
= XCAR (tail
);
8471 Widget menu_bar
= XFRAME (frame
)->output_data
.x
->menubar_widget
;
8473 if (menu_bar
&& xlwmenu_window_p (menu_bar
, window
))
8480 #endif /* USE_LUCID */
8483 /************************************************************************
8485 ************************************************************************/
8487 #ifdef USE_TOOLKIT_SCROLL_BARS
8489 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
8490 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
8491 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
8492 struct scroll_bar
*));
8493 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
8497 /* Id of action hook installed for scroll bars. */
8499 static XtActionHookId action_hook_id
;
8501 /* Lisp window being scrolled. Set when starting to interact with
8502 a toolkit scroll bar, reset to nil when ending the interaction. */
8504 static Lisp_Object window_being_scrolled
;
8506 /* Last scroll bar part sent in xm_scroll_callback. */
8508 static int last_scroll_bar_part
;
8510 /* Whether this is an Xaw with arrow-scrollbars. This should imply
8511 that movements of 1/20 of the screen size are mapped to up/down. */
8513 static Boolean xaw3d_arrow_scroll
;
8515 /* Whether the drag scrolling maintains the mouse at the top of the
8516 thumb. If not, resizing the thumb needs to be done more carefully
8517 to avoid jerkyness. */
8519 static Boolean xaw3d_pick_top
;
8522 /* Action hook installed via XtAppAddActionHook when toolkit scroll
8523 bars are used.. The hook is responsible for detecting when
8524 the user ends an interaction with the scroll bar, and generates
8525 a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so. */
8528 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
8531 XtPointer client_data
;
8535 Cardinal
*num_params
;
8541 scroll_bar_p
= XmIsScrollBar (widget
);
8542 end_action
= "Release";
8543 #else /* !USE_MOTIF i.e. use Xaw */
8544 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
8545 end_action
= "EndScroll";
8546 #endif /* USE_MOTIF */
8549 && strcmp (action_name
, end_action
) == 0
8550 && WINDOWP (window_being_scrolled
))
8554 x_send_scroll_bar_event (window_being_scrolled
,
8555 scroll_bar_end_scroll
, 0, 0);
8556 w
= XWINDOW (window_being_scrolled
);
8557 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
8558 window_being_scrolled
= Qnil
;
8559 last_scroll_bar_part
= -1;
8561 /* Xt timeouts no longer needed. */
8562 toolkit_scroll_bar_interaction
= 0;
8566 /* A vector of windows used for communication between
8567 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
8569 static struct window
**scroll_bar_windows
;
8570 static int scroll_bar_windows_size
;
8573 /* Send a client message with message type Xatom_Scrollbar for a
8574 scroll action to the frame of WINDOW. PART is a value identifying
8575 the part of the scroll bar that was clicked on. PORTION is the
8576 amount to scroll of a whole of WHOLE. */
8579 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8581 int part
, portion
, whole
;
8584 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8585 struct window
*w
= XWINDOW (window
);
8586 struct frame
*f
= XFRAME (w
->frame
);
8591 /* Construct a ClientMessage event to send to the frame. */
8592 ev
->type
= ClientMessage
;
8593 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8594 ev
->display
= FRAME_X_DISPLAY (f
);
8595 ev
->window
= FRAME_X_WINDOW (f
);
8598 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8599 not enough to store a pointer or Lisp_Object on a 64 bit system.
8600 So, store the window in scroll_bar_windows and pass the index
8601 into that array in the event. */
8602 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8603 if (scroll_bar_windows
[i
] == NULL
)
8606 if (i
== scroll_bar_windows_size
)
8608 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8609 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8610 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8612 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8614 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8615 scroll_bar_windows_size
= new_size
;
8618 scroll_bar_windows
[i
] = w
;
8619 ev
->data
.l
[0] = (long) i
;
8620 ev
->data
.l
[1] = (long) part
;
8621 ev
->data
.l
[2] = (long) 0;
8622 ev
->data
.l
[3] = (long) portion
;
8623 ev
->data
.l
[4] = (long) whole
;
8625 /* Make Xt timeouts work while the scroll bar is active. */
8626 toolkit_scroll_bar_interaction
= 1;
8628 /* Setting the event mask to zero means that the message will
8629 be sent to the client that created the window, and if that
8630 window no longer exists, no event will be sent. */
8631 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8636 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8640 x_scroll_bar_to_input_event (event
, ievent
)
8642 struct input_event
*ievent
;
8644 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8649 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8650 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8652 XSETWINDOW (window
, w
);
8653 f
= XFRAME (w
->frame
);
8655 ievent
->kind
= SCROLL_BAR_CLICK_EVENT
;
8656 ievent
->frame_or_window
= window
;
8658 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8659 ievent
->part
= ev
->data
.l
[1];
8660 ievent
->code
= ev
->data
.l
[2];
8661 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8662 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8663 ievent
->modifiers
= 0;
8669 /* Minimum and maximum values used for Motif scroll bars. */
8672 #define XM_SB_MAX 10000000
8673 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8676 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8677 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8678 CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */
8681 xm_scroll_callback (widget
, client_data
, call_data
)
8683 XtPointer client_data
, call_data
;
8685 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8686 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8687 int part
= -1, whole
= 0, portion
= 0;
8691 case XmCR_DECREMENT
:
8692 bar
->dragging
= Qnil
;
8693 part
= scroll_bar_up_arrow
;
8696 case XmCR_INCREMENT
:
8697 bar
->dragging
= Qnil
;
8698 part
= scroll_bar_down_arrow
;
8701 case XmCR_PAGE_DECREMENT
:
8702 bar
->dragging
= Qnil
;
8703 part
= scroll_bar_above_handle
;
8706 case XmCR_PAGE_INCREMENT
:
8707 bar
->dragging
= Qnil
;
8708 part
= scroll_bar_below_handle
;
8712 bar
->dragging
= Qnil
;
8713 part
= scroll_bar_to_top
;
8716 case XmCR_TO_BOTTOM
:
8717 bar
->dragging
= Qnil
;
8718 part
= scroll_bar_to_bottom
;
8724 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8725 && XINT (bar
->dragging
) <= cs
->value
);
8727 /* Get the slider size. */
8729 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8732 whole
= XM_SB_RANGE
- slider_size
;
8733 portion
= min (cs
->value
- XM_SB_MIN
, whole
);
8734 part
= scroll_bar_handle
;
8735 bar
->dragging
= make_number (cs
->value
);
8739 case XmCR_VALUE_CHANGED
:
8745 window_being_scrolled
= bar
->window
;
8746 last_scroll_bar_part
= part
;
8747 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8752 #else /* !USE_MOTIF, i.e. Xaw. */
8755 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8756 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8757 scroll bar struct. CALL_DATA is a pointer to a float saying where
8761 xaw_jump_callback (widget
, client_data
, call_data
)
8763 XtPointer client_data
, call_data
;
8765 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8766 float top
= *(float *) call_data
;
8768 int whole
, portion
, height
;
8771 /* Get the size of the thumb, a value between 0 and 1. */
8773 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8777 portion
= shown
< 1 ? top
* whole
: 0;
8779 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8780 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8781 the bottom, so we force the scrolling whenever we see that we're
8782 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8783 we try to ensure that we always stay two pixels away from the
8785 part
= scroll_bar_down_arrow
;
8787 part
= scroll_bar_handle
;
8789 window_being_scrolled
= bar
->window
;
8790 bar
->dragging
= make_number (portion
);
8791 last_scroll_bar_part
= part
;
8792 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8796 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8797 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8798 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8799 the scroll bar. CALL_DATA is an integer specifying the action that
8800 has taken place. Its magnitude is in the range 0..height of the
8801 scroll bar. Negative values mean scroll towards buffer start.
8802 Values < height of scroll bar mean line-wise movement. */
8805 xaw_scroll_callback (widget
, client_data
, call_data
)
8807 XtPointer client_data
, call_data
;
8809 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8810 /* The position really is stored cast to a pointer. */
8811 int position
= (long) call_data
;
8815 /* Get the height of the scroll bar. */
8817 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8820 if (abs (position
) >= height
)
8821 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8823 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8824 it maps line-movement to call_data = max(5, height/20). */
8825 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8826 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8828 part
= scroll_bar_move_ratio
;
8830 window_being_scrolled
= bar
->window
;
8831 bar
->dragging
= Qnil
;
8832 last_scroll_bar_part
= part
;
8833 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8837 #endif /* not USE_MOTIF */
8840 /* Create the widget for scroll bar BAR on frame F. Record the widget
8841 and X window of the scroll bar in BAR. */
8844 x_create_toolkit_scroll_bar (f
, bar
)
8846 struct scroll_bar
*bar
;
8852 char *scroll_bar_name
= "verticalScrollBar";
8853 unsigned long pixel
;
8858 /* Set resources. Create the widget. */
8859 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8860 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8861 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8862 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8863 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8864 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8865 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8867 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8870 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8874 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8877 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8881 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8882 scroll_bar_name
, av
, ac
);
8884 /* Add one callback for everything that can happen. */
8885 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8887 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8889 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8891 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8893 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8895 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8897 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8900 /* Realize the widget. Only after that is the X window created. */
8901 XtRealizeWidget (widget
);
8903 /* Set the cursor to an arrow. I didn't find a resource to do that.
8904 And I'm wondering why it hasn't an arrow cursor by default. */
8905 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8906 f
->output_data
.x
->nontext_cursor
);
8908 #else /* !USE_MOTIF i.e. use Xaw */
8910 /* Set resources. Create the widget. The background of the
8911 Xaw3d scroll bar widget is a little bit light for my taste.
8912 We don't alter it here to let users change it according
8913 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8914 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8915 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8916 /* For smoother scrolling with Xaw3d -sm */
8917 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8919 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8922 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8926 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8929 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8933 /* Top/bottom shadow colors. */
8935 /* Allocate them, if necessary. */
8936 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1)
8938 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8939 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8940 &pixel
, 1.2, 0x8000))
8942 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= pixel
;
8944 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8946 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8947 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8948 &pixel
, 0.6, 0x4000))
8950 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= pixel
;
8953 /* Tell the toolkit about them. */
8954 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1
8955 || f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8956 /* We tried to allocate a color for the top/bottom shadow, and
8957 failed, so tell Xaw3d to use dithering instead. */
8959 XtSetArg (av
[ac
], XtNbeNiceToColormap
, True
);
8963 /* Tell what colors Xaw3d should use for the top/bottom shadow, to
8964 be more consistent with other emacs 3d colors, and since Xaw3d is
8965 not good at dealing with allocation failure. */
8967 /* This tells Xaw3d to use real colors instead of dithering for
8969 XtSetArg (av
[ac
], XtNbeNiceToColormap
, False
);
8972 /* Specify the colors. */
8973 pixel
= f
->output_data
.x
->scroll_bar_top_shadow_pixel
;
8976 XtSetArg (av
[ac
], "topShadowPixel", pixel
);
8979 pixel
= f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
;
8982 XtSetArg (av
[ac
], "bottomShadowPixel", pixel
);
8987 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8988 f
->output_data
.x
->edit_widget
, av
, ac
);
8992 char *val
= initial
;
8993 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8994 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8996 { /* ARROW_SCROLL */
8997 xaw3d_arrow_scroll
= True
;
8998 /* Isn't that just a personal preference ? -sm */
8999 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
9003 /* Define callbacks. */
9004 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
9005 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
9008 /* Realize the widget. Only after that is the X window created. */
9009 XtRealizeWidget (widget
);
9011 #endif /* !USE_MOTIF */
9013 /* Install an action hook that lets us detect when the user
9014 finishes interacting with a scroll bar. */
9015 if (action_hook_id
== 0)
9016 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
9018 /* Remember X window and widget in the scroll bar vector. */
9019 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
9020 xwindow
= XtWindow (widget
);
9021 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
9027 /* Set the thumb size and position of scroll bar BAR. We are currently
9028 displaying PORTION out of a whole WHOLE, and our position POSITION. */
9031 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
9032 struct scroll_bar
*bar
;
9033 int portion
, position
, whole
;
9035 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9036 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
9043 /* We use an estimate of 30 chars per line rather than the real
9044 `portion' value. This has the disadvantage that the thumb size
9045 is not very representative, but it makes our life a lot easier.
9046 Otherwise, we have to constantly adjust the thumb size, which
9047 we can't always do quickly enough: while dragging, the size of
9048 the thumb might prevent the user from dragging the thumb all the
9049 way to the end. but Motif and some versions of Xaw3d don't allow
9050 updating the thumb size while dragging. Also, even if we can update
9051 its size, the update will often happen too late.
9052 If you don't believe it, check out revision 1.650 of xterm.c to see
9053 what hoops we were going through and the still poor behavior we got. */
9054 portion
= XFASTINT (XWINDOW (bar
->window
)->height
) * 30;
9055 /* When the thumb is at the bottom, position == whole.
9056 So we need to increase `whole' to make space for the thumb. */
9063 top
= (float) position
/ whole
;
9064 shown
= (float) portion
/ whole
;
9067 if (NILP (bar
->dragging
))
9071 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
9072 is the scroll bar's maximum and MIN is the scroll bar's minimum
9074 size
= shown
* XM_SB_RANGE
;
9075 size
= min (size
, XM_SB_RANGE
);
9076 size
= max (size
, 1);
9078 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
9079 value
= top
* XM_SB_RANGE
;
9080 value
= min (value
, XM_SB_MAX
- size
);
9081 value
= max (value
, XM_SB_MIN
);
9083 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
9085 #else /* !USE_MOTIF i.e. use Xaw */
9091 top
= (float) position
/ whole
;
9092 shown
= (float) portion
/ whole
;
9096 float old_top
, old_shown
;
9098 XtVaGetValues (widget
,
9099 XtNtopOfThumb
, &old_top
,
9100 XtNshown
, &old_shown
,
9104 /* Massage the top+shown values. */
9105 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
9106 top
= max (0, min (1, top
));
9109 /* Keep two pixels available for moving the thumb down. */
9110 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
9112 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
9113 check that your system's configuration file contains a define
9114 for `NARROWPROTO'. See s/freebsd.h for an example. */
9115 if (top
!= old_top
|| shown
!= old_shown
)
9117 if (NILP (bar
->dragging
))
9118 XawScrollbarSetThumb (widget
, top
, shown
);
9122 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
9123 int scroll_mode
= 0;
9125 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
9126 if (xaw3d_arrow_scroll
)
9128 /* Xaw3d stupidly ignores resize requests while dragging
9129 so we have to make it believe it's not in dragging mode. */
9130 scroll_mode
= sb
->scrollbar
.scroll_mode
;
9131 if (scroll_mode
== 2)
9132 sb
->scrollbar
.scroll_mode
= 0;
9135 /* Try to make the scrolling a tad smoother. */
9136 if (!xaw3d_pick_top
)
9137 shown
= min (shown
, old_shown
);
9139 XawScrollbarSetThumb (widget
, top
, shown
);
9142 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
9143 sb
->scrollbar
.scroll_mode
= scroll_mode
;
9148 #endif /* !USE_MOTIF */
9153 #endif /* USE_TOOLKIT_SCROLL_BARS */
9157 /************************************************************************
9158 Scroll bars, general
9159 ************************************************************************/
9161 /* Create a scroll bar and return the scroll bar vector for it. W is
9162 the Emacs window on which to create the scroll bar. TOP, LEFT,
9163 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
9166 static struct scroll_bar
*
9167 x_scroll_bar_create (w
, top
, left
, width
, height
)
9169 int top
, left
, width
, height
;
9171 struct frame
*f
= XFRAME (w
->frame
);
9172 struct scroll_bar
*bar
9173 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
9177 #ifdef USE_TOOLKIT_SCROLL_BARS
9178 x_create_toolkit_scroll_bar (f
, bar
);
9179 #else /* not USE_TOOLKIT_SCROLL_BARS */
9181 XSetWindowAttributes a
;
9185 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
9186 if (a
.background_pixel
== -1)
9187 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
9189 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
9190 | ButtonMotionMask
| PointerMotionHintMask
9192 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
9194 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
9196 /* Clear the area of W that will serve as a scroll bar. This is
9197 for the case that a window has been split horizontally. In
9198 this case, no clear_frame is generated to reduce flickering. */
9199 if (width
> 0 && height
> 0)
9200 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9202 window_box_height (w
), False
);
9204 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9205 /* Position and size of scroll bar. */
9206 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9208 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9210 /* Border width, depth, class, and visual. */
9217 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
9219 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9221 XSETWINDOW (bar
->window
, w
);
9222 XSETINT (bar
->top
, top
);
9223 XSETINT (bar
->left
, left
);
9224 XSETINT (bar
->width
, width
);
9225 XSETINT (bar
->height
, height
);
9226 XSETINT (bar
->start
, 0);
9227 XSETINT (bar
->end
, 0);
9228 bar
->dragging
= Qnil
;
9230 /* Add bar to its frame's list of scroll bars. */
9231 bar
->next
= FRAME_SCROLL_BARS (f
);
9233 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9234 if (!NILP (bar
->next
))
9235 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9237 /* Map the window/widget. */
9238 #ifdef USE_TOOLKIT_SCROLL_BARS
9240 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
9241 XtConfigureWidget (scroll_bar
,
9242 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9244 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9245 max (height
, 1), 0);
9246 XtMapWidget (scroll_bar
);
9248 #else /* not USE_TOOLKIT_SCROLL_BARS */
9249 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9250 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9257 /* Draw BAR's handle in the proper position.
9259 If the handle is already drawn from START to END, don't bother
9260 redrawing it, unless REBUILD is non-zero; in that case, always
9261 redraw it. (REBUILD is handy for drawing the handle after expose
9264 Normally, we want to constrain the start and end of the handle to
9265 fit inside its rectangle, but if the user is dragging the scroll
9266 bar handle, we want to let them drag it down all the way, so that
9267 the bar's top is as far down as it goes; otherwise, there's no way
9268 to move to the very end of the buffer. */
9270 #ifndef USE_TOOLKIT_SCROLL_BARS
9273 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
9274 struct scroll_bar
*bar
;
9278 int dragging
= ! NILP (bar
->dragging
);
9279 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9280 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9281 GC gc
= f
->output_data
.x
->normal_gc
;
9283 /* If the display is already accurate, do nothing. */
9285 && start
== XINT (bar
->start
)
9286 && end
== XINT (bar
->end
))
9292 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
9293 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9294 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9296 /* Make sure the values are reasonable, and try to preserve
9297 the distance between start and end. */
9299 int length
= end
- start
;
9303 else if (start
> top_range
)
9305 end
= start
+ length
;
9309 else if (end
> top_range
&& ! dragging
)
9313 /* Store the adjusted setting in the scroll bar. */
9314 XSETINT (bar
->start
, start
);
9315 XSETINT (bar
->end
, end
);
9317 /* Clip the end position, just for display. */
9318 if (end
> top_range
)
9321 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
9322 below top positions, to make sure the handle is always at least
9323 that many pixels tall. */
9324 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
9326 /* Draw the empty space above the handle. Note that we can't clear
9327 zero-height areas; that means "clear to end of window." */
9329 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9330 /* x, y, width, height, and exposures. */
9331 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9332 VERTICAL_SCROLL_BAR_TOP_BORDER
,
9333 inside_width
, start
,
9336 /* Change to proper foreground color if one is specified. */
9337 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9338 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9339 f
->output_data
.x
->scroll_bar_foreground_pixel
);
9341 /* Draw the handle itself. */
9342 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9343 /* x, y, width, height */
9344 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9345 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
9346 inside_width
, end
- start
);
9348 /* Restore the foreground color of the GC if we changed it above. */
9349 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9350 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9351 f
->output_data
.x
->foreground_pixel
);
9353 /* Draw the empty space below the handle. Note that we can't
9354 clear zero-height areas; that means "clear to end of window." */
9355 if (end
< inside_height
)
9356 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9357 /* x, y, width, height, and exposures. */
9358 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9359 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
9360 inside_width
, inside_height
- end
,
9368 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9370 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
9374 x_scroll_bar_remove (bar
)
9375 struct scroll_bar
*bar
;
9377 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9380 #ifdef USE_TOOLKIT_SCROLL_BARS
9381 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
9383 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9386 /* Disassociate this scroll bar from its window. */
9387 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
9393 /* Set the handle of the vertical scroll bar for WINDOW to indicate
9394 that we are displaying PORTION characters out of a total of WHOLE
9395 characters, starting at POSITION. If WINDOW has no scroll bar,
9399 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
9401 int portion
, whole
, position
;
9403 struct frame
*f
= XFRAME (w
->frame
);
9404 struct scroll_bar
*bar
;
9405 int top
, height
, left
, sb_left
, width
, sb_width
;
9406 int window_x
, window_y
, window_width
, window_height
;
9408 /* Get window dimensions. */
9409 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9411 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9412 height
= window_height
;
9414 /* Compute the left edge of the scroll bar area. */
9415 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9416 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
9418 left
= XFASTINT (w
->left
);
9419 left
*= CANON_X_UNIT (f
);
9420 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
9422 /* Compute the width of the scroll bar which might be less than
9423 the width of the area reserved for the scroll bar. */
9424 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
9425 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
9429 /* Compute the left edge of the scroll bar. */
9430 #ifdef USE_TOOLKIT_SCROLL_BARS
9431 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9432 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
9434 sb_left
= left
+ (width
- sb_width
) / 2;
9436 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9437 sb_left
= left
+ width
- sb_width
;
9442 /* Does the scroll bar exist yet? */
9443 if (NILP (w
->vertical_scroll_bar
))
9445 if (width
> 0 && height
> 0)
9448 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9449 left
, top
, width
, height
, False
);
9453 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
9457 /* It may just need to be moved and resized. */
9458 unsigned int mask
= 0;
9460 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
9464 if (sb_left
!= XINT (bar
->left
))
9466 if (top
!= XINT (bar
->top
))
9468 if (sb_width
!= XINT (bar
->width
))
9470 if (height
!= XINT (bar
->height
))
9473 #ifdef USE_TOOLKIT_SCROLL_BARS
9475 /* Since toolkit scroll bars are smaller than the space reserved
9476 for them on the frame, we have to clear "under" them. */
9477 if (width
> 0 && height
> 0)
9478 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9479 left
, top
, width
, height
, False
);
9481 /* Move/size the scroll bar widget. */
9483 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
9484 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9486 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9487 max (height
, 1), 0);
9489 #else /* not USE_TOOLKIT_SCROLL_BARS */
9491 /* Clear areas not covered by the scroll bar because of
9492 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
9493 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
9495 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9496 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9498 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9499 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9500 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9504 /* Clear areas not covered by the scroll bar because it's not as
9505 wide as the area reserved for it. This makes sure a
9506 previous mode line display is cleared after C-x 2 C-x 1, for
9509 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9510 int rest
= area_width
- sb_width
;
9511 if (rest
> 0 && height
> 0)
9513 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
9514 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9515 left
+ area_width
- rest
, top
,
9516 rest
, height
, False
);
9518 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9519 left
, top
, rest
, height
, False
);
9523 /* Move/size the scroll bar window. */
9528 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9530 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
9532 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
9536 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9538 /* Remember new settings. */
9539 XSETINT (bar
->left
, sb_left
);
9540 XSETINT (bar
->top
, top
);
9541 XSETINT (bar
->width
, sb_width
);
9542 XSETINT (bar
->height
, height
);
9547 #ifdef USE_TOOLKIT_SCROLL_BARS
9548 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
9549 #else /* not USE_TOOLKIT_SCROLL_BARS */
9550 /* Set the scroll bar's current state, unless we're currently being
9552 if (NILP (bar
->dragging
))
9554 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
9557 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
9560 int start
= ((double) position
* top_range
) / whole
;
9561 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
9562 x_scroll_bar_set_handle (bar
, start
, end
, 0);
9565 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9567 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
9571 /* The following three hooks are used when we're doing a thorough
9572 redisplay of the frame. We don't explicitly know which scroll bars
9573 are going to be deleted, because keeping track of when windows go
9574 away is a real pain - "Can you say set-window-configuration, boys
9575 and girls?" Instead, we just assert at the beginning of redisplay
9576 that *all* scroll bars are to be removed, and then save a scroll bar
9577 from the fiery pit when we actually redisplay its window. */
9579 /* Arrange for all scroll bars on FRAME to be removed at the next call
9580 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
9581 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
9584 XTcondemn_scroll_bars (frame
)
9587 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
9588 while (! NILP (FRAME_SCROLL_BARS (frame
)))
9591 bar
= FRAME_SCROLL_BARS (frame
);
9592 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
9593 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
9594 XSCROLL_BAR (bar
)->prev
= Qnil
;
9595 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
9596 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
9597 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
9602 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
9603 Note that WINDOW isn't necessarily condemned at all. */
9606 XTredeem_scroll_bar (window
)
9607 struct window
*window
;
9609 struct scroll_bar
*bar
;
9612 /* We can't redeem this window's scroll bar if it doesn't have one. */
9613 if (NILP (window
->vertical_scroll_bar
))
9616 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
9618 /* Unlink it from the condemned list. */
9619 f
= XFRAME (WINDOW_FRAME (window
));
9620 if (NILP (bar
->prev
))
9622 /* If the prev pointer is nil, it must be the first in one of
9624 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9625 /* It's not condemned. Everything's fine. */
9627 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9628 window
->vertical_scroll_bar
))
9629 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9631 /* If its prev pointer is nil, it must be at the front of
9632 one or the other! */
9636 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9638 if (! NILP (bar
->next
))
9639 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9641 bar
->next
= FRAME_SCROLL_BARS (f
);
9643 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9644 if (! NILP (bar
->next
))
9645 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9648 /* Remove all scroll bars on FRAME that haven't been saved since the
9649 last call to `*condemn_scroll_bars_hook'. */
9652 XTjudge_scroll_bars (f
)
9655 Lisp_Object bar
, next
;
9657 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9659 /* Clear out the condemned list now so we won't try to process any
9660 more events on the hapless scroll bars. */
9661 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9663 for (; ! NILP (bar
); bar
= next
)
9665 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9667 x_scroll_bar_remove (b
);
9670 b
->next
= b
->prev
= Qnil
;
9673 /* Now there should be no references to the condemned scroll bars,
9674 and they should get garbage-collected. */
9678 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9679 is a no-op when using toolkit scroll bars.
9681 This may be called from a signal handler, so we have to ignore GC
9685 x_scroll_bar_expose (bar
, event
)
9686 struct scroll_bar
*bar
;
9689 #ifndef USE_TOOLKIT_SCROLL_BARS
9691 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9692 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9693 GC gc
= f
->output_data
.x
->normal_gc
;
9694 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9698 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9700 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9701 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9703 /* x, y, width, height */
9705 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9706 XINT (bar
->height
) - 1);
9710 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9713 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9714 is set to something other than NO_EVENT, it is enqueued.
9716 This may be called from a signal handler, so we have to ignore GC
9719 #ifndef USE_TOOLKIT_SCROLL_BARS
9722 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9723 struct scroll_bar
*bar
;
9725 struct input_event
*emacs_event
;
9727 if (! GC_WINDOWP (bar
->window
))
9730 emacs_event
->kind
= SCROLL_BAR_CLICK_EVENT
;
9731 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9732 emacs_event
->modifiers
9733 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9734 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9735 event
->xbutton
.state
)
9736 | (event
->type
== ButtonRelease
9739 emacs_event
->frame_or_window
= bar
->window
;
9740 emacs_event
->arg
= Qnil
;
9741 emacs_event
->timestamp
= event
->xbutton
.time
;
9744 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9746 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9749 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9750 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9753 if (y
> top_range
) y
= top_range
;
9755 if (y
< XINT (bar
->start
))
9756 emacs_event
->part
= scroll_bar_above_handle
;
9757 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9758 emacs_event
->part
= scroll_bar_handle
;
9760 emacs_event
->part
= scroll_bar_below_handle
;
9762 /* Just because the user has clicked on the handle doesn't mean
9763 they want to drag it. Lisp code needs to be able to decide
9764 whether or not we're dragging. */
9766 /* If the user has just clicked on the handle, record where they're
9768 if (event
->type
== ButtonPress
9769 && emacs_event
->part
== scroll_bar_handle
)
9770 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9773 /* If the user has released the handle, set it to its final position. */
9774 if (event
->type
== ButtonRelease
9775 && ! NILP (bar
->dragging
))
9777 int new_start
= y
- XINT (bar
->dragging
);
9778 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9780 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9781 bar
->dragging
= Qnil
;
9784 /* Same deal here as the other #if 0. */
9786 /* Clicks on the handle are always reported as occurring at the top of
9788 if (emacs_event
->part
== scroll_bar_handle
)
9789 emacs_event
->x
= bar
->start
;
9791 XSETINT (emacs_event
->x
, y
);
9793 XSETINT (emacs_event
->x
, y
);
9796 XSETINT (emacs_event
->y
, top_range
);
9800 /* Handle some mouse motion while someone is dragging the scroll bar.
9802 This may be called from a signal handler, so we have to ignore GC
9806 x_scroll_bar_note_movement (bar
, event
)
9807 struct scroll_bar
*bar
;
9810 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9812 last_mouse_movement_time
= event
->xmotion
.time
;
9815 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9817 /* If we're dragging the bar, display it. */
9818 if (! GC_NILP (bar
->dragging
))
9820 /* Where should the handle be now? */
9821 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9823 if (new_start
!= XINT (bar
->start
))
9825 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9827 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9832 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9834 /* Return information to the user about the current position of the mouse
9835 on the scroll bar. */
9838 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9840 Lisp_Object
*bar_window
;
9841 enum scroll_bar_part
*part
;
9843 unsigned long *time
;
9845 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9846 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9847 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9849 Window dummy_window
;
9851 unsigned int dummy_mask
;
9855 /* Get the mouse's position relative to the scroll bar window, and
9857 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9859 /* Root, child, root x and root y. */
9860 &dummy_window
, &dummy_window
,
9861 &dummy_coord
, &dummy_coord
,
9863 /* Position relative to scroll bar. */
9866 /* Mouse buttons and modifier keys. */
9873 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9876 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9878 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9880 if (! NILP (bar
->dragging
))
9881 win_y
-= XINT (bar
->dragging
);
9885 if (win_y
> top_range
)
9889 *bar_window
= bar
->window
;
9891 if (! NILP (bar
->dragging
))
9892 *part
= scroll_bar_handle
;
9893 else if (win_y
< XINT (bar
->start
))
9894 *part
= scroll_bar_above_handle
;
9895 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9896 *part
= scroll_bar_handle
;
9898 *part
= scroll_bar_below_handle
;
9900 XSETINT (*x
, win_y
);
9901 XSETINT (*y
, top_range
);
9904 last_mouse_scroll_bar
= Qnil
;
9907 *time
= last_mouse_movement_time
;
9913 /* The screen has been cleared so we may have changed foreground or
9914 background colors, and the scroll bars may need to be redrawn.
9915 Clear out the scroll bars, and ask for expose events, so we can
9919 x_scroll_bar_clear (f
)
9922 #ifndef USE_TOOLKIT_SCROLL_BARS
9925 /* We can have scroll bars even if this is 0,
9926 if we just turned off scroll bar mode.
9927 But in that case we should not clear them. */
9928 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9929 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9930 bar
= XSCROLL_BAR (bar
)->next
)
9931 XClearArea (FRAME_X_DISPLAY (f
),
9932 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9934 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9938 /* Define a queue to save up SelectionRequest events for later handling. */
9940 struct selection_event_queue
9943 struct selection_event_queue
*next
;
9946 static struct selection_event_queue
*queue
;
9948 /* Nonzero means queue up certain events--don't process them yet. */
9950 static int x_queue_selection_requests
;
9952 /* Queue up an X event *EVENT, to be processed later. */
9955 x_queue_event (f
, event
)
9959 struct selection_event_queue
*queue_tmp
9960 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9962 if (queue_tmp
!= NULL
)
9964 queue_tmp
->event
= *event
;
9965 queue_tmp
->next
= queue
;
9970 /* Take all the queued events and put them back
9971 so that they get processed afresh. */
9974 x_unqueue_events (display
)
9977 while (queue
!= NULL
)
9979 struct selection_event_queue
*queue_tmp
= queue
;
9980 XPutBackEvent (display
, &queue_tmp
->event
);
9981 queue
= queue_tmp
->next
;
9982 xfree ((char *)queue_tmp
);
9986 /* Start queuing SelectionRequest events. */
9989 x_start_queuing_selection_requests (display
)
9992 x_queue_selection_requests
++;
9995 /* Stop queuing SelectionRequest events. */
9998 x_stop_queuing_selection_requests (display
)
10001 x_queue_selection_requests
--;
10002 x_unqueue_events (display
);
10005 /* The main X event-reading loop - XTread_socket. */
10008 /* Time stamp of enter window event. This is only used by XTread_socket,
10009 but we have to put it out here, since static variables within functions
10010 sometimes don't work. */
10012 static Time enter_timestamp
;
10015 /* This holds the state XLookupString needs to implement dead keys
10016 and other tricks known as "compose processing". _X Window System_
10017 says that a portable program can't use this, but Stephen Gildea assures
10018 me that letting the compiler initialize it to zeros will work okay.
10020 This must be defined outside of XTread_socket, for the same reasons
10021 given for enter_timestamp, above. */
10023 static XComposeStatus compose_status
;
10025 /* Record the last 100 characters stored
10026 to help debug the loss-of-chars-during-GC problem. */
10028 static int temp_index
;
10029 static short temp_buffer
[100];
10031 /* Set this to nonzero to fake an "X I/O error"
10032 on a particular display. */
10034 struct x_display_info
*XTread_socket_fake_io_error
;
10036 /* When we find no input here, we occasionally do a no-op command
10037 to verify that the X server is still running and we can still talk with it.
10038 We try all the open displays, one by one.
10039 This variable is used for cycling thru the displays. */
10041 static struct x_display_info
*next_noop_dpyinfo
;
10043 #define SET_SAVED_MENU_EVENT(size) \
10046 if (f->output_data.x->saved_menu_event == 0) \
10047 f->output_data.x->saved_menu_event \
10048 = (XEvent *) xmalloc (sizeof (XEvent)); \
10049 bcopy (&event, f->output_data.x->saved_menu_event, size); \
10050 if (numchars >= 1) \
10052 bufp->kind = MENU_BAR_ACTIVATE_EVENT; \
10053 XSETFRAME (bufp->frame_or_window, f); \
10054 bufp->arg = Qnil; \
10062 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
10063 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
10073 /* Handles the XEvent EVENT on display DPYINFO.
10075 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
10076 *FINISH is zero if caller should continue reading events.
10077 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
10079 Events representing keys are stored in buffer *BUFP_R,
10080 which can hold up to *NUMCHARSP characters.
10081 We return the number of characters stored into the buffer. */
10084 handle_one_xevent (dpyinfo
, eventp
, bufp_r
, numcharsp
, finish
)
10085 struct x_display_info
*dpyinfo
;
10087 /* register */ struct input_event
**bufp_r
;
10088 /* register */ int *numcharsp
;
10094 struct coding_system coding
;
10095 struct input_event
*bufp
= *bufp_r
;
10096 int numchars
= *numcharsp
;
10097 XEvent event
= *eventp
;
10099 *finish
= X_EVENT_NORMAL
;
10101 switch (event
.type
)
10103 case ClientMessage
:
10105 if (event
.xclient
.message_type
10106 == dpyinfo
->Xatom_wm_protocols
10107 && event
.xclient
.format
== 32)
10109 if (event
.xclient
.data
.l
[0]
10110 == dpyinfo
->Xatom_wm_take_focus
)
10112 /* Use x_any_window_to_frame because this
10113 could be the shell widget window
10114 if the frame has no title bar. */
10115 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
10117 /* Not quite sure this is needed -pd */
10118 if (f
&& FRAME_XIC (f
))
10119 XSetICFocus (FRAME_XIC (f
));
10121 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
10122 instructs the WM to set the input focus automatically for
10123 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
10124 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
10125 it has set the focus. So, XSetInputFocus below is not
10128 The call to XSetInputFocus below has also caused trouble. In
10129 cases where the XSetInputFocus done by the WM and the one
10130 below are temporally close (on a fast machine), the call
10131 below can generate additional FocusIn events which confuse
10134 /* Since we set WM_TAKE_FOCUS, we must call
10135 XSetInputFocus explicitly. But not if f is null,
10136 since that might be an event for a deleted frame. */
10139 Display
*d
= event
.xclient
.display
;
10140 /* Catch and ignore errors, in case window has been
10141 iconified by a window manager such as GWM. */
10142 int count
= x_catch_errors (d
);
10143 XSetInputFocus (d
, event
.xclient
.window
,
10144 /* The ICCCM says this is
10145 the only valid choice. */
10147 event
.xclient
.data
.l
[1]);
10148 /* This is needed to detect the error
10149 if there is an error. */
10151 x_uncatch_errors (d
, count
);
10153 /* Not certain about handling scroll bars here */
10156 else if (event
.xclient
.data
.l
[0]
10157 == dpyinfo
->Xatom_wm_save_yourself
)
10159 /* Save state modify the WM_COMMAND property to
10160 something which can reinstate us. This notifies
10161 the session manager, who's looking for such a
10162 PropertyNotify. Can restart processing when
10163 a keyboard or mouse event arrives. */
10164 /* If we have a session manager, don't set this.
10165 KDE will then start two Emacsen, one for the
10166 session manager and one for this. */
10169 && ! x_session_have_connection ()
10173 f
= x_top_window_to_frame (dpyinfo
,
10174 event
.xclient
.window
);
10175 /* This is just so we only give real data once
10176 for a single Emacs process. */
10177 if (f
== SELECTED_FRAME ())
10178 XSetCommand (FRAME_X_DISPLAY (f
),
10179 event
.xclient
.window
,
10180 initial_argv
, initial_argc
);
10182 XSetCommand (FRAME_X_DISPLAY (f
),
10183 event
.xclient
.window
,
10187 else if (event
.xclient
.data
.l
[0]
10188 == dpyinfo
->Xatom_wm_delete_window
)
10191 = x_any_window_to_frame (dpyinfo
,
10192 event
.xclient
.window
);
10199 bufp
->kind
= DELETE_WINDOW_EVENT
;
10200 XSETFRAME (bufp
->frame_or_window
, f
);
10208 goto OTHER
; /* May be a dialog that is to be removed */
10211 else if (event
.xclient
.message_type
10212 == dpyinfo
->Xatom_wm_configure_denied
)
10215 else if (event
.xclient
.message_type
10216 == dpyinfo
->Xatom_wm_window_moved
)
10220 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10222 new_x
= event
.xclient
.data
.s
[0];
10223 new_y
= event
.xclient
.data
.s
[1];
10227 f
->output_data
.x
->left_pos
= new_x
;
10228 f
->output_data
.x
->top_pos
= new_y
;
10231 #ifdef HACK_EDITRES
10232 else if (event
.xclient
.message_type
10233 == dpyinfo
->Xatom_editres
)
10236 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
10237 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
10240 #endif /* HACK_EDITRES */
10241 else if ((event
.xclient
.message_type
10242 == dpyinfo
->Xatom_DONE
)
10243 || (event
.xclient
.message_type
10244 == dpyinfo
->Xatom_PAGE
))
10246 /* Ghostview job completed. Kill it. We could
10247 reply with "Next" if we received "Page", but we
10248 currently never do because we are interested in
10249 images, only, which should have 1 page. */
10250 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
10252 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10253 x_kill_gs_process (pixmap
, f
);
10254 expose_frame (f
, 0, 0, 0, 0);
10256 #ifdef USE_TOOLKIT_SCROLL_BARS
10257 /* Scroll bar callbacks send a ClientMessage from which
10258 we construct an input_event. */
10259 else if (event
.xclient
.message_type
10260 == dpyinfo
->Xatom_Scrollbar
)
10262 x_scroll_bar_to_input_event (&event
, bufp
);
10263 ++bufp
, ++count
, --numchars
;
10266 #endif /* USE_TOOLKIT_SCROLL_BARS */
10272 case SelectionNotify
:
10273 #ifdef USE_X_TOOLKIT
10274 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
10276 #endif /* not USE_X_TOOLKIT */
10277 x_handle_selection_notify (&event
.xselection
);
10280 case SelectionClear
: /* Someone has grabbed ownership. */
10281 #ifdef USE_X_TOOLKIT
10282 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
10284 #endif /* USE_X_TOOLKIT */
10286 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
10291 bufp
->kind
= SELECTION_CLEAR_EVENT
;
10292 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10293 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10294 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10295 bufp
->frame_or_window
= Qnil
;
10304 case SelectionRequest
: /* Someone wants our selection. */
10305 #ifdef USE_X_TOOLKIT
10306 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
10308 #endif /* USE_X_TOOLKIT */
10309 if (x_queue_selection_requests
)
10310 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
10314 XSelectionRequestEvent
*eventp
10315 = (XSelectionRequestEvent
*) &event
;
10320 bufp
->kind
= SELECTION_REQUEST_EVENT
;
10321 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10322 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
10323 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10324 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
10325 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
10326 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10327 bufp
->frame_or_window
= Qnil
;
10336 case PropertyNotify
:
10337 #if 0 /* This is plain wrong. In the case that we are waiting for a
10338 PropertyNotify used as an ACK in incremental selection
10339 transfer, the property will be on the receiver's window. */
10340 #if defined USE_X_TOOLKIT
10341 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
10345 x_handle_property_notify (&event
.xproperty
);
10348 case ReparentNotify
:
10349 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
10353 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
10354 x_real_positions (f
, &x
, &y
);
10355 f
->output_data
.x
->left_pos
= x
;
10356 f
->output_data
.x
->top_pos
= y
;
10362 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
10365 x_check_fullscreen (f
);
10367 if (f
->async_visible
== 0)
10369 f
->async_visible
= 1;
10370 f
->async_iconified
= 0;
10371 f
->output_data
.x
->has_been_visible
= 1;
10372 SET_FRAME_GARBAGED (f
);
10375 expose_frame (x_window_to_frame (dpyinfo
,
10376 event
.xexpose
.window
),
10377 event
.xexpose
.x
, event
.xexpose
.y
,
10378 event
.xexpose
.width
, event
.xexpose
.height
);
10382 #ifndef USE_TOOLKIT_SCROLL_BARS
10383 struct scroll_bar
*bar
;
10385 #if defined USE_LUCID
10386 /* Submenus of the Lucid menu bar aren't widgets
10387 themselves, so there's no way to dispatch events
10388 to them. Recognize this case separately. */
10391 = x_window_to_menu_bar (event
.xexpose
.window
);
10393 xlwmenu_redisplay (widget
);
10395 #endif /* USE_LUCID */
10397 #ifdef USE_TOOLKIT_SCROLL_BARS
10398 /* Dispatch event to the widget. */
10400 #else /* not USE_TOOLKIT_SCROLL_BARS */
10401 bar
= x_window_to_scroll_bar (event
.xexpose
.window
);
10404 x_scroll_bar_expose (bar
, &event
);
10405 #ifdef USE_X_TOOLKIT
10408 #endif /* USE_X_TOOLKIT */
10409 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10413 case GraphicsExpose
: /* This occurs when an XCopyArea's
10414 source area was obscured or not
10416 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
10420 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
10421 event
.xgraphicsexpose
.width
,
10422 event
.xgraphicsexpose
.height
);
10424 #ifdef USE_X_TOOLKIT
10427 #endif /* USE_X_TOOLKIT */
10430 case NoExpose
: /* This occurs when an XCopyArea's
10431 source area was completely
10436 /* Redo the mouse-highlight after the tooltip has gone. */
10437 if (event
.xmap
.window
== tip_window
)
10440 redo_mouse_highlight ();
10443 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
10444 if (f
) /* F may no longer exist if
10445 the frame was deleted. */
10447 /* While a frame is unmapped, display generation is
10448 disabled; you don't want to spend time updating a
10449 display that won't ever be seen. */
10450 f
->async_visible
= 0;
10451 /* We can't distinguish, from the event, whether the window
10452 has become iconified or invisible. So assume, if it
10453 was previously visible, than now it is iconified.
10454 But x_make_frame_invisible clears both
10455 the visible flag and the iconified flag;
10456 and that way, we know the window is not iconified now. */
10457 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
10459 f
->async_iconified
= 1;
10461 bufp
->kind
= ICONIFY_EVENT
;
10462 XSETFRAME (bufp
->frame_or_window
, f
);
10472 if (event
.xmap
.window
== tip_window
)
10473 /* The tooltip has been drawn already. Avoid
10474 the SET_FRAME_GARBAGED below. */
10477 /* We use x_top_window_to_frame because map events can
10478 come for sub-windows and they don't mean that the
10479 frame is visible. */
10480 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
10483 /* wait_reading_process_input will notice this and update
10484 the frame's display structures.
10485 If we where iconified, we should not set garbaged,
10486 because that stops redrawing on Expose events. This looks
10487 bad if we are called from a recursive event loop
10488 (x_dispatch_event), for example when a dialog is up. */
10489 if (! f
->async_iconified
)
10490 SET_FRAME_GARBAGED (f
);
10492 f
->async_visible
= 1;
10493 f
->async_iconified
= 0;
10494 f
->output_data
.x
->has_been_visible
= 1;
10498 bufp
->kind
= DEICONIFY_EVENT
;
10499 XSETFRAME (bufp
->frame_or_window
, f
);
10505 else if (! NILP (Vframe_list
)
10506 && ! NILP (XCDR (Vframe_list
)))
10507 /* Force a redisplay sooner or later
10508 to update the frame titles
10509 in case this is the second frame. */
10510 record_asynch_buffer_change ();
10516 /* Dispatch KeyPress events when in menu. */
10517 if (popup_activated_flag
)
10519 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
10521 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
10523 dpyinfo
->mouse_face_hidden
= 1;
10524 clear_mouse_face (dpyinfo
);
10527 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10530 /* Scroll bars consume key events, but we want
10531 the keys to go to the scroll bar's frame. */
10532 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
10533 event
.xkey
.window
);
10534 if (widget
&& XmIsScrollBar (widget
))
10536 widget
= XtParent (widget
);
10537 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
10540 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10544 KeySym keysym
, orig_keysym
;
10545 /* al%imercury@uunet.uu.net says that making this 81
10546 instead of 80 fixed a bug whereby meta chars made
10549 It seems that some version of XmbLookupString has
10550 a bug of not returning XBufferOverflow in
10551 status_return even if the input is too long to
10552 fit in 81 bytes. So, we must prepare sufficient
10553 bytes for copy_buffer. 513 bytes (256 chars for
10554 two-byte character set) seems to be a fairly good
10555 approximation. -- 2000.8.10 handa@etl.go.jp */
10556 unsigned char copy_buffer
[513];
10557 unsigned char *copy_bufptr
= copy_buffer
;
10558 int copy_bufsiz
= sizeof (copy_buffer
);
10560 Lisp_Object coding_system
= Qlatin_1
;
10563 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10564 extra_keyboard_modifiers
);
10565 modifiers
= event
.xkey
.state
;
10567 /* This will have to go some day... */
10569 /* make_lispy_event turns chars into control chars.
10570 Don't do it here because XLookupString is too eager. */
10571 event
.xkey
.state
&= ~ControlMask
;
10572 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10573 | dpyinfo
->super_mod_mask
10574 | dpyinfo
->hyper_mod_mask
10575 | dpyinfo
->alt_mod_mask
);
10577 /* In case Meta is ComposeCharacter,
10578 clear its status. According to Markus Ehrnsperger
10579 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10580 this enables ComposeCharacter to work whether or
10581 not it is combined with Meta. */
10582 if (modifiers
& dpyinfo
->meta_mod_mask
)
10583 bzero (&compose_status
, sizeof (compose_status
));
10588 Status status_return
;
10590 coding_system
= Vlocale_coding_system
;
10591 nbytes
= XmbLookupString (FRAME_XIC (f
),
10592 &event
.xkey
, copy_bufptr
,
10593 copy_bufsiz
, &keysym
,
10595 if (status_return
== XBufferOverflow
)
10597 copy_bufsiz
= nbytes
+ 1;
10598 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10599 nbytes
= XmbLookupString (FRAME_XIC (f
),
10600 &event
.xkey
, copy_bufptr
,
10601 copy_bufsiz
, &keysym
,
10604 /* Xutf8LookupString is a new but already deprecated interface. -stef */
10605 #if 0 && defined X_HAVE_UTF8_STRING
10606 else if (status_return
== XLookupKeySym
)
10607 { /* Try again but with utf-8. */
10608 coding_system
= Qutf_8
;
10609 nbytes
= Xutf8LookupString (FRAME_XIC (f
),
10610 &event
.xkey
, copy_bufptr
,
10611 copy_bufsiz
, &keysym
,
10613 if (status_return
== XBufferOverflow
)
10615 copy_bufsiz
= nbytes
+ 1;
10616 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10617 nbytes
= Xutf8LookupString (FRAME_XIC (f
),
10620 copy_bufsiz
, &keysym
,
10626 if (status_return
== XLookupNone
)
10628 else if (status_return
== XLookupChars
)
10633 else if (status_return
!= XLookupKeySym
10634 && status_return
!= XLookupBoth
)
10638 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10639 copy_bufsiz
, &keysym
,
10642 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10643 copy_bufsiz
, &keysym
,
10647 orig_keysym
= keysym
;
10653 /* First deal with keysyms which have defined
10654 translations to characters. */
10655 if (keysym
>= 32 && keysym
< 128)
10656 /* Avoid explicitly decoding each ASCII character. */
10658 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
10659 bufp
->code
= keysym
;
10660 XSETFRAME (bufp
->frame_or_window
, f
);
10663 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10665 bufp
->timestamp
= event
.xkey
.time
;
10670 /* Now non-ASCII. */
10671 else if (HASH_TABLE_P (Vx_keysym_table
)
10672 && (NATNUMP (c
= Fgethash (make_number (keysym
),
10676 bufp
->kind
= (SINGLE_BYTE_CHAR_P (XFASTINT (c
))
10677 ? ASCII_KEYSTROKE_EVENT
10678 : MULTIBYTE_CHAR_KEYSTROKE_EVENT
);
10679 bufp
->code
= XFASTINT (c
);
10680 XSETFRAME (bufp
->frame_or_window
, f
);
10683 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10685 bufp
->timestamp
= event
.xkey
.time
;
10690 /* Random non-modifier sorts of keysyms. */
10691 else if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10692 || keysym
== XK_Delete
10693 #ifdef XK_ISO_Left_Tab
10694 || (keysym
>= XK_ISO_Left_Tab
10695 && keysym
<= XK_ISO_Enter
)
10697 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10698 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10700 /* This recognizes the "extended function
10701 keys". It seems there's no cleaner way.
10702 Test IsModifierKey to avoid handling
10703 mode_switch incorrectly. */
10704 || ((unsigned) (keysym
) >= XK_Select
10705 && (unsigned)(keysym
) < XK_KP_Space
)
10707 #ifdef XK_dead_circumflex
10708 || orig_keysym
== XK_dead_circumflex
10710 #ifdef XK_dead_grave
10711 || orig_keysym
== XK_dead_grave
10713 #ifdef XK_dead_tilde
10714 || orig_keysym
== XK_dead_tilde
10716 #ifdef XK_dead_diaeresis
10717 || orig_keysym
== XK_dead_diaeresis
10719 #ifdef XK_dead_macron
10720 || orig_keysym
== XK_dead_macron
10722 #ifdef XK_dead_degree
10723 || orig_keysym
== XK_dead_degree
10725 #ifdef XK_dead_acute
10726 || orig_keysym
== XK_dead_acute
10728 #ifdef XK_dead_cedilla
10729 || orig_keysym
== XK_dead_cedilla
10731 #ifdef XK_dead_breve
10732 || orig_keysym
== XK_dead_breve
10734 #ifdef XK_dead_ogonek
10735 || orig_keysym
== XK_dead_ogonek
10737 #ifdef XK_dead_caron
10738 || orig_keysym
== XK_dead_caron
10740 #ifdef XK_dead_doubleacute
10741 || orig_keysym
== XK_dead_doubleacute
10743 #ifdef XK_dead_abovedot
10744 || orig_keysym
== XK_dead_abovedot
10746 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10747 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10748 /* Any "vendor-specific" key is ok. */
10749 || (orig_keysym
& (1 << 28))
10750 || (keysym
!= NoSymbol
&& nbytes
== 0))
10751 && ! (IsModifierKey (orig_keysym
)
10753 #ifdef XK_Mode_switch
10754 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10757 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10759 #endif /* not HAVE_X11R5 */
10760 /* The symbols from XK_ISO_Lock
10761 to XK_ISO_Last_Group_Lock
10762 don't have real modifiers but
10763 should be treated similarly to
10764 Mode_switch by Emacs. */
10765 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
10766 || ((unsigned)(orig_keysym
)
10768 && (unsigned)(orig_keysym
)
10769 <= XK_ISO_Last_Group_Lock
)
10773 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10775 temp_buffer
[temp_index
++] = keysym
;
10776 /* make_lispy_event will convert this to a symbolic
10778 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
10779 bufp
->code
= keysym
;
10780 XSETFRAME (bufp
->frame_or_window
, f
);
10783 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10785 bufp
->timestamp
= event
.xkey
.time
;
10790 else if (numchars
> nbytes
)
10791 { /* Raw bytes, not keysym. */
10796 /* The input should be decoded with `coding_system'
10797 which depends on which X*LookupString function
10798 we used just above and the locale. */
10799 setup_coding_system (coding_system
, &coding
);
10800 coding
.src_multibyte
= 0;
10801 coding
.dst_multibyte
= 1;
10802 /* The input is converted to events, thus we can't
10803 handle composition. Anyway, there's no XIM that
10804 gives us composition information. */
10805 coding
.composing
= COMPOSITION_DISABLED
;
10807 for (i
= 0; i
< nbytes
; i
++)
10809 if (temp_index
== (sizeof temp_buffer
10812 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10816 /* Decode the input data. */
10820 require
= decoding_buffer_size (&coding
, nbytes
);
10821 p
= (unsigned char *) alloca (require
);
10822 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10823 /* We explicitely disable composition
10824 handling because key data should
10825 not contain any composition
10827 coding
.composing
= COMPOSITION_DISABLED
;
10828 decode_coding (&coding
, copy_bufptr
, p
,
10830 nbytes
= coding
.produced
;
10831 nchars
= coding
.produced_char
;
10835 /* Convert the input data to a sequence of
10836 character events. */
10837 for (i
= 0; i
< nbytes
; i
+= len
)
10839 if (nchars
== nbytes
)
10840 c
= copy_bufptr
[i
], len
= 1;
10842 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10845 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10846 ? ASCII_KEYSTROKE_EVENT
10847 : MULTIBYTE_CHAR_KEYSTROKE_EVENT
);
10849 XSETFRAME (bufp
->frame_or_window
, f
);
10852 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10854 bufp
->timestamp
= event
.xkey
.time
;
10859 numchars
-= nchars
;
10861 if (keysym
== NoSymbol
)
10871 /* Don't dispatch this event since XtDispatchEvent calls
10872 XFilterEvent, and two calls in a row may freeze the
10881 /* Don't dispatch this event since XtDispatchEvent calls
10882 XFilterEvent, and two calls in a row may freeze the
10893 n
= x_detect_focus_change (dpyinfo
, &event
, bufp
, numchars
);
10896 bufp
+= n
, count
+= n
, numchars
-= n
;
10899 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10902 if (event
.xcrossing
.focus
)
10904 /* Avoid nasty pop/raise loops. */
10905 if (f
&& (!(f
->auto_raise
)
10906 || !(f
->auto_lower
)
10907 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10909 x_new_focus_frame (dpyinfo
, f
);
10910 enter_timestamp
= event
.xcrossing
.time
;
10913 else if (f
== dpyinfo
->x_focus_frame
)
10914 x_new_focus_frame (dpyinfo
, 0);
10917 /* EnterNotify counts as mouse movement,
10918 so update things that depend on mouse position. */
10919 if (f
&& !f
->output_data
.x
->hourglass_p
)
10920 note_mouse_movement (f
, &event
.xmotion
);
10928 n
= x_detect_focus_change (dpyinfo
, &event
, bufp
, numchars
);
10931 bufp
+= n
, count
+= n
, numchars
-= n
;
10941 n
= x_detect_focus_change (dpyinfo
, &event
, bufp
, numchars
);
10944 bufp
+= n
, count
+= n
, numchars
-= n
;
10948 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10951 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10953 /* If we move outside the frame, then we're
10954 certainly no longer on any text in the frame. */
10955 clear_mouse_face (dpyinfo
);
10956 dpyinfo
->mouse_face_mouse_frame
= 0;
10959 /* Generate a nil HELP_EVENT to cancel a help-echo.
10960 Do it only if there's something to cancel.
10961 Otherwise, the startup message is cleared when
10962 the mouse leaves the frame. */
10963 if (any_help_event_p
)
10968 XSETFRAME (frame
, f
);
10970 n
= gen_help_event (bufp
, numchars
,
10971 Qnil
, frame
, Qnil
, Qnil
, 0);
10972 bufp
+= n
, count
+= n
, numchars
-= n
;
10982 n
= x_detect_focus_change (dpyinfo
, &event
, bufp
, numchars
);
10985 bufp
+= n
, count
+= n
, numchars
-= n
;
10993 previous_help_echo
= help_echo
;
10994 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10995 help_echo_pos
= -1;
10997 if (dpyinfo
->grabbed
&& last_mouse_frame
10998 && FRAME_LIVE_P (last_mouse_frame
))
10999 f
= last_mouse_frame
;
11001 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
11003 if (dpyinfo
->mouse_face_hidden
)
11005 dpyinfo
->mouse_face_hidden
= 0;
11006 clear_mouse_face (dpyinfo
);
11012 /* Generate SELECT_WINDOW_EVENTs when needed. */
11013 if (mouse_autoselect_window
)
11015 Lisp_Object window
;
11018 window
= window_from_coordinates (f
,
11019 event
.xmotion
.x
, event
.xmotion
.y
,
11022 /* Window will be selected only when it is not selected now and
11023 last mouse movement event was not in it. Minibuffer window
11024 will be selected iff it is active. */
11025 if (WINDOWP(window
)
11026 && !EQ (window
, last_window
)
11027 && !EQ (window
, selected_window
)
11030 bufp
->kind
= SELECT_WINDOW_EVENT
;
11031 bufp
->frame_or_window
= window
;
11033 ++bufp
, ++count
, --numchars
;
11036 last_window
=window
;
11038 note_mouse_movement (f
, &event
.xmotion
);
11042 #ifndef USE_TOOLKIT_SCROLL_BARS
11043 struct scroll_bar
*bar
11044 = x_window_to_scroll_bar (event
.xmotion
.window
);
11047 x_scroll_bar_note_movement (bar
, &event
);
11048 #endif /* USE_TOOLKIT_SCROLL_BARS */
11050 /* If we move outside the frame, then we're
11051 certainly no longer on any text in the frame. */
11052 clear_mouse_face (dpyinfo
);
11055 /* If the contents of the global variable help_echo
11056 has changed, generate a HELP_EVENT. */
11057 if (!NILP (help_echo
)
11058 || !NILP (previous_help_echo
))
11064 XSETFRAME (frame
, f
);
11068 any_help_event_p
= 1;
11069 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
11070 help_echo_window
, help_echo_object
,
11072 bufp
+= n
, count
+= n
, numchars
-= n
;
11078 case ConfigureNotify
:
11079 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
11082 #ifndef USE_X_TOOLKIT
11083 /* If there is a pending resize for fullscreen, don't
11084 do this one, the right one will come later.
11085 The toolkit version doesn't seem to need this, but we
11086 need to reset it below. */
11088 ((f
->output_data
.x
->want_fullscreen
& FULLSCREEN_WAIT
)
11089 && FRAME_NEW_WIDTH (f
) != 0);
11090 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
11091 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
11095 /* In the toolkit version, change_frame_size
11096 is called by the code that handles resizing
11097 of the EmacsFrame widget. */
11099 /* Even if the number of character rows and columns has
11100 not changed, the font size may have changed, so we need
11101 to check the pixel dimensions as well. */
11102 if (columns
!= f
->width
11103 || rows
!= f
->height
11104 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
11105 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
11107 change_frame_size (f
, rows
, columns
, 0, 1, 0);
11108 SET_FRAME_GARBAGED (f
);
11109 cancel_mouse_face (f
);
11113 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
11114 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
11116 /* What we have now is the position of Emacs's own window.
11117 Convert that to the position of the window manager window. */
11118 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
11119 &f
->output_data
.x
->top_pos
);
11121 x_check_fullscreen_move(f
);
11122 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_WAIT
)
11123 f
->output_data
.x
->want_fullscreen
&=
11124 ~(FULLSCREEN_WAIT
|FULLSCREEN_BOTH
);
11126 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
11127 xic_set_statusarea (f
);
11130 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
11132 /* Since the WM decorations come below top_pos now,
11133 we must put them below top_pos in the future. */
11134 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
11135 x_wm_set_size_hint (f
, (long) 0, 0);
11141 case ButtonRelease
:
11143 /* If we decide we want to generate an event to be seen
11144 by the rest of Emacs, we put it here. */
11145 struct input_event emacs_event
;
11146 int tool_bar_p
= 0;
11148 emacs_event
.kind
= NO_EVENT
;
11149 bzero (&compose_status
, sizeof (compose_status
));
11151 if (dpyinfo
->grabbed
11152 && last_mouse_frame
11153 && FRAME_LIVE_P (last_mouse_frame
))
11154 f
= last_mouse_frame
;
11156 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
11160 /* Is this in the tool-bar? */
11161 if (WINDOWP (f
->tool_bar_window
)
11162 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
11164 Lisp_Object window
;
11167 x
= event
.xbutton
.x
;
11168 y
= event
.xbutton
.y
;
11171 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
11172 if (EQ (window
, f
->tool_bar_window
))
11174 x_handle_tool_bar_click (f
, &event
.xbutton
);
11180 if (!dpyinfo
->x_focus_frame
11181 || f
== dpyinfo
->x_focus_frame
)
11182 construct_mouse_click (&emacs_event
, &event
, f
);
11186 #ifndef USE_TOOLKIT_SCROLL_BARS
11187 struct scroll_bar
*bar
11188 = x_window_to_scroll_bar (event
.xbutton
.window
);
11191 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
11192 #endif /* not USE_TOOLKIT_SCROLL_BARS */
11195 if (event
.type
== ButtonPress
)
11197 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
11198 last_mouse_frame
= f
;
11199 /* Ignore any mouse motion that happened
11200 before this event; any subsequent mouse-movement
11201 Emacs events should reflect only motion after
11202 the ButtonPress. */
11204 f
->mouse_moved
= 0;
11207 last_tool_bar_item
= -1;
11211 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
11214 if (numchars
>= 1 && emacs_event
.kind
!= NO_EVENT
)
11216 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
11222 #ifdef USE_X_TOOLKIT
11223 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
11224 /* For a down-event in the menu bar,
11225 don't pass it to Xt right now.
11226 Instead, save it away
11227 and we will pass it to Xt from kbd_buffer_get_event.
11228 That way, we can run some Lisp code first. */
11229 if (f
&& event
.type
== ButtonPress
11230 /* Verify the event is really within the menu bar
11231 and not just sent to it due to grabbing. */
11232 && event
.xbutton
.x
>= 0
11233 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
11234 && event
.xbutton
.y
>= 0
11235 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
11236 && event
.xbutton
.same_screen
)
11238 SET_SAVED_BUTTON_EVENT
;
11239 XSETFRAME (last_mouse_press_frame
, f
);
11241 else if (event
.type
== ButtonPress
)
11243 last_mouse_press_frame
= Qnil
;
11247 #ifdef USE_MOTIF /* This should do not harm for Lucid,
11248 but I am trying to be cautious. */
11249 else if (event
.type
== ButtonRelease
)
11251 if (!NILP (last_mouse_press_frame
))
11253 f
= XFRAME (last_mouse_press_frame
);
11254 if (f
->output_data
.x
)
11255 SET_SAVED_BUTTON_EVENT
;
11260 #endif /* USE_MOTIF */
11263 #endif /* USE_X_TOOLKIT */
11267 case CirculateNotify
:
11270 case CirculateRequest
:
11273 case VisibilityNotify
:
11276 case MappingNotify
:
11277 /* Someone has changed the keyboard mapping - update the
11279 switch (event
.xmapping
.request
)
11281 case MappingModifier
:
11282 x_find_modifier_meanings (dpyinfo
);
11283 /* This is meant to fall through. */
11284 case MappingKeyboard
:
11285 XRefreshKeyboardMapping (&event
.xmapping
);
11291 #ifdef USE_X_TOOLKIT
11293 XtDispatchEvent (&event
);
11295 #endif /* USE_X_TOOLKIT */
11302 *finish
= X_EVENT_GOTO_OUT
;
11306 *numcharsp
= numchars
;
11313 /* Handles the XEvent EVENT on display DISPLAY.
11314 This is used for event loops outside the normal event handling,
11315 i.e. looping while a popup menu or a dialog is posted. */
11317 x_dispatch_event (event
, display
)
11321 struct x_display_info
*dpyinfo
;
11322 struct input_event bufp
[10];
11323 struct input_event
*bufpp
= bufp
;
11327 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
11328 if (dpyinfo
->display
== display
)
11334 events
= handle_one_xevent (dpyinfo
,
11339 for (i
= 0; i
< events
; ++i
)
11340 kbd_buffer_store_event (&bufp
[i
]);
11345 /* Read events coming from the X server.
11346 This routine is called by the SIGIO handler.
11347 We return as soon as there are no more events to be read.
11349 Events representing keys are stored in buffer BUFP,
11350 which can hold up to NUMCHARS characters.
11351 We return the number of characters stored into the buffer,
11352 thus pretending to be `read'.
11354 EXPECTED is nonzero if the caller knows input is available. */
11357 XTread_socket (sd
, bufp
, numchars
, expected
)
11359 /* register */ struct input_event
*bufp
;
11360 /* register */ int numchars
;
11366 int event_found
= 0;
11367 struct x_display_info
*dpyinfo
;
11369 if (interrupt_input_blocked
)
11371 interrupt_input_pending
= 1;
11375 interrupt_input_pending
= 0;
11378 /* So people can tell when we have read the available input. */
11379 input_signal_count
++;
11382 abort (); /* Don't think this happens. */
11386 /* Find the display we are supposed to read input for.
11387 It's the one communicating on descriptor SD. */
11388 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
11390 #if 0 /* This ought to be unnecessary; let's verify it. */
11392 /* If available, Xlib uses FIOSNBIO to make the socket
11393 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
11394 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
11395 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
11396 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
11397 #endif /* ! defined (FIOSNBIO) */
11400 #if 0 /* This code can't be made to work, with multiple displays,
11401 and appears not to be used on any system any more.
11402 Also keyboard.c doesn't turn O_NDELAY on and off
11403 for X connections. */
11405 #ifndef HAVE_SELECT
11406 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
11408 extern int read_alarm_should_throw
;
11409 read_alarm_should_throw
= 1;
11410 XPeekEvent (dpyinfo
->display
, &event
);
11411 read_alarm_should_throw
= 0;
11413 #endif /* HAVE_SELECT */
11417 /* For debugging, this gives a way to fake an I/O error. */
11418 if (dpyinfo
== XTread_socket_fake_io_error
)
11420 XTread_socket_fake_io_error
= 0;
11421 x_io_error_quitter (dpyinfo
->display
);
11426 count
+= x_session_check_input (bufp
, &numchars
);
11430 while (XPending (dpyinfo
->display
))
11434 XNextEvent (dpyinfo
->display
, &event
);
11438 /* Filter events for the current X input method.
11439 XFilterEvent returns non-zero if the input method has
11440 consumed the event. We pass the frame's X window to
11441 XFilterEvent because that's the one for which the IC
11443 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
11444 event
.xclient
.window
);
11445 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
11451 count
+= handle_one_xevent (dpyinfo
,
11457 if (finish
== X_EVENT_GOTO_OUT
)
11464 /* On some systems, an X bug causes Emacs to get no more events
11465 when the window is destroyed. Detect that. (1994.) */
11468 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
11469 One XNOOP in 100 loops will make Emacs terminate.
11470 B. Bretthauer, 1994 */
11472 if (x_noop_count
>= 100)
11476 if (next_noop_dpyinfo
== 0)
11477 next_noop_dpyinfo
= x_display_list
;
11479 XNoOp (next_noop_dpyinfo
->display
);
11481 /* Each time we get here, cycle through the displays now open. */
11482 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
11486 /* If the focus was just given to an auto-raising frame,
11488 /* ??? This ought to be able to handle more than one such frame. */
11489 if (pending_autoraise_frame
)
11491 x_raise_frame (pending_autoraise_frame
);
11492 pending_autoraise_frame
= 0;
11503 /***********************************************************************
11505 ***********************************************************************/
11507 /* Notice when the text cursor of window W has been completely
11508 overwritten by a drawing operation that outputs glyphs in AREA
11509 starting at X0 and ending at X1 in the line starting at Y0 and
11510 ending at Y1. X coordinates are area-relative. X1 < 0 means all
11511 the rest of the line after X0 has been written. Y coordinates
11512 are window-relative. */
11515 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
11517 enum glyph_row_area area
;
11518 int x0
, y0
, x1
, y1
;
11520 if (area
== TEXT_AREA
&& w
->phys_cursor_on_p
)
11522 int cx0
= w
->phys_cursor
.x
;
11523 int cx1
= cx0
+ w
->phys_cursor_width
;
11524 int cy0
= w
->phys_cursor
.y
;
11525 int cy1
= cy0
+ w
->phys_cursor_height
;
11527 if (x0
<= cx0
&& (x1
< 0 || x1
>= cx1
))
11529 /* The cursor image will be completely removed from the
11530 screen if the output area intersects the cursor area in
11531 y-direction. When we draw in [y0 y1[, and some part of
11532 the cursor is at y < y0, that part must have been drawn
11533 before. When scrolling, the cursor is erased before
11534 actually scrolling, so we don't come here. When not
11535 scrolling, the rows above the old cursor row must have
11536 changed, and in this case these rows must have written
11537 over the cursor image.
11539 Likewise if part of the cursor is below y1, with the
11540 exception of the cursor being in the first blank row at
11541 the buffer and window end because update_text_area
11542 doesn't draw that row. (Except when it does, but
11543 that's handled in update_text_area.) */
11545 if (((y0
>= cy0
&& y0
< cy1
) || (y1
> cy0
&& y1
< cy1
))
11546 && w
->current_matrix
->rows
[w
->phys_cursor
.vpos
].displays_text_p
)
11547 w
->phys_cursor_on_p
= 0;
11553 /* Set clipping for output in glyph row ROW. W is the window in which
11554 we operate. GC is the graphics context to set clipping in.
11555 WHOLE_LINE_P non-zero means include the areas used for truncation
11556 mark display and alike in the clipping rectangle.
11558 ROW may be a text row or, e.g., a mode line. Text rows must be
11559 clipped to the interior of the window dedicated to text display,
11560 mode lines must be clipped to the whole window. */
11563 x_clip_to_row (w
, row
, gc
, whole_line_p
)
11565 struct glyph_row
*row
;
11569 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11570 XRectangle clip_rect
;
11571 int window_x
, window_y
, window_width
, window_height
;
11573 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
11575 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
11576 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
11577 clip_rect
.y
= max (clip_rect
.y
, window_y
);
11578 clip_rect
.width
= window_width
;
11579 clip_rect
.height
= row
->visible_height
;
11581 /* If clipping to the whole line, including trunc marks, extend
11582 the rectangle to the left and increase its width. */
11585 clip_rect
.x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
11586 clip_rect
.width
+= FRAME_X_FRINGE_WIDTH (f
);
11589 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
11593 /* Draw a hollow box cursor on window W in glyph row ROW. */
11596 x_draw_hollow_cursor (w
, row
)
11598 struct glyph_row
*row
;
11600 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11601 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11602 Display
*dpy
= FRAME_X_DISPLAY (f
);
11605 struct glyph
*cursor_glyph
;
11608 /* Compute frame-relative coordinates from window-relative
11610 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11611 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
11612 + row
->ascent
- w
->phys_cursor_ascent
);
11613 h
= row
->height
- 1;
11615 /* Get the glyph the cursor is on. If we can't tell because
11616 the current matrix is invalid or such, give up. */
11617 cursor_glyph
= get_phys_cursor_glyph (w
);
11618 if (cursor_glyph
== NULL
)
11621 /* Compute the width of the rectangle to draw. If on a stretch
11622 glyph, and `x-stretch-block-cursor' is nil, don't draw a
11623 rectangle as wide as the glyph, but use a canonical character
11625 wd
= cursor_glyph
->pixel_width
- 1;
11626 if (cursor_glyph
->type
== STRETCH_GLYPH
11627 && !x_stretch_cursor_p
)
11628 wd
= min (CANON_X_UNIT (f
), wd
);
11629 w
->phys_cursor_width
= wd
;
11631 /* The foreground of cursor_gc is typically the same as the normal
11632 background color, which can cause the cursor box to be invisible. */
11633 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11634 if (dpyinfo
->scratch_cursor_gc
)
11635 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
11637 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
11638 GCForeground
, &xgcv
);
11639 gc
= dpyinfo
->scratch_cursor_gc
;
11641 /* Set clipping, draw the rectangle, and reset clipping again. */
11642 x_clip_to_row (w
, row
, gc
, 0);
11643 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
11644 XSetClipMask (dpy
, gc
, None
);
11648 /* Draw a bar cursor on window W in glyph row ROW.
11650 Implementation note: One would like to draw a bar cursor with an
11651 angle equal to the one given by the font property XA_ITALIC_ANGLE.
11652 Unfortunately, I didn't find a font yet that has this property set.
11656 x_draw_bar_cursor (w
, row
, width
, kind
)
11658 struct glyph_row
*row
;
11660 enum text_cursor_kinds kind
;
11662 struct frame
*f
= XFRAME (w
->frame
);
11663 struct glyph
*cursor_glyph
;
11665 /* If cursor is out of bounds, don't draw garbage. This can happen
11666 in mini-buffer windows when switching between echo area glyphs
11667 and mini-buffer. */
11668 cursor_glyph
= get_phys_cursor_glyph (w
);
11669 if (cursor_glyph
== NULL
)
11672 /* If on an image, draw like a normal cursor. That's usually better
11673 visible than drawing a bar, esp. if the image is large so that
11674 the bar might not be in the window. */
11675 if (cursor_glyph
->type
== IMAGE_GLYPH
)
11677 struct glyph_row
*row
;
11678 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
11679 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
11683 Display
*dpy
= FRAME_X_DISPLAY (f
);
11684 Window window
= FRAME_X_WINDOW (f
);
11685 GC gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
11686 unsigned long mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
11687 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
11690 /* If the glyph's background equals the color we normally draw
11691 the bar cursor in, the bar cursor in its normal color is
11692 invisible. Use the glyph's foreground color instead in this
11693 case, on the assumption that the glyph's colors are chosen so
11694 that the glyph is legible. */
11695 if (face
->background
== f
->output_data
.x
->cursor_pixel
)
11696 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
11698 xgcv
.background
= xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11699 xgcv
.graphics_exposures
= 0;
11702 XChangeGC (dpy
, gc
, mask
, &xgcv
);
11705 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
11706 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
11710 width
= FRAME_CURSOR_WIDTH (f
);
11711 width
= min (cursor_glyph
->pixel_width
, width
);
11713 w
->phys_cursor_width
= width
;
11714 x_clip_to_row (w
, row
, gc
, 0);
11716 if (kind
== BAR_CURSOR
)
11717 XFillRectangle (dpy
, window
, gc
,
11718 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11719 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
11720 width
, row
->height
);
11722 XFillRectangle (dpy
, window
, gc
,
11723 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11724 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
11725 row
->height
- width
),
11726 cursor_glyph
->pixel_width
,
11729 XSetClipMask (dpy
, gc
, None
);
11734 /* Clear the cursor of window W to background color, and mark the
11735 cursor as not shown. This is used when the text where the cursor
11736 is is about to be rewritten. */
11742 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11743 x_update_window_cursor (w
, 0);
11747 /* Draw the cursor glyph of window W in glyph row ROW. See the
11748 comment of x_draw_glyphs for the meaning of HL. */
11751 x_draw_phys_cursor_glyph (w
, row
, hl
)
11753 struct glyph_row
*row
;
11754 enum draw_glyphs_face hl
;
11756 /* If cursor hpos is out of bounds, don't draw garbage. This can
11757 happen in mini-buffer windows when switching between echo area
11758 glyphs and mini-buffer. */
11759 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11761 int on_p
= w
->phys_cursor_on_p
;
11764 x1
= x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11765 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11767 w
->phys_cursor_on_p
= on_p
;
11769 if (hl
== DRAW_CURSOR
)
11770 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
11772 /* When we erase the cursor, and ROW is overlapped by other
11773 rows, make sure that these overlapping parts of other rows
11775 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11777 if (row
> w
->current_matrix
->rows
11778 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11779 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11781 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11782 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11783 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11789 /* Erase the image of a cursor of window W from the screen. */
11792 x_erase_phys_cursor (w
)
11795 struct frame
*f
= XFRAME (w
->frame
);
11796 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11797 int hpos
= w
->phys_cursor
.hpos
;
11798 int vpos
= w
->phys_cursor
.vpos
;
11799 int mouse_face_here_p
= 0;
11800 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11801 struct glyph_row
*cursor_row
;
11802 struct glyph
*cursor_glyph
;
11803 enum draw_glyphs_face hl
;
11805 /* No cursor displayed or row invalidated => nothing to do on the
11807 if (w
->phys_cursor_type
== NO_CURSOR
)
11808 goto mark_cursor_off
;
11810 /* VPOS >= active_glyphs->nrows means that window has been resized.
11811 Don't bother to erase the cursor. */
11812 if (vpos
>= active_glyphs
->nrows
)
11813 goto mark_cursor_off
;
11815 /* If row containing cursor is marked invalid, there is nothing we
11817 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11818 if (!cursor_row
->enabled_p
)
11819 goto mark_cursor_off
;
11821 /* If row is completely invisible, don't attempt to delete a cursor which
11822 isn't there. This can happen if cursor is at top of a window, and
11823 we switch to a buffer with a header line in that window. */
11824 if (cursor_row
->visible_height
<= 0)
11825 goto mark_cursor_off
;
11827 /* This can happen when the new row is shorter than the old one.
11828 In this case, either x_draw_glyphs or clear_end_of_line
11829 should have cleared the cursor. Note that we wouldn't be
11830 able to erase the cursor in this case because we don't have a
11831 cursor glyph at hand. */
11832 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11833 goto mark_cursor_off
;
11835 /* If the cursor is in the mouse face area, redisplay that when
11836 we clear the cursor. */
11837 if (! NILP (dpyinfo
->mouse_face_window
)
11838 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11839 && (vpos
> dpyinfo
->mouse_face_beg_row
11840 || (vpos
== dpyinfo
->mouse_face_beg_row
11841 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11842 && (vpos
< dpyinfo
->mouse_face_end_row
11843 || (vpos
== dpyinfo
->mouse_face_end_row
11844 && hpos
< dpyinfo
->mouse_face_end_col
))
11845 /* Don't redraw the cursor's spot in mouse face if it is at the
11846 end of a line (on a newline). The cursor appears there, but
11847 mouse highlighting does not. */
11848 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11849 mouse_face_here_p
= 1;
11851 /* Maybe clear the display under the cursor. */
11852 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11855 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11857 cursor_glyph
= get_phys_cursor_glyph (w
);
11858 if (cursor_glyph
== NULL
)
11859 goto mark_cursor_off
;
11861 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11863 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11865 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11867 cursor_glyph
->pixel_width
,
11868 cursor_row
->visible_height
,
11872 /* Erase the cursor by redrawing the character underneath it. */
11873 if (mouse_face_here_p
)
11874 hl
= DRAW_MOUSE_FACE
;
11876 hl
= DRAW_NORMAL_TEXT
;
11877 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11880 w
->phys_cursor_on_p
= 0;
11881 w
->phys_cursor_type
= NO_CURSOR
;
11885 /* Non-zero if physical cursor of window W is within mouse face. */
11888 cursor_in_mouse_face_p (w
)
11891 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
11892 int in_mouse_face
= 0;
11894 if (WINDOWP (dpyinfo
->mouse_face_window
)
11895 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
11897 int hpos
= w
->phys_cursor
.hpos
;
11898 int vpos
= w
->phys_cursor
.vpos
;
11900 if (vpos
>= dpyinfo
->mouse_face_beg_row
11901 && vpos
<= dpyinfo
->mouse_face_end_row
11902 && (vpos
> dpyinfo
->mouse_face_beg_row
11903 || hpos
>= dpyinfo
->mouse_face_beg_col
)
11904 && (vpos
< dpyinfo
->mouse_face_end_row
11905 || hpos
< dpyinfo
->mouse_face_end_col
11906 || dpyinfo
->mouse_face_past_end
))
11910 return in_mouse_face
;
11914 /* Display or clear cursor of window W. If ON is zero, clear the
11915 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11916 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11919 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11921 int on
, hpos
, vpos
, x
, y
;
11923 struct frame
*f
= XFRAME (w
->frame
);
11924 int new_cursor_type
;
11925 int new_cursor_width
;
11927 struct glyph_matrix
*current_glyphs
;
11928 struct glyph_row
*glyph_row
;
11929 struct glyph
*glyph
;
11931 /* This is pointless on invisible frames, and dangerous on garbaged
11932 windows and frames; in the latter case, the frame or window may
11933 be in the midst of changing its size, and x and y may be off the
11935 if (! FRAME_VISIBLE_P (f
)
11936 || FRAME_GARBAGED_P (f
)
11937 || vpos
>= w
->current_matrix
->nrows
11938 || hpos
>= w
->current_matrix
->matrix_w
)
11941 /* If cursor is off and we want it off, return quickly. */
11942 if (!on
&& !w
->phys_cursor_on_p
)
11945 current_glyphs
= w
->current_matrix
;
11946 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11947 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11949 /* If cursor row is not enabled, we don't really know where to
11950 display the cursor. */
11951 if (!glyph_row
->enabled_p
)
11953 w
->phys_cursor_on_p
= 0;
11957 xassert (interrupt_input_blocked
);
11959 /* Set new_cursor_type to the cursor we want to be displayed. */
11960 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
11962 /* If cursor is currently being shown and we don't want it to be or
11963 it is in the wrong place, or the cursor type is not what we want,
11965 if (w
->phys_cursor_on_p
11967 || w
->phys_cursor
.x
!= x
11968 || w
->phys_cursor
.y
!= y
11969 || new_cursor_type
!= w
->phys_cursor_type
11970 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
11971 && new_cursor_width
!= w
->phys_cursor_width
)))
11972 x_erase_phys_cursor (w
);
11974 /* Don't check phys_cursor_on_p here because that flag is only set
11975 to zero in some cases where we know that the cursor has been
11976 completely erased, to avoid the extra work of erasing the cursor
11977 twice. In other words, phys_cursor_on_p can be 1 and the cursor
11978 still not be visible, or it has only been partly erased. */
11981 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11982 w
->phys_cursor_height
= glyph_row
->height
;
11984 /* Set phys_cursor_.* before x_draw_.* is called because some
11985 of them may need the information. */
11986 w
->phys_cursor
.x
= x
;
11987 w
->phys_cursor
.y
= glyph_row
->y
;
11988 w
->phys_cursor
.hpos
= hpos
;
11989 w
->phys_cursor
.vpos
= vpos
;
11990 w
->phys_cursor_type
= new_cursor_type
;
11991 w
->phys_cursor_on_p
= 1;
11993 switch (new_cursor_type
)
11995 case HOLLOW_BOX_CURSOR
:
11996 x_draw_hollow_cursor (w
, glyph_row
);
11999 case FILLED_BOX_CURSOR
:
12000 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
12004 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, BAR_CURSOR
);
12008 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, HBAR_CURSOR
);
12012 w
->phys_cursor_width
= 0;
12020 if (w
== XWINDOW (f
->selected_window
))
12021 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
12022 xic_set_preeditarea (w
, x
, y
);
12027 if (updating_frame
!= f
)
12028 XFlush (FRAME_X_DISPLAY (f
));
12033 /* Display the cursor on window W, or clear it. X and Y are window
12034 relative pixel coordinates. HPOS and VPOS are glyph matrix
12035 positions. If W is not the selected window, display a hollow
12036 cursor. ON non-zero means display the cursor at X, Y which
12037 correspond to HPOS, VPOS, otherwise it is cleared. */
12040 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
12042 int on
, hpos
, vpos
, x
, y
;
12045 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
12050 /* Display the cursor on window W, or clear it, according to ON_P.
12051 Don't change the cursor's position. */
12054 x_update_cursor (f
, on_p
)
12058 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
12062 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
12063 in the window tree rooted at W. */
12066 x_update_cursor_in_window_tree (w
, on_p
)
12072 if (!NILP (w
->hchild
))
12073 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
12074 else if (!NILP (w
->vchild
))
12075 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
12077 x_update_window_cursor (w
, on_p
);
12079 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
12084 /* Switch the display of W's cursor on or off, according to the value
12088 x_update_window_cursor (w
, on
)
12092 /* Don't update cursor in windows whose frame is in the process
12093 of being deleted. */
12094 if (w
->current_matrix
)
12097 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
12098 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
12108 /* Make the x-window of frame F use the gnu icon bitmap. */
12111 x_bitmap_icon (f
, file
)
12117 if (FRAME_X_WINDOW (f
) == 0)
12120 /* Free up our existing icon bitmap if any. */
12121 if (f
->output_data
.x
->icon_bitmap
> 0)
12122 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
12123 f
->output_data
.x
->icon_bitmap
= 0;
12125 if (STRINGP (file
))
12126 bitmap_id
= x_create_bitmap_from_file (f
, file
);
12129 /* Create the GNU bitmap if necessary. */
12130 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
12131 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
12132 = x_create_bitmap_from_data (f
, gnu_bits
,
12133 gnu_width
, gnu_height
);
12135 /* The first time we create the GNU bitmap,
12136 this increments the ref-count one extra time.
12137 As a result, the GNU bitmap is never freed.
12138 That way, we don't have to worry about allocating it again. */
12139 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
12141 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
12144 x_wm_set_icon_pixmap (f
, bitmap_id
);
12145 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
12151 /* Make the x-window of frame F use a rectangle with text.
12152 Use ICON_NAME as the text. */
12155 x_text_icon (f
, icon_name
)
12159 if (FRAME_X_WINDOW (f
) == 0)
12164 XTextProperty text
;
12165 text
.value
= (unsigned char *) icon_name
;
12166 text
.encoding
= XA_STRING
;
12168 text
.nitems
= strlen (icon_name
);
12169 #ifdef USE_X_TOOLKIT
12170 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12172 #else /* not USE_X_TOOLKIT */
12173 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
12174 #endif /* not USE_X_TOOLKIT */
12176 #else /* not HAVE_X11R4 */
12177 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
12178 #endif /* not HAVE_X11R4 */
12180 if (f
->output_data
.x
->icon_bitmap
> 0)
12181 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
12182 f
->output_data
.x
->icon_bitmap
= 0;
12183 x_wm_set_icon_pixmap (f
, 0);
12188 #define X_ERROR_MESSAGE_SIZE 200
12190 /* If non-nil, this should be a string.
12191 It means catch X errors and store the error message in this string. */
12193 static Lisp_Object x_error_message_string
;
12195 /* An X error handler which stores the error message in
12196 x_error_message_string. This is called from x_error_handler if
12197 x_catch_errors is in effect. */
12200 x_error_catcher (display
, error
)
12202 XErrorEvent
*error
;
12204 XGetErrorText (display
, error
->error_code
,
12205 SDATA (x_error_message_string
),
12206 X_ERROR_MESSAGE_SIZE
);
12209 /* Begin trapping X errors for display DPY. Actually we trap X errors
12210 for all displays, but DPY should be the display you are actually
12213 After calling this function, X protocol errors no longer cause
12214 Emacs to exit; instead, they are recorded in the string
12215 stored in x_error_message_string.
12217 Calling x_check_errors signals an Emacs error if an X error has
12218 occurred since the last call to x_catch_errors or x_check_errors.
12220 Calling x_uncatch_errors resumes the normal error handling. */
12222 void x_check_errors ();
12223 static Lisp_Object
x_catch_errors_unwind ();
12226 x_catch_errors (dpy
)
12229 int count
= SPECPDL_INDEX ();
12231 /* Make sure any errors from previous requests have been dealt with. */
12232 XSync (dpy
, False
);
12234 record_unwind_protect (x_catch_errors_unwind
,
12235 Fcons (make_save_value (dpy
, 0),
12236 x_error_message_string
));
12238 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
12239 SSET (x_error_message_string
, 0, 0);
12244 /* Unbind the binding that we made to check for X errors. */
12247 x_catch_errors_unwind (old_val
)
12248 Lisp_Object old_val
;
12252 first
= XCAR (old_val
);
12254 XSync (XSAVE_VALUE (first
)->pointer
, False
);
12256 x_error_message_string
= XCDR (old_val
);
12260 /* If any X protocol errors have arrived since the last call to
12261 x_catch_errors or x_check_errors, signal an Emacs error using
12262 sprintf (a buffer, FORMAT, the x error message text) as the text. */
12265 x_check_errors (dpy
, format
)
12269 /* Make sure to catch any errors incurred so far. */
12270 XSync (dpy
, False
);
12272 if (SREF (x_error_message_string
, 0))
12273 error (format
, SDATA (x_error_message_string
));
12276 /* Nonzero if we had any X protocol errors
12277 since we did x_catch_errors on DPY. */
12280 x_had_errors_p (dpy
)
12283 /* Make sure to catch any errors incurred so far. */
12284 XSync (dpy
, False
);
12286 return SREF (x_error_message_string
, 0) != 0;
12289 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
12292 x_clear_errors (dpy
)
12295 SSET (x_error_message_string
, 0, 0);
12298 /* Stop catching X protocol errors and let them make Emacs die.
12299 DPY should be the display that was passed to x_catch_errors.
12300 COUNT should be the value that was returned by
12301 the corresponding call to x_catch_errors. */
12304 x_uncatch_errors (dpy
, count
)
12308 unbind_to (count
, Qnil
);
12312 static unsigned int x_wire_count
;
12315 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
12320 /* Handle SIGPIPE, which can happen when the connection to a server
12321 simply goes away. SIGPIPE is handled by x_connection_signal.
12322 Don't need to do anything, because the write which caused the
12323 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
12324 which will do the appropriate cleanup for us. */
12327 x_connection_signal (signalnum
) /* If we don't have an argument, */
12328 int signalnum
; /* some compilers complain in signal calls. */
12331 /* USG systems forget handlers when they are used;
12332 must reestablish each time */
12333 signal (signalnum
, x_connection_signal
);
12338 /************************************************************************
12340 ************************************************************************/
12342 /* Error message passed to x_connection_closed. */
12344 static char *error_msg
;
12346 /* Function installed as fatal_error_signal_hook in
12347 x_connection_closed. Print the X error message, and exit normally,
12348 instead of dumping core when XtCloseDisplay fails. */
12351 x_fatal_error_signal ()
12353 fprintf (stderr
, "%s\n", error_msg
);
12357 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
12358 the text of an error message that lead to the connection loss. */
12361 x_connection_closed (dpy
, error_message
)
12363 char *error_message
;
12365 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
12366 Lisp_Object frame
, tail
;
12369 error_msg
= (char *) alloca (strlen (error_message
) + 1);
12370 strcpy (error_msg
, error_message
);
12371 handling_signal
= 0;
12373 /* Prevent being called recursively because of an error condition
12374 below. Otherwise, we might end up with printing ``can't find per
12375 display information'' in the recursive call instead of printing
12376 the original message here. */
12377 count
= x_catch_errors (dpy
);
12379 /* We have to close the display to inform Xt that it doesn't
12380 exist anymore. If we don't, Xt will continue to wait for
12381 events from the display. As a consequence, a sequence of
12383 M-x make-frame-on-display RET :1 RET
12384 ...kill the new frame, so that we get an IO error...
12385 M-x make-frame-on-display RET :1 RET
12387 will indefinitely wait in Xt for events for display `:1', opened
12388 in the first class to make-frame-on-display.
12390 Closing the display is reported to lead to a bus error on
12391 OpenWindows in certain situations. I suspect that is a bug
12392 in OpenWindows. I don't know how to cicumvent it here. */
12394 #ifdef USE_X_TOOLKIT
12395 /* If DPYINFO is null, this means we didn't open the display
12396 in the first place, so don't try to close it. */
12399 extern void (*fatal_error_signal_hook
) P_ ((void));
12400 fatal_error_signal_hook
= x_fatal_error_signal
;
12401 XtCloseDisplay (dpy
);
12402 fatal_error_signal_hook
= NULL
;
12406 /* Indicate that this display is dead. */
12408 dpyinfo
->display
= 0;
12410 /* First delete frames whose mini-buffers are on frames
12411 that are on the dead display. */
12412 FOR_EACH_FRAME (tail
, frame
)
12414 Lisp_Object minibuf_frame
;
12416 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
12417 if (FRAME_X_P (XFRAME (frame
))
12418 && FRAME_X_P (XFRAME (minibuf_frame
))
12419 && ! EQ (frame
, minibuf_frame
)
12420 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
12421 Fdelete_frame (frame
, Qt
);
12424 /* Now delete all remaining frames on the dead display.
12425 We are now sure none of these is used as the mini-buffer
12426 for another frame that we need to delete. */
12427 FOR_EACH_FRAME (tail
, frame
)
12428 if (FRAME_X_P (XFRAME (frame
))
12429 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
12431 /* Set this to t so that Fdelete_frame won't get confused
12432 trying to find a replacement. */
12433 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
12434 Fdelete_frame (frame
, Qt
);
12438 x_delete_display (dpyinfo
);
12440 x_uncatch_errors (dpy
, count
);
12442 if (x_display_list
== 0)
12444 fprintf (stderr
, "%s\n", error_msg
);
12445 shut_down_emacs (0, 0, Qnil
);
12449 /* Ordinary stack unwind doesn't deal with these. */
12451 sigunblock (sigmask (SIGIO
));
12453 sigunblock (sigmask (SIGALRM
));
12454 TOTALLY_UNBLOCK_INPUT
;
12456 clear_waiting_for_input ();
12457 error ("%s", error_msg
);
12461 /* This is the usual handler for X protocol errors.
12462 It kills all frames on the display that we got the error for.
12463 If that was the only one, it prints an error message and kills Emacs. */
12466 x_error_quitter (display
, error
)
12468 XErrorEvent
*error
;
12470 char buf
[256], buf1
[356];
12472 /* Note that there is no real way portable across R3/R4 to get the
12473 original error handler. */
12475 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
12476 sprintf (buf1
, "X protocol error: %s on protocol request %d",
12477 buf
, error
->request_code
);
12478 x_connection_closed (display
, buf1
);
12482 /* This is the first-level handler for X protocol errors.
12483 It calls x_error_quitter or x_error_catcher. */
12486 x_error_handler (display
, error
)
12488 XErrorEvent
*error
;
12490 if (! NILP (x_error_message_string
))
12491 x_error_catcher (display
, error
);
12493 x_error_quitter (display
, error
);
12497 /* This is the handler for X IO errors, always.
12498 It kills all frames on the display that we lost touch with.
12499 If that was the only one, it prints an error message and kills Emacs. */
12502 x_io_error_quitter (display
)
12507 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
12508 x_connection_closed (display
, buf
);
12512 /* Changing the font of the frame. */
12514 /* Give frame F the font named FONTNAME as its default font, and
12515 return the full name of that font. FONTNAME may be a wildcard
12516 pattern; in that case, we choose some font that fits the pattern.
12517 The return value shows which font we chose. */
12520 x_new_font (f
, fontname
)
12522 register char *fontname
;
12524 struct font_info
*fontp
12525 = FS_LOAD_FONT (f
, 0, fontname
, -1);
12530 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
12531 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
12532 f
->output_data
.x
->fontset
= -1;
12534 x_compute_fringe_widths (f
, 1);
12536 /* Compute the scroll bar width in character columns. */
12537 if (f
->scroll_bar_pixel_width
> 0)
12539 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12540 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
12544 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12545 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
12548 /* Now make the frame display the given font. */
12549 if (FRAME_X_WINDOW (f
) != 0)
12551 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
12552 f
->output_data
.x
->font
->fid
);
12553 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
12554 f
->output_data
.x
->font
->fid
);
12555 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
12556 f
->output_data
.x
->font
->fid
);
12558 frame_update_line_height (f
);
12560 /* Don't change the size of a tip frame; there's no point in
12561 doing it because it's done in Fx_show_tip, and it leads to
12562 problems because the tip frame has no widget. */
12563 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
12564 x_set_window_size (f
, 0, f
->width
, f
->height
);
12567 /* If we are setting a new frame's font for the first time,
12568 there are no faces yet, so this font's height is the line height. */
12569 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
12571 return build_string (fontp
->full_name
);
12574 /* Give frame F the fontset named FONTSETNAME as its default font, and
12575 return the full name of that fontset. FONTSETNAME may be a wildcard
12576 pattern; in that case, we choose some fontset that fits the pattern.
12577 The return value shows which fontset we chose. */
12580 x_new_fontset (f
, fontsetname
)
12584 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
12585 Lisp_Object result
;
12590 if (f
->output_data
.x
->fontset
== fontset
)
12591 /* This fontset is already set in frame F. There's nothing more
12593 return fontset_name (fontset
);
12595 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
12597 if (!STRINGP (result
))
12598 /* Can't load ASCII font. */
12601 /* Since x_new_font doesn't update any fontset information, do it now. */
12602 f
->output_data
.x
->fontset
= fontset
;
12606 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
12607 xic_set_xfontset (f
, SDATA (fontset_ascii (fontset
)));
12610 return build_string (fontsetname
);
12613 /* Compute actual fringe widths */
12616 x_compute_fringe_widths (f
, redraw
)
12620 int o_left
= f
->output_data
.x
->left_fringe_width
;
12621 int o_right
= f
->output_data
.x
->right_fringe_width
;
12622 int o_cols
= f
->output_data
.x
->fringe_cols
;
12624 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
12625 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
12626 int left_fringe_width
, right_fringe_width
;
12628 if (!NILP (left_fringe
))
12629 left_fringe
= Fcdr (left_fringe
);
12630 if (!NILP (right_fringe
))
12631 right_fringe
= Fcdr (right_fringe
);
12633 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
12634 XINT (left_fringe
));
12635 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
12636 XINT (right_fringe
));
12638 if (left_fringe_width
|| right_fringe_width
)
12640 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
12641 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
12642 int conf_wid
= left_wid
+ right_wid
;
12643 int font_wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12644 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
12645 int real_wid
= cols
* font_wid
;
12646 if (left_wid
&& right_wid
)
12648 if (left_fringe_width
< 0)
12650 /* Left fringe width is fixed, adjust right fringe if necessary */
12651 f
->output_data
.x
->left_fringe_width
= left_wid
;
12652 f
->output_data
.x
->right_fringe_width
= real_wid
- left_wid
;
12654 else if (right_fringe_width
< 0)
12656 /* Right fringe width is fixed, adjust left fringe if necessary */
12657 f
->output_data
.x
->left_fringe_width
= real_wid
- right_wid
;
12658 f
->output_data
.x
->right_fringe_width
= right_wid
;
12662 /* Adjust both fringes with an equal amount.
12663 Note that we are doing integer arithmetic here, so don't
12664 lose a pixel if the total width is an odd number. */
12665 int fill
= real_wid
- conf_wid
;
12666 f
->output_data
.x
->left_fringe_width
= left_wid
+ fill
/2;
12667 f
->output_data
.x
->right_fringe_width
= right_wid
+ fill
- fill
/2;
12670 else if (left_fringe_width
)
12672 f
->output_data
.x
->left_fringe_width
= real_wid
;
12673 f
->output_data
.x
->right_fringe_width
= 0;
12677 f
->output_data
.x
->left_fringe_width
= 0;
12678 f
->output_data
.x
->right_fringe_width
= real_wid
;
12680 f
->output_data
.x
->fringe_cols
= cols
;
12681 f
->output_data
.x
->fringes_extra
= real_wid
;
12685 f
->output_data
.x
->left_fringe_width
= 0;
12686 f
->output_data
.x
->right_fringe_width
= 0;
12687 f
->output_data
.x
->fringe_cols
= 0;
12688 f
->output_data
.x
->fringes_extra
= 0;
12691 if (redraw
&& FRAME_VISIBLE_P (f
))
12692 if (o_left
!= f
->output_data
.x
->left_fringe_width
||
12693 o_right
!= f
->output_data
.x
->right_fringe_width
||
12694 o_cols
!= f
->output_data
.x
->fringe_cols
)
12698 /***********************************************************************
12700 ***********************************************************************/
12706 /* XIM destroy callback function, which is called whenever the
12707 connection to input method XIM dies. CLIENT_DATA contains a
12708 pointer to the x_display_info structure corresponding to XIM. */
12711 xim_destroy_callback (xim
, client_data
, call_data
)
12713 XPointer client_data
;
12714 XPointer call_data
;
12716 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
12717 Lisp_Object frame
, tail
;
12721 /* No need to call XDestroyIC.. */
12722 FOR_EACH_FRAME (tail
, frame
)
12724 struct frame
*f
= XFRAME (frame
);
12725 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
12727 FRAME_XIC (f
) = NULL
;
12728 if (FRAME_XIC_FONTSET (f
))
12730 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
12731 FRAME_XIC_FONTSET (f
) = NULL
;
12736 /* No need to call XCloseIM. */
12737 dpyinfo
->xim
= NULL
;
12738 XFree (dpyinfo
->xim_styles
);
12742 #endif /* HAVE_X11R6 */
12745 /* This isn't prototyped in OSF 5.0 or 5.1a. */
12746 extern char *XSetIMValues
P_ ((XIM
, ...));
12749 /* Open the connection to the XIM server on display DPYINFO.
12750 RESOURCE_NAME is the resource name Emacs uses. */
12753 xim_open_dpy (dpyinfo
, resource_name
)
12754 struct x_display_info
*dpyinfo
;
12755 char *resource_name
;
12760 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
12761 dpyinfo
->xim
= xim
;
12766 XIMCallback destroy
;
12769 /* Get supported styles and XIM values. */
12770 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
12773 destroy
.callback
= xim_destroy_callback
;
12774 destroy
.client_data
= (XPointer
)dpyinfo
;
12775 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
12779 #else /* not USE_XIM */
12780 dpyinfo
->xim
= NULL
;
12781 #endif /* not USE_XIM */
12785 #ifdef HAVE_X11R6_XIM
12789 struct x_display_info
*dpyinfo
;
12790 char *resource_name
;
12793 /* XIM instantiate callback function, which is called whenever an XIM
12794 server is available. DISPLAY is teh display of the XIM.
12795 CLIENT_DATA contains a pointer to an xim_inst_t structure created
12796 when the callback was registered. */
12799 xim_instantiate_callback (display
, client_data
, call_data
)
12801 XPointer client_data
;
12802 XPointer call_data
;
12804 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
12805 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
12807 /* We don't support multiple XIM connections. */
12811 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
12813 /* Create XIC for the existing frames on the same display, as long
12814 as they have no XIC. */
12815 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
12817 Lisp_Object tail
, frame
;
12820 FOR_EACH_FRAME (tail
, frame
)
12822 struct frame
*f
= XFRAME (frame
);
12824 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
12825 if (FRAME_XIC (f
) == NULL
)
12827 create_frame_xic (f
);
12828 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
12829 xic_set_statusarea (f
);
12830 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
12832 struct window
*w
= XWINDOW (f
->selected_window
);
12833 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
12842 #endif /* HAVE_X11R6_XIM */
12845 /* Open a connection to the XIM server on display DPYINFO.
12846 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
12847 connection only at the first time. On X11R6, open the connection
12848 in the XIM instantiate callback function. */
12851 xim_initialize (dpyinfo
, resource_name
)
12852 struct x_display_info
*dpyinfo
;
12853 char *resource_name
;
12856 #ifdef HAVE_X11R6_XIM
12857 struct xim_inst_t
*xim_inst
;
12860 dpyinfo
->xim
= NULL
;
12861 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12862 xim_inst
->dpyinfo
= dpyinfo
;
12863 len
= strlen (resource_name
);
12864 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12865 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12866 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12867 resource_name
, EMACS_CLASS
,
12868 xim_instantiate_callback
,
12869 /* Fixme: This is XPointer in
12870 XFree86 but (XPointer *) on
12871 Tru64, at least. */
12872 (XPointer
) xim_inst
);
12873 #else /* not HAVE_X11R6_XIM */
12874 dpyinfo
->xim
= NULL
;
12875 xim_open_dpy (dpyinfo
, resource_name
);
12876 #endif /* not HAVE_X11R6_XIM */
12878 #else /* not USE_XIM */
12879 dpyinfo
->xim
= NULL
;
12880 #endif /* not USE_XIM */
12884 /* Close the connection to the XIM server on display DPYINFO. */
12887 xim_close_dpy (dpyinfo
)
12888 struct x_display_info
*dpyinfo
;
12891 #ifdef HAVE_X11R6_XIM
12892 if (dpyinfo
->display
)
12893 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12895 xim_instantiate_callback
, NULL
);
12896 #endif /* not HAVE_X11R6_XIM */
12897 if (dpyinfo
->display
)
12898 XCloseIM (dpyinfo
->xim
);
12899 dpyinfo
->xim
= NULL
;
12900 XFree (dpyinfo
->xim_styles
);
12901 #endif /* USE_XIM */
12904 #endif /* not HAVE_X11R6_XIM */
12908 /* Calculate the absolute position in frame F
12909 from its current recorded position values and gravity. */
12912 x_calc_absolute_position (f
)
12916 int win_x
= 0, win_y
= 0;
12917 int flags
= f
->output_data
.x
->size_hint_flags
;
12920 /* We have nothing to do if the current position
12921 is already for the top-left corner. */
12922 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12925 #ifdef USE_X_TOOLKIT
12926 this_window
= XtWindow (f
->output_data
.x
->widget
);
12928 this_window
= FRAME_X_WINDOW (f
);
12931 /* Find the position of the outside upper-left corner of
12932 the inner window, with respect to the outer window.
12933 But do this only if we will need the results. */
12934 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12939 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12942 x_clear_errors (FRAME_X_DISPLAY (f
));
12943 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12945 /* From-window, to-window. */
12947 f
->output_data
.x
->parent_desc
,
12949 /* From-position, to-position. */
12950 0, 0, &win_x
, &win_y
,
12952 /* Child of win. */
12954 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12956 Window newroot
, newparent
= 0xdeadbeef;
12957 Window
*newchildren
;
12958 unsigned int nchildren
;
12960 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12961 &newparent
, &newchildren
, &nchildren
))
12964 XFree ((char *) newchildren
);
12966 f
->output_data
.x
->parent_desc
= newparent
;
12972 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12976 /* Treat negative positions as relative to the leftmost bottommost
12977 position that fits on the screen. */
12978 if (flags
& XNegative
)
12979 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12980 - 2 * f
->output_data
.x
->border_width
- win_x
12982 + f
->output_data
.x
->left_pos
);
12985 int height
= PIXEL_HEIGHT (f
);
12987 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12988 /* Something is fishy here. When using Motif, starting Emacs with
12989 `-g -0-0', the frame appears too low by a few pixels.
12991 This seems to be so because initially, while Emacs is starting,
12992 the column widget's height and the frame's pixel height are
12993 different. The column widget's height is the right one. In
12994 later invocations, when Emacs is up, the frame's pixel height
12997 It's not obvious where the initial small difference comes from.
12998 2000-12-01, gerd. */
13000 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
13003 if (flags
& YNegative
)
13004 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
13005 - 2 * f
->output_data
.x
->border_width
13008 + f
->output_data
.x
->top_pos
);
13011 /* The left_pos and top_pos
13012 are now relative to the top and left screen edges,
13013 so the flags should correspond. */
13014 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
13017 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
13018 to really change the position, and 0 when calling from
13019 x_make_frame_visible (in that case, XOFF and YOFF are the current
13020 position values). It is -1 when calling from x_set_frame_parameters,
13021 which means, do adjust for borders but don't change the gravity. */
13024 x_set_offset (f
, xoff
, yoff
, change_gravity
)
13026 register int xoff
, yoff
;
13027 int change_gravity
;
13029 int modified_top
, modified_left
;
13031 if (change_gravity
> 0)
13033 f
->output_data
.x
->top_pos
= yoff
;
13034 f
->output_data
.x
->left_pos
= xoff
;
13035 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
13037 f
->output_data
.x
->size_hint_flags
|= XNegative
;
13039 f
->output_data
.x
->size_hint_flags
|= YNegative
;
13040 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
13042 x_calc_absolute_position (f
);
13045 x_wm_set_size_hint (f
, (long) 0, 0);
13047 modified_left
= f
->output_data
.x
->left_pos
;
13048 modified_top
= f
->output_data
.x
->top_pos
;
13049 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
13050 this seems to be unnecessary and incorrect. rms, 4/17/97. */
13051 /* It is a mystery why we need to add the border_width here
13052 when the frame is already visible, but experiment says we do. */
13053 if (change_gravity
!= 0)
13055 modified_left
+= f
->output_data
.x
->border_width
;
13056 modified_top
+= f
->output_data
.x
->border_width
;
13060 #ifdef USE_X_TOOLKIT
13061 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
13062 modified_left
, modified_top
);
13063 #else /* not USE_X_TOOLKIT */
13064 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
13065 modified_left
, modified_top
);
13066 #endif /* not USE_X_TOOLKIT */
13070 /* Check if we need to resize the frame due to a fullscreen request.
13071 If so needed, resize the frame. */
13073 x_check_fullscreen (f
)
13076 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_BOTH
)
13078 int width
, height
, ign
;
13080 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
13081 &f
->output_data
.x
->top_pos
);
13083 x_fullscreen_adjust (f
, &width
, &height
, &ign
, &ign
);
13085 /* We do not need to move the window, it shall be taken care of
13086 when setting WM manager hints.
13087 If the frame is visible already, the position is checked by
13088 x_check_fullscreen_move. */
13089 if (f
->width
!= width
|| f
->height
!= height
)
13091 change_frame_size (f
, height
, width
, 0, 1, 0);
13092 SET_FRAME_GARBAGED (f
);
13093 cancel_mouse_face (f
);
13095 /* Wait for the change of frame size to occur */
13096 f
->output_data
.x
->want_fullscreen
|= FULLSCREEN_WAIT
;
13102 /* If frame parameters are set after the frame is mapped, we need to move
13103 the window. This is done in xfns.c.
13104 Some window managers moves the window to the right position, some
13105 moves the outer window manager window to the specified position.
13106 Here we check that we are in the right spot. If not, make a second
13107 move, assuming we are dealing with the second kind of window manager. */
13109 x_check_fullscreen_move (f
)
13112 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_MOVE_WAIT
)
13114 int expect_top
= f
->output_data
.x
->top_pos
;
13115 int expect_left
= f
->output_data
.x
->left_pos
;
13117 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_HEIGHT
)
13119 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_WIDTH
)
13122 if (expect_top
!= f
->output_data
.x
->top_pos
13123 || expect_left
!= f
->output_data
.x
->left_pos
)
13124 x_set_offset (f
, expect_left
, expect_top
, 1);
13126 /* Just do this once */
13127 f
->output_data
.x
->want_fullscreen
&= ~FULLSCREEN_MOVE_WAIT
;
13132 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
13133 wanted positions of the WM window (not emacs window).
13134 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
13135 window (FRAME_X_WINDOW).
13138 x_fullscreen_adjust (f
, width
, height
, top_pos
, left_pos
)
13145 int newwidth
= f
->width
, newheight
= f
->height
;
13147 *top_pos
= f
->output_data
.x
->top_pos
;
13148 *left_pos
= f
->output_data
.x
->left_pos
;
13150 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_HEIGHT
)
13154 ph
= FRAME_X_DISPLAY_INFO (f
)->height
;
13155 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
13156 ph
= CHAR_TO_PIXEL_HEIGHT (f
, newheight
)
13157 - f
->output_data
.x
->y_pixels_diff
;
13158 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
13162 if (f
->output_data
.x
->want_fullscreen
& FULLSCREEN_WIDTH
)
13166 pw
= FRAME_X_DISPLAY_INFO (f
)->width
;
13167 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
13168 pw
= CHAR_TO_PIXEL_WIDTH (f
, newwidth
)
13169 - f
->output_data
.x
->x_pixels_diff
;
13170 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
13175 *height
= newheight
;
13179 /* Change the size of frame F's X window to COLS/ROWS in the case F
13180 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
13181 top-left-corner window gravity for this size change and subsequent
13182 size changes. Otherwise we leave the window gravity unchanged. */
13185 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
13187 int change_gravity
;
13190 int pixelwidth
, pixelheight
;
13192 check_frame_size (f
, &rows
, &cols
);
13193 f
->output_data
.x
->vertical_scroll_bar_extra
13194 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
13196 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
13197 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
13198 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
13200 x_compute_fringe_widths (f
, 0);
13202 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
13203 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
13205 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
13206 x_wm_set_size_hint (f
, (long) 0, 0);
13208 XSync (FRAME_X_DISPLAY (f
), False
);
13209 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
13210 pixelwidth
, pixelheight
);
13212 /* Now, strictly speaking, we can't be sure that this is accurate,
13213 but the window manager will get around to dealing with the size
13214 change request eventually, and we'll hear how it went when the
13215 ConfigureNotify event gets here.
13217 We could just not bother storing any of this information here,
13218 and let the ConfigureNotify event set everything up, but that
13219 might be kind of confusing to the Lisp code, since size changes
13220 wouldn't be reported in the frame parameters until some random
13221 point in the future when the ConfigureNotify event arrives.
13223 We pass 1 for DELAY since we can't run Lisp code inside of
13225 change_frame_size (f
, rows
, cols
, 0, 1, 0);
13226 PIXEL_WIDTH (f
) = pixelwidth
;
13227 PIXEL_HEIGHT (f
) = pixelheight
;
13229 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
13230 receive in the ConfigureNotify event; if we get what we asked
13231 for, then the event won't cause the screen to become garbaged, so
13232 we have to make sure to do it here. */
13233 SET_FRAME_GARBAGED (f
);
13235 XFlush (FRAME_X_DISPLAY (f
));
13239 /* Call this to change the size of frame F's x-window.
13240 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
13241 for this size change and subsequent size changes.
13242 Otherwise we leave the window gravity unchanged. */
13245 x_set_window_size (f
, change_gravity
, cols
, rows
)
13247 int change_gravity
;
13252 #ifdef USE_X_TOOLKIT
13254 if (f
->output_data
.x
->widget
!= NULL
)
13256 /* The x and y position of the widget is clobbered by the
13257 call to XtSetValues within EmacsFrameSetCharSize.
13258 This is a real kludge, but I don't understand Xt so I can't
13259 figure out a correct fix. Can anyone else tell me? -- rms. */
13260 int xpos
= f
->output_data
.x
->widget
->core
.x
;
13261 int ypos
= f
->output_data
.x
->widget
->core
.y
;
13262 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
13263 f
->output_data
.x
->widget
->core
.x
= xpos
;
13264 f
->output_data
.x
->widget
->core
.y
= ypos
;
13267 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
13269 #else /* not USE_X_TOOLKIT */
13271 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
13273 #endif /* not USE_X_TOOLKIT */
13275 /* If cursor was outside the new size, mark it as off. */
13276 mark_window_cursors_off (XWINDOW (f
->root_window
));
13278 /* Clear out any recollection of where the mouse highlighting was,
13279 since it might be in a place that's outside the new frame size.
13280 Actually checking whether it is outside is a pain in the neck,
13281 so don't try--just let the highlighting be done afresh with new size. */
13282 cancel_mouse_face (f
);
13287 /* Mouse warping. */
13290 x_set_mouse_position (f
, x
, y
)
13296 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
13297 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
13299 if (pix_x
< 0) pix_x
= 0;
13300 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
13302 if (pix_y
< 0) pix_y
= 0;
13303 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
13307 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
13308 0, 0, 0, 0, pix_x
, pix_y
);
13312 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
13315 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
13321 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
13322 0, 0, 0, 0, pix_x
, pix_y
);
13326 /* focus shifting, raising and lowering. */
13329 x_focus_on_frame (f
)
13332 #if 0 /* This proves to be unpleasant. */
13336 /* I don't think that the ICCCM allows programs to do things like this
13337 without the interaction of the window manager. Whatever you end up
13338 doing with this code, do it to x_unfocus_frame too. */
13339 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
13340 RevertToPointerRoot
, CurrentTime
);
13345 x_unfocus_frame (f
)
13349 /* Look at the remarks in x_focus_on_frame. */
13350 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
13351 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
13352 RevertToPointerRoot
, CurrentTime
);
13356 /* Raise frame F. */
13362 if (f
->async_visible
)
13365 #ifdef USE_X_TOOLKIT
13366 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
13367 #else /* not USE_X_TOOLKIT */
13368 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13369 #endif /* not USE_X_TOOLKIT */
13370 XFlush (FRAME_X_DISPLAY (f
));
13375 /* Lower frame F. */
13381 if (f
->async_visible
)
13384 #ifdef USE_X_TOOLKIT
13385 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
13386 #else /* not USE_X_TOOLKIT */
13387 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13388 #endif /* not USE_X_TOOLKIT */
13389 XFlush (FRAME_X_DISPLAY (f
));
13395 XTframe_raise_lower (f
, raise_flag
)
13405 /* Change of visibility. */
13407 /* This tries to wait until the frame is really visible.
13408 However, if the window manager asks the user where to position
13409 the frame, this will return before the user finishes doing that.
13410 The frame will not actually be visible at that time,
13411 but it will become visible later when the window manager
13412 finishes with it. */
13415 x_make_frame_visible (f
)
13419 int original_top
, original_left
;
13420 int retry_count
= 2;
13426 type
= x_icon_type (f
);
13428 x_bitmap_icon (f
, type
);
13430 if (! FRAME_VISIBLE_P (f
))
13432 /* We test FRAME_GARBAGED_P here to make sure we don't
13433 call x_set_offset a second time
13434 if we get to x_make_frame_visible a second time
13435 before the window gets really visible. */
13436 if (! FRAME_ICONIFIED_P (f
)
13437 && ! f
->output_data
.x
->asked_for_visible
)
13438 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
13440 f
->output_data
.x
->asked_for_visible
= 1;
13442 if (! EQ (Vx_no_window_manager
, Qt
))
13443 x_wm_set_window_state (f
, NormalState
);
13444 #ifdef USE_X_TOOLKIT
13445 /* This was XtPopup, but that did nothing for an iconified frame. */
13446 XtMapWidget (f
->output_data
.x
->widget
);
13447 #else /* not USE_X_TOOLKIT */
13448 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13449 #endif /* not USE_X_TOOLKIT */
13450 #if 0 /* This seems to bring back scroll bars in the wrong places
13451 if the window configuration has changed. They seem
13452 to come back ok without this. */
13453 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
13454 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13458 XFlush (FRAME_X_DISPLAY (f
));
13460 /* Synchronize to ensure Emacs knows the frame is visible
13461 before we do anything else. We do this loop with input not blocked
13462 so that incoming events are handled. */
13466 /* This must be before UNBLOCK_INPUT
13467 since events that arrive in response to the actions above
13468 will set it when they are handled. */
13469 int previously_visible
= f
->output_data
.x
->has_been_visible
;
13471 original_left
= f
->output_data
.x
->left_pos
;
13472 original_top
= f
->output_data
.x
->top_pos
;
13474 /* This must come after we set COUNT. */
13477 /* We unblock here so that arriving X events are processed. */
13479 /* Now move the window back to where it was "supposed to be".
13480 But don't do it if the gravity is negative.
13481 When the gravity is negative, this uses a position
13482 that is 3 pixels too low. Perhaps that's really the border width.
13484 Don't do this if the window has never been visible before,
13485 because the window manager may choose the position
13486 and we don't want to override it. */
13488 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
13489 && f
->output_data
.x
->win_gravity
== NorthWestGravity
13490 && previously_visible
)
13494 unsigned int width
, height
, border
, depth
;
13498 /* On some window managers (such as FVWM) moving an existing
13499 window, even to the same place, causes the window manager
13500 to introduce an offset. This can cause the window to move
13501 to an unexpected location. Check the geometry (a little
13502 slow here) and then verify that the window is in the right
13503 place. If the window is not in the right place, move it
13504 there, and take the potential window manager hit. */
13505 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
13506 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
13508 if (original_left
!= x
|| original_top
!= y
)
13509 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
13510 original_left
, original_top
);
13515 XSETFRAME (frame
, f
);
13517 /* Wait until the frame is visible. Process X events until a
13518 MapNotify event has been seen, or until we think we won't get a
13519 MapNotify at all.. */
13520 for (count
= input_signal_count
+ 10;
13521 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
13523 /* Force processing of queued events. */
13526 /* Machines that do polling rather than SIGIO have been
13527 observed to go into a busy-wait here. So we'll fake an
13528 alarm signal to let the handler know that there's something
13529 to be read. We used to raise a real alarm, but it seems
13530 that the handler isn't always enabled here. This is
13532 if (input_polling_used ())
13534 /* It could be confusing if a real alarm arrives while
13535 processing the fake one. Turn it off and let the
13536 handler reset it. */
13537 extern void poll_for_input_1
P_ ((void));
13538 int old_poll_suppress_count
= poll_suppress_count
;
13539 poll_suppress_count
= 1;
13540 poll_for_input_1 ();
13541 poll_suppress_count
= old_poll_suppress_count
;
13544 /* See if a MapNotify event has been processed. */
13545 FRAME_SAMPLE_VISIBILITY (f
);
13550 (let ((f (selected-frame)))
13554 the frame is not raised with various window managers on
13555 FreeBSD, Linux and Solaris. It turns out that, for some
13556 unknown reason, the call to XtMapWidget is completely ignored.
13557 Mapping the widget a second time works. */
13559 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
13564 /* Change from mapped state to withdrawn state. */
13566 /* Make the frame visible (mapped and not iconified). */
13569 x_make_frame_invisible (f
)
13574 #ifdef USE_X_TOOLKIT
13575 /* Use the frame's outermost window, not the one we normally draw on. */
13576 window
= XtWindow (f
->output_data
.x
->widget
);
13577 #else /* not USE_X_TOOLKIT */
13578 window
= FRAME_X_WINDOW (f
);
13579 #endif /* not USE_X_TOOLKIT */
13581 /* Don't keep the highlight on an invisible frame. */
13582 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13583 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13585 #if 0/* This might add unreliability; I don't trust it -- rms. */
13586 if (! f
->async_visible
&& ! f
->async_iconified
)
13592 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
13593 that the current position of the window is user-specified, rather than
13594 program-specified, so that when the window is mapped again, it will be
13595 placed at the same location, without forcing the user to position it
13596 by hand again (they have already done that once for this window.) */
13597 x_wm_set_size_hint (f
, (long) 0, 1);
13601 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
13602 DefaultScreen (FRAME_X_DISPLAY (f
))))
13604 UNBLOCK_INPUT_RESIGNAL
;
13605 error ("Can't notify window manager of window withdrawal");
13607 #else /* ! defined (HAVE_X11R4) */
13609 /* Tell the window manager what we're going to do. */
13610 if (! EQ (Vx_no_window_manager
, Qt
))
13614 unmap
.xunmap
.type
= UnmapNotify
;
13615 unmap
.xunmap
.window
= window
;
13616 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
13617 unmap
.xunmap
.from_configure
= False
;
13618 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13619 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13621 SubstructureRedirectMaskSubstructureNotifyMask
,
13624 UNBLOCK_INPUT_RESIGNAL
;
13625 error ("Can't notify window manager of withdrawal");
13629 /* Unmap the window ourselves. Cheeky! */
13630 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
13631 #endif /* ! defined (HAVE_X11R4) */
13633 /* We can't distinguish this from iconification
13634 just by the event that we get from the server.
13635 So we can't win using the usual strategy of letting
13636 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
13637 and synchronize with the server to make sure we agree. */
13639 FRAME_ICONIFIED_P (f
) = 0;
13640 f
->async_visible
= 0;
13641 f
->async_iconified
= 0;
13648 /* Change window state from mapped to iconified. */
13651 x_iconify_frame (f
)
13657 /* Don't keep the highlight on an invisible frame. */
13658 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13659 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13661 if (f
->async_iconified
)
13666 FRAME_SAMPLE_VISIBILITY (f
);
13668 type
= x_icon_type (f
);
13670 x_bitmap_icon (f
, type
);
13672 #ifdef USE_X_TOOLKIT
13674 if (! FRAME_VISIBLE_P (f
))
13676 if (! EQ (Vx_no_window_manager
, Qt
))
13677 x_wm_set_window_state (f
, IconicState
);
13678 /* This was XtPopup, but that did nothing for an iconified frame. */
13679 XtMapWidget (f
->output_data
.x
->widget
);
13680 /* The server won't give us any event to indicate
13681 that an invisible frame was changed to an icon,
13682 so we have to record it here. */
13685 f
->async_iconified
= 1;
13686 f
->async_visible
= 0;
13691 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
13692 XtWindow (f
->output_data
.x
->widget
),
13693 DefaultScreen (FRAME_X_DISPLAY (f
)));
13697 error ("Can't notify window manager of iconification");
13699 f
->async_iconified
= 1;
13700 f
->async_visible
= 0;
13704 XFlush (FRAME_X_DISPLAY (f
));
13706 #else /* not USE_X_TOOLKIT */
13708 /* Make sure the X server knows where the window should be positioned,
13709 in case the user deiconifies with the window manager. */
13710 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
13711 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
13713 /* Since we don't know which revision of X we're running, we'll use both
13714 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
13716 /* X11R4: send a ClientMessage to the window manager using the
13717 WM_CHANGE_STATE type. */
13721 message
.xclient
.window
= FRAME_X_WINDOW (f
);
13722 message
.xclient
.type
= ClientMessage
;
13723 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
13724 message
.xclient
.format
= 32;
13725 message
.xclient
.data
.l
[0] = IconicState
;
13727 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13728 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13730 SubstructureRedirectMask
| SubstructureNotifyMask
,
13733 UNBLOCK_INPUT_RESIGNAL
;
13734 error ("Can't notify window manager of iconification");
13738 /* X11R3: set the initial_state field of the window manager hints to
13740 x_wm_set_window_state (f
, IconicState
);
13742 if (!FRAME_VISIBLE_P (f
))
13744 /* If the frame was withdrawn, before, we must map it. */
13745 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13748 f
->async_iconified
= 1;
13749 f
->async_visible
= 0;
13751 XFlush (FRAME_X_DISPLAY (f
));
13753 #endif /* not USE_X_TOOLKIT */
13757 /* Free X resources of frame F. */
13760 x_free_frame_resources (f
)
13763 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13765 struct scroll_bar
*b
;
13769 /* If a display connection is dead, don't try sending more
13770 commands to the X server. */
13771 if (dpyinfo
->display
)
13773 if (f
->output_data
.x
->icon_desc
)
13774 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
13776 #ifdef USE_X_TOOLKIT
13777 /* Explicitly destroy the scroll bars of the frame. Without
13778 this, we get "BadDrawable" errors from the toolkit later on,
13779 presumably from expose events generated for the disappearing
13780 toolkit scroll bars. */
13781 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
); bar
= b
->next
)
13783 b
= XSCROLL_BAR (bar
);
13784 x_scroll_bar_remove (b
);
13790 free_frame_xic (f
);
13793 #ifdef USE_X_TOOLKIT
13794 if (f
->output_data
.x
->widget
)
13796 XtDestroyWidget (f
->output_data
.x
->widget
);
13797 f
->output_data
.x
->widget
= NULL
;
13799 /* Tooltips don't have widgets, only a simple X window, even if
13800 we are using a toolkit. */
13801 else if (FRAME_X_WINDOW (f
))
13802 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13804 free_frame_menubar (f
);
13805 #else /* !USE_X_TOOLKIT */
13806 if (FRAME_X_WINDOW (f
))
13807 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13808 #endif /* !USE_X_TOOLKIT */
13810 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
13811 unload_color (f
, f
->output_data
.x
->background_pixel
);
13812 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
13813 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
13814 unload_color (f
, f
->output_data
.x
->border_pixel
);
13815 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
13817 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
13818 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
13819 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
13820 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
13821 #ifdef USE_TOOLKIT_SCROLL_BARS
13822 /* Scrollbar shadow colors. */
13823 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
13824 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
13825 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
13826 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
13827 #endif /* USE_TOOLKIT_SCROLL_BARS */
13828 if (f
->output_data
.x
->white_relief
.allocated_p
)
13829 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
13830 if (f
->output_data
.x
->black_relief
.allocated_p
)
13831 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
13833 if (FRAME_FACE_CACHE (f
))
13834 free_frame_faces (f
);
13837 XFlush (FRAME_X_DISPLAY (f
));
13840 if (f
->output_data
.x
->saved_menu_event
)
13841 xfree (f
->output_data
.x
->saved_menu_event
);
13843 xfree (f
->output_data
.x
);
13844 f
->output_data
.x
= NULL
;
13846 if (f
== dpyinfo
->x_focus_frame
)
13847 dpyinfo
->x_focus_frame
= 0;
13848 if (f
== dpyinfo
->x_focus_event_frame
)
13849 dpyinfo
->x_focus_event_frame
= 0;
13850 if (f
== dpyinfo
->x_highlight_frame
)
13851 dpyinfo
->x_highlight_frame
= 0;
13853 if (f
== dpyinfo
->mouse_face_mouse_frame
)
13855 dpyinfo
->mouse_face_beg_row
13856 = dpyinfo
->mouse_face_beg_col
= -1;
13857 dpyinfo
->mouse_face_end_row
13858 = dpyinfo
->mouse_face_end_col
= -1;
13859 dpyinfo
->mouse_face_window
= Qnil
;
13860 dpyinfo
->mouse_face_deferred_gc
= 0;
13861 dpyinfo
->mouse_face_mouse_frame
= 0;
13868 /* Destroy the X window of frame F. */
13871 x_destroy_window (f
)
13874 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13876 /* If a display connection is dead, don't try sending more
13877 commands to the X server. */
13878 if (dpyinfo
->display
!= 0)
13879 x_free_frame_resources (f
);
13881 dpyinfo
->reference_count
--;
13885 /* Setting window manager hints. */
13887 /* Set the normal size hints for the window manager, for frame F.
13888 FLAGS is the flags word to use--or 0 meaning preserve the flags
13889 that the window now has.
13890 If USER_POSITION is nonzero, we set the USPosition
13891 flag (this is useful when FLAGS is 0). */
13894 x_wm_set_size_hint (f
, flags
, user_position
)
13899 XSizeHints size_hints
;
13901 #ifdef USE_X_TOOLKIT
13904 Dimension widget_width
, widget_height
;
13905 Window window
= XtWindow (f
->output_data
.x
->widget
);
13906 #else /* not USE_X_TOOLKIT */
13907 Window window
= FRAME_X_WINDOW (f
);
13908 #endif /* not USE_X_TOOLKIT */
13910 /* Setting PMaxSize caused various problems. */
13911 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
13913 size_hints
.x
= f
->output_data
.x
->left_pos
;
13914 size_hints
.y
= f
->output_data
.x
->top_pos
;
13916 #ifdef USE_X_TOOLKIT
13917 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
13918 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
13919 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
13920 size_hints
.height
= widget_height
;
13921 size_hints
.width
= widget_width
;
13922 #else /* not USE_X_TOOLKIT */
13923 size_hints
.height
= PIXEL_HEIGHT (f
);
13924 size_hints
.width
= PIXEL_WIDTH (f
);
13925 #endif /* not USE_X_TOOLKIT */
13927 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
13928 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
13929 size_hints
.max_width
13930 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
13931 size_hints
.max_height
13932 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
13934 /* Calculate the base and minimum sizes.
13936 (When we use the X toolkit, we don't do it here.
13937 Instead we copy the values that the widgets are using, below.) */
13938 #ifndef USE_X_TOOLKIT
13940 int base_width
, base_height
;
13941 int min_rows
= 0, min_cols
= 0;
13943 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
13944 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
13946 check_frame_size (f
, &min_rows
, &min_cols
);
13948 /* The window manager uses the base width hints to calculate the
13949 current number of rows and columns in the frame while
13950 resizing; min_width and min_height aren't useful for this
13951 purpose, since they might not give the dimensions for a
13952 zero-row, zero-column frame.
13954 We use the base_width and base_height members if we have
13955 them; otherwise, we set the min_width and min_height members
13956 to the size for a zero x zero frame. */
13959 size_hints
.flags
|= PBaseSize
;
13960 size_hints
.base_width
= base_width
;
13961 size_hints
.base_height
= base_height
;
13962 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
13963 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
13965 size_hints
.min_width
= base_width
;
13966 size_hints
.min_height
= base_height
;
13970 /* If we don't need the old flags, we don't need the old hint at all. */
13973 size_hints
.flags
|= flags
;
13976 #endif /* not USE_X_TOOLKIT */
13979 XSizeHints hints
; /* Sometimes I hate X Windows... */
13980 long supplied_return
;
13984 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
13987 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13990 #ifdef USE_X_TOOLKIT
13991 size_hints
.base_height
= hints
.base_height
;
13992 size_hints
.base_width
= hints
.base_width
;
13993 size_hints
.min_height
= hints
.min_height
;
13994 size_hints
.min_width
= hints
.min_width
;
13998 size_hints
.flags
|= flags
;
14003 if (hints
.flags
& PSize
)
14004 size_hints
.flags
|= PSize
;
14005 if (hints
.flags
& PPosition
)
14006 size_hints
.flags
|= PPosition
;
14007 if (hints
.flags
& USPosition
)
14008 size_hints
.flags
|= USPosition
;
14009 if (hints
.flags
& USSize
)
14010 size_hints
.flags
|= USSize
;
14014 #ifndef USE_X_TOOLKIT
14019 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
14020 size_hints
.flags
|= PWinGravity
;
14024 size_hints
.flags
&= ~ PPosition
;
14025 size_hints
.flags
|= USPosition
;
14027 #endif /* PWinGravity */
14030 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
14032 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
14036 /* Used for IconicState or NormalState */
14039 x_wm_set_window_state (f
, state
)
14043 #ifdef USE_X_TOOLKIT
14046 XtSetArg (al
[0], XtNinitialState
, state
);
14047 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
14048 #else /* not USE_X_TOOLKIT */
14049 Window window
= FRAME_X_WINDOW (f
);
14051 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
14052 f
->output_data
.x
->wm_hints
.initial_state
= state
;
14054 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
14055 #endif /* not USE_X_TOOLKIT */
14059 x_wm_set_icon_pixmap (f
, pixmap_id
)
14063 Pixmap icon_pixmap
;
14065 #ifndef USE_X_TOOLKIT
14066 Window window
= FRAME_X_WINDOW (f
);
14071 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
14072 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
14076 /* It seems there is no way to turn off use of an icon pixmap.
14077 The following line does it, only if no icon has yet been created,
14078 for some window managers. But with mwm it crashes.
14079 Some people say it should clear the IconPixmapHint bit in this case,
14080 but that doesn't work, and the X consortium said it isn't the
14081 right thing at all. Since there is no way to win,
14082 best to explicitly give up. */
14084 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
14090 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
14094 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
14095 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
14098 #else /* not USE_X_TOOLKIT */
14100 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
14101 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
14103 #endif /* not USE_X_TOOLKIT */
14107 x_wm_set_icon_position (f
, icon_x
, icon_y
)
14109 int icon_x
, icon_y
;
14111 #ifdef USE_X_TOOLKIT
14112 Window window
= XtWindow (f
->output_data
.x
->widget
);
14114 Window window
= FRAME_X_WINDOW (f
);
14117 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
14118 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
14119 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
14121 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
14125 /***********************************************************************
14127 ***********************************************************************/
14129 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
14132 x_get_font_info (f
, font_idx
)
14136 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
14140 /* Return a list of names of available fonts matching PATTERN on frame F.
14142 If SIZE is > 0, it is the size (maximum bounds width) of fonts
14145 SIZE < 0 means include scalable fonts.
14147 Frame F null means we have not yet created any frame on X, and
14148 consult the first display in x_display_list. MAXNAMES sets a limit
14149 on how many fonts to match. */
14152 x_list_fonts (f
, pattern
, size
, maxnames
)
14154 Lisp_Object pattern
;
14158 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
14159 Lisp_Object tem
, second_best
;
14160 struct x_display_info
*dpyinfo
14161 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
14162 Display
*dpy
= dpyinfo
->display
;
14163 int try_XLoadQueryFont
= 0;
14165 int allow_scalable_fonts_p
= 0;
14169 allow_scalable_fonts_p
= 1;
14173 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
14174 if (NILP (patterns
))
14175 patterns
= Fcons (pattern
, Qnil
);
14177 if (maxnames
== 1 && !size
)
14178 /* We can return any single font matching PATTERN. */
14179 try_XLoadQueryFont
= 1;
14181 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
14184 char **names
= NULL
;
14186 pattern
= XCAR (patterns
);
14187 /* See if we cached the result for this particular query.
14188 The cache is an alist of the form:
14189 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
14190 tem
= XCDR (dpyinfo
->name_list_element
);
14191 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
14192 allow_scalable_fonts_p
? Qt
: Qnil
);
14193 list
= Fassoc (key
, tem
);
14196 list
= Fcdr_safe (list
);
14197 /* We have a cashed list. Don't have to get the list again. */
14201 /* At first, put PATTERN in the cache. */
14204 count
= x_catch_errors (dpy
);
14206 if (try_XLoadQueryFont
)
14209 unsigned long value
;
14211 font
= XLoadQueryFont (dpy
, SDATA (pattern
));
14212 if (x_had_errors_p (dpy
))
14214 /* This error is perhaps due to insufficient memory on X
14215 server. Let's just ignore it. */
14217 x_clear_errors (dpy
);
14221 && XGetFontProperty (font
, XA_FONT
, &value
))
14223 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
14224 int len
= strlen (name
);
14227 /* If DXPC (a Differential X Protocol Compressor)
14228 Ver.3.7 is running, XGetAtomName will return null
14229 string. We must avoid such a name. */
14231 try_XLoadQueryFont
= 0;
14235 names
= (char **) alloca (sizeof (char *));
14236 /* Some systems only allow alloca assigned to a
14238 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
14239 bcopy (name
, names
[0], len
+ 1);
14244 try_XLoadQueryFont
= 0;
14247 XFreeFont (dpy
, font
);
14250 if (!try_XLoadQueryFont
)
14252 /* We try at least 10 fonts because XListFonts will return
14253 auto-scaled fonts at the head. */
14254 names
= XListFonts (dpy
, SDATA (pattern
), max (maxnames
, 10),
14256 if (x_had_errors_p (dpy
))
14258 /* This error is perhaps due to insufficient memory on X
14259 server. Let's just ignore it. */
14261 x_clear_errors (dpy
);
14265 x_uncatch_errors (dpy
, count
);
14272 /* Make a list of all the fonts we got back.
14273 Store that in the font cache for the display. */
14274 for (i
= 0; i
< num_fonts
; i
++)
14277 char *p
= names
[i
];
14278 int average_width
= -1, dashes
= 0;
14280 /* Count the number of dashes in NAMES[I]. If there are
14281 14 dashes, and the field value following 12th dash
14282 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
14283 is usually too ugly to be used for editing. Let's
14289 if (dashes
== 7) /* PIXEL_SIZE field */
14291 else if (dashes
== 12) /* AVERAGE_WIDTH field */
14292 average_width
= atoi (p
);
14295 if (allow_scalable_fonts_p
14296 || dashes
< 14 || average_width
!= 0)
14298 tem
= build_string (names
[i
]);
14299 if (NILP (Fassoc (tem
, list
)))
14301 if (STRINGP (Vx_pixel_size_width_font_regexp
)
14302 && ((fast_c_string_match_ignore_case
14303 (Vx_pixel_size_width_font_regexp
, names
[i
]))
14305 /* We can set the value of PIXEL_SIZE to the
14306 width of this font. */
14307 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
14309 /* For the moment, width is not known. */
14310 list
= Fcons (Fcons (tem
, Qnil
), list
);
14315 if (!try_XLoadQueryFont
)
14318 XFreeFontNames (names
);
14323 /* Now store the result in the cache. */
14324 XSETCDR (dpyinfo
->name_list_element
,
14325 Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
)));
14328 if (NILP (list
)) continue; /* Try the remaining alternatives. */
14330 newlist
= second_best
= Qnil
;
14331 /* Make a list of the fonts that have the right width. */
14332 for (; CONSP (list
); list
= XCDR (list
))
14338 if (!CONSP (tem
) || NILP (XCAR (tem
)))
14342 newlist
= Fcons (XCAR (tem
), newlist
);
14346 if (!INTEGERP (XCDR (tem
)))
14348 /* Since we have not yet known the size of this font, we
14349 must try slow function call XLoadQueryFont. */
14350 XFontStruct
*thisinfo
;
14353 count
= x_catch_errors (dpy
);
14354 thisinfo
= XLoadQueryFont (dpy
,
14355 SDATA (XCAR (tem
)));
14356 if (x_had_errors_p (dpy
))
14358 /* This error is perhaps due to insufficient memory on X
14359 server. Let's just ignore it. */
14361 x_clear_errors (dpy
);
14363 x_uncatch_errors (dpy
, count
);
14369 (thisinfo
->min_bounds
.width
== 0
14371 : make_number (thisinfo
->max_bounds
.width
)));
14373 XFreeFont (dpy
, thisinfo
);
14377 /* For unknown reason, the previous call of XListFont had
14378 returned a font which can't be opened. Record the size
14379 as 0 not to try to open it again. */
14380 XSETCDR (tem
, make_number (0));
14383 found_size
= XINT (XCDR (tem
));
14384 if (found_size
== size
)
14385 newlist
= Fcons (XCAR (tem
), newlist
);
14386 else if (found_size
> 0)
14388 if (NILP (second_best
))
14390 else if (found_size
< size
)
14392 if (XINT (XCDR (second_best
)) > size
14393 || XINT (XCDR (second_best
)) < found_size
)
14398 if (XINT (XCDR (second_best
)) > size
14399 && XINT (XCDR (second_best
)) > found_size
)
14404 if (!NILP (newlist
))
14406 else if (!NILP (second_best
))
14408 newlist
= Fcons (XCAR (second_best
), Qnil
);
14419 /* Check that FONT is valid on frame F. It is if it can be found in F's
14423 x_check_font (f
, font
)
14428 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14430 xassert (font
!= NULL
);
14432 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14433 if (dpyinfo
->font_table
[i
].name
14434 && font
== dpyinfo
->font_table
[i
].font
)
14437 xassert (i
< dpyinfo
->n_fonts
);
14440 #endif /* GLYPH_DEBUG != 0 */
14442 /* Set *W to the minimum width, *H to the minimum font height of FONT.
14443 Note: There are (broken) X fonts out there with invalid XFontStruct
14444 min_bounds contents. For example, handa@etl.go.jp reports that
14445 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
14446 have font->min_bounds.width == 0. */
14449 x_font_min_bounds (font
, w
, h
)
14453 *h
= FONT_HEIGHT (font
);
14454 *w
= font
->min_bounds
.width
;
14456 /* Try to handle the case where FONT->min_bounds has invalid
14457 contents. Since the only font known to have invalid min_bounds
14458 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
14460 *w
= font
->max_bounds
.width
;
14464 /* Compute the smallest character width and smallest font height over
14465 all fonts available on frame F. Set the members smallest_char_width
14466 and smallest_font_height in F's x_display_info structure to
14467 the values computed. Value is non-zero if smallest_font_height or
14468 smallest_char_width become smaller than they were before. */
14471 x_compute_min_glyph_bounds (f
)
14475 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14477 int old_width
= dpyinfo
->smallest_char_width
;
14478 int old_height
= dpyinfo
->smallest_font_height
;
14480 dpyinfo
->smallest_font_height
= 100000;
14481 dpyinfo
->smallest_char_width
= 100000;
14483 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
14484 if (dpyinfo
->font_table
[i
].name
)
14486 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
14489 font
= (XFontStruct
*) fontp
->font
;
14490 xassert (font
!= (XFontStruct
*) ~0);
14491 x_font_min_bounds (font
, &w
, &h
);
14493 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
14494 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
14497 xassert (dpyinfo
->smallest_char_width
> 0
14498 && dpyinfo
->smallest_font_height
> 0);
14500 return (dpyinfo
->n_fonts
== 1
14501 || dpyinfo
->smallest_char_width
< old_width
14502 || dpyinfo
->smallest_font_height
< old_height
);
14506 /* Load font named FONTNAME of the size SIZE for frame F, and return a
14507 pointer to the structure font_info while allocating it dynamically.
14508 If SIZE is 0, load any size of font.
14509 If loading is failed, return NULL. */
14512 x_load_font (f
, fontname
, size
)
14514 register char *fontname
;
14517 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14518 Lisp_Object font_names
;
14521 /* Get a list of all the fonts that match this name. Once we
14522 have a list of matching fonts, we compare them against the fonts
14523 we already have by comparing names. */
14524 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
14526 if (!NILP (font_names
))
14531 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14532 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
14533 if (dpyinfo
->font_table
[i
].name
14534 && (!strcmp (dpyinfo
->font_table
[i
].name
,
14535 SDATA (XCAR (tail
)))
14536 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
14537 SDATA (XCAR (tail
)))))
14538 return (dpyinfo
->font_table
+ i
);
14541 /* Load the font and add it to the table. */
14545 struct font_info
*fontp
;
14546 unsigned long value
;
14549 /* If we have found fonts by x_list_font, load one of them. If
14550 not, we still try to load a font by the name given as FONTNAME
14551 because XListFonts (called in x_list_font) of some X server has
14552 a bug of not finding a font even if the font surely exists and
14553 is loadable by XLoadQueryFont. */
14554 if (size
> 0 && !NILP (font_names
))
14555 fontname
= (char *) SDATA (XCAR (font_names
));
14558 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
14559 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
14560 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
14562 /* This error is perhaps due to insufficient memory on X
14563 server. Let's just ignore it. */
14565 x_clear_errors (FRAME_X_DISPLAY (f
));
14567 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
14572 /* Find a free slot in the font table. */
14573 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
14574 if (dpyinfo
->font_table
[i
].name
== NULL
)
14577 /* If no free slot found, maybe enlarge the font table. */
14578 if (i
== dpyinfo
->n_fonts
14579 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
14582 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
14583 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
14584 dpyinfo
->font_table
14585 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
14588 fontp
= dpyinfo
->font_table
+ i
;
14589 if (i
== dpyinfo
->n_fonts
)
14590 ++dpyinfo
->n_fonts
;
14592 /* Now fill in the slots of *FONTP. */
14594 fontp
->font
= font
;
14595 fontp
->font_idx
= i
;
14596 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
14597 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
14599 /* Try to get the full name of FONT. Put it in FULL_NAME. */
14601 if (XGetFontProperty (font
, XA_FONT
, &value
))
14603 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
14607 /* Count the number of dashes in the "full name".
14608 If it is too few, this isn't really the font's full name,
14610 In X11R4, the fonts did not come with their canonical names
14621 full_name
= (char *) xmalloc (p
- name
+ 1);
14622 bcopy (name
, full_name
, p
- name
+ 1);
14628 if (full_name
!= 0)
14629 fontp
->full_name
= full_name
;
14631 fontp
->full_name
= fontp
->name
;
14633 fontp
->size
= font
->max_bounds
.width
;
14634 fontp
->height
= FONT_HEIGHT (font
);
14636 if (NILP (font_names
))
14638 /* We come here because of a bug of XListFonts mentioned at
14639 the head of this block. Let's store this information in
14640 the cache for x_list_fonts. */
14641 Lisp_Object lispy_name
= build_string (fontname
);
14642 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
14643 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
14646 XSETCDR (dpyinfo
->name_list_element
,
14648 Fcons (Fcons (lispy_full_name
,
14649 make_number (fontp
->size
)),
14651 XCDR (dpyinfo
->name_list_element
)));
14654 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
14656 XSETCDR (dpyinfo
->name_list_element
,
14658 Fcons (Fcons (lispy_full_name
,
14659 make_number (fontp
->size
)),
14661 XCDR (dpyinfo
->name_list_element
)));
14665 /* The slot `encoding' specifies how to map a character
14666 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
14667 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
14668 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
14669 2:0xA020..0xFF7F). For the moment, we don't know which charset
14670 uses this font. So, we set information in fontp->encoding[1]
14671 which is never used by any charset. If mapping can't be
14672 decided, set FONT_ENCODING_NOT_DECIDED. */
14674 = (font
->max_byte1
== 0
14676 ? (font
->min_char_or_byte2
< 0x80
14677 ? (font
->max_char_or_byte2
< 0x80
14678 ? 0 /* 0x20..0x7F */
14679 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
14680 : 1) /* 0xA0..0xFF */
14682 : (font
->min_byte1
< 0x80
14683 ? (font
->max_byte1
< 0x80
14684 ? (font
->min_char_or_byte2
< 0x80
14685 ? (font
->max_char_or_byte2
< 0x80
14686 ? 0 /* 0x2020..0x7F7F */
14687 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
14688 : 3) /* 0x20A0..0x7FFF */
14689 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
14690 : (font
->min_char_or_byte2
< 0x80
14691 ? (font
->max_char_or_byte2
< 0x80
14692 ? 2 /* 0xA020..0xFF7F */
14693 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
14694 : 1))); /* 0xA0A0..0xFFFF */
14696 fontp
->baseline_offset
14697 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
14698 ? (long) value
: 0);
14699 fontp
->relative_compose
14700 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
14701 ? (long) value
: 0);
14702 fontp
->default_ascent
14703 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
14704 ? (long) value
: 0);
14706 /* Set global flag fonts_changed_p to non-zero if the font loaded
14707 has a character with a smaller width than any other character
14708 before, or if the font loaded has a smaller height than any
14709 other font loaded before. If this happens, it will make a
14710 glyph matrix reallocation necessary. */
14711 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
14718 /* Return a pointer to struct font_info of a font named FONTNAME for
14719 frame F. If no such font is loaded, return NULL. */
14722 x_query_font (f
, fontname
)
14724 register char *fontname
;
14726 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14729 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14730 if (dpyinfo
->font_table
[i
].name
14731 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
14732 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
14733 return (dpyinfo
->font_table
+ i
);
14738 /* Find a CCL program for a font specified by FONTP, and set the member
14739 `encoder' of the structure. */
14742 x_find_ccl_program (fontp
)
14743 struct font_info
*fontp
;
14745 Lisp_Object list
, elt
;
14748 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
14752 && STRINGP (XCAR (elt
))
14753 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
14755 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
14762 struct ccl_program
*ccl
14763 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
14765 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
14768 fontp
->font_encoder
= ccl
;
14774 /***********************************************************************
14776 ***********************************************************************/
14778 #ifdef USE_X_TOOLKIT
14779 static XrmOptionDescRec emacs_options
[] = {
14780 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
14781 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
14783 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
14784 XrmoptionSepArg
, NULL
},
14785 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
14787 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14788 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14789 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14790 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14791 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14792 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
14793 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
14795 #endif /* USE_X_TOOLKIT */
14797 static int x_initialized
;
14799 #ifdef MULTI_KBOARD
14800 /* Test whether two display-name strings agree up to the dot that separates
14801 the screen number from the server number. */
14803 same_x_server (name1
, name2
)
14804 const char *name1
, *name2
;
14806 int seen_colon
= 0;
14807 const unsigned char *system_name
= SDATA (Vsystem_name
);
14808 int system_name_length
= strlen (system_name
);
14809 int length_until_period
= 0;
14811 while (system_name
[length_until_period
] != 0
14812 && system_name
[length_until_period
] != '.')
14813 length_until_period
++;
14815 /* Treat `unix' like an empty host name. */
14816 if (! strncmp (name1
, "unix:", 5))
14818 if (! strncmp (name2
, "unix:", 5))
14820 /* Treat this host's name like an empty host name. */
14821 if (! strncmp (name1
, system_name
, system_name_length
)
14822 && name1
[system_name_length
] == ':')
14823 name1
+= system_name_length
;
14824 if (! strncmp (name2
, system_name
, system_name_length
)
14825 && name2
[system_name_length
] == ':')
14826 name2
+= system_name_length
;
14827 /* Treat this host's domainless name like an empty host name. */
14828 if (! strncmp (name1
, system_name
, length_until_period
)
14829 && name1
[length_until_period
] == ':')
14830 name1
+= length_until_period
;
14831 if (! strncmp (name2
, system_name
, length_until_period
)
14832 && name2
[length_until_period
] == ':')
14833 name2
+= length_until_period
;
14835 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
14839 if (seen_colon
&& *name1
== '.')
14843 && (*name1
== '.' || *name1
== '\0')
14844 && (*name2
== '.' || *name2
== '\0'));
14848 struct x_display_info
*
14849 x_term_init (display_name
, xrm_option
, resource_name
)
14850 Lisp_Object display_name
;
14852 char *resource_name
;
14856 struct x_display_info
*dpyinfo
;
14861 if (!x_initialized
)
14867 #ifdef USE_X_TOOLKIT
14868 /* weiner@footloose.sps.mot.com reports that this causes
14870 X protocol error: BadAtom (invalid Atom parameter)
14871 on protocol request 18skiloaf.
14872 So let's not use it until R6. */
14873 #ifdef HAVE_X11XTR6
14874 XtSetLanguageProc (NULL
, NULL
, NULL
);
14885 argv
[argc
++] = "-xrm";
14886 argv
[argc
++] = xrm_option
;
14888 turn_on_atimers (0);
14889 dpy
= XtOpenDisplay (Xt_app_con
, SDATA (display_name
),
14890 resource_name
, EMACS_CLASS
,
14891 emacs_options
, XtNumber (emacs_options
),
14893 turn_on_atimers (1);
14895 #ifdef HAVE_X11XTR6
14896 /* I think this is to compensate for XtSetLanguageProc. */
14901 #else /* not USE_X_TOOLKIT */
14903 XSetLocaleModifiers ("");
14905 dpy
= XOpenDisplay (SDATA (display_name
));
14906 #endif /* not USE_X_TOOLKIT */
14908 /* Detect failure. */
14915 /* We have definitely succeeded. Record the new connection. */
14917 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
14918 bzero (dpyinfo
, sizeof *dpyinfo
);
14920 #ifdef MULTI_KBOARD
14922 struct x_display_info
*share
;
14925 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
14926 share
= share
->next
, tail
= XCDR (tail
))
14927 if (same_x_server (SDATA (XCAR (XCAR (tail
))),
14928 SDATA (display_name
)))
14931 dpyinfo
->kboard
= share
->kboard
;
14934 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
14935 init_kboard (dpyinfo
->kboard
);
14936 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
14938 char *vendor
= ServerVendor (dpy
);
14940 dpyinfo
->kboard
->Vsystem_key_alist
14941 = call1 (Qvendor_specific_keysyms
,
14942 build_string (vendor
? vendor
: ""));
14946 dpyinfo
->kboard
->next_kboard
= all_kboards
;
14947 all_kboards
= dpyinfo
->kboard
;
14948 /* Don't let the initial kboard remain current longer than necessary.
14949 That would cause problems if a file loaded on startup tries to
14950 prompt in the mini-buffer. */
14951 if (current_kboard
== initial_kboard
)
14952 current_kboard
= dpyinfo
->kboard
;
14954 dpyinfo
->kboard
->reference_count
++;
14958 /* Put this display on the chain. */
14959 dpyinfo
->next
= x_display_list
;
14960 x_display_list
= dpyinfo
;
14962 /* Put it on x_display_name_list as well, to keep them parallel. */
14963 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
14964 x_display_name_list
);
14965 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
14967 dpyinfo
->display
= dpy
;
14970 XSetAfterFunction (x_current_display
, x_trace_wire
);
14974 = (char *) xmalloc (SBYTES (Vinvocation_name
)
14975 + SBYTES (Vsystem_name
)
14977 sprintf (dpyinfo
->x_id_name
, "%s@%s",
14978 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
14980 /* Figure out which modifier bits mean what. */
14981 x_find_modifier_meanings (dpyinfo
);
14983 /* Get the scroll bar cursor. */
14984 dpyinfo
->vertical_scroll_bar_cursor
14985 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
14987 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
14988 resource_name
, EMACS_CLASS
);
14989 #ifdef HAVE_XRMSETDATABASE
14990 XrmSetDatabase (dpyinfo
->display
, xrdb
);
14992 dpyinfo
->display
->db
= xrdb
;
14994 /* Put the rdb where we can find it in a way that works on
14996 dpyinfo
->xrdb
= xrdb
;
14998 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14999 DefaultScreen (dpyinfo
->display
));
15000 select_visual (dpyinfo
);
15001 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
15002 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
15003 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
15004 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
15005 dpyinfo
->grabbed
= 0;
15006 dpyinfo
->reference_count
= 0;
15007 dpyinfo
->icon_bitmap_id
= -1;
15008 dpyinfo
->font_table
= NULL
;
15009 dpyinfo
->n_fonts
= 0;
15010 dpyinfo
->font_table_size
= 0;
15011 dpyinfo
->bitmaps
= 0;
15012 dpyinfo
->bitmaps_size
= 0;
15013 dpyinfo
->bitmaps_last
= 0;
15014 dpyinfo
->scratch_cursor_gc
= 0;
15015 dpyinfo
->mouse_face_mouse_frame
= 0;
15016 dpyinfo
->mouse_face_deferred_gc
= 0;
15017 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
15018 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
15019 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
15020 dpyinfo
->mouse_face_window
= Qnil
;
15021 dpyinfo
->mouse_face_overlay
= Qnil
;
15022 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
15023 dpyinfo
->mouse_face_defer
= 0;
15024 dpyinfo
->mouse_face_hidden
= 0;
15025 dpyinfo
->x_focus_frame
= 0;
15026 dpyinfo
->x_focus_event_frame
= 0;
15027 dpyinfo
->x_highlight_frame
= 0;
15028 dpyinfo
->image_cache
= make_image_cache ();
15030 /* See if a private colormap is requested. */
15031 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
15033 if (dpyinfo
->visual
->class == PseudoColor
)
15036 value
= display_x_get_resource (dpyinfo
,
15037 build_string ("privateColormap"),
15038 build_string ("PrivateColormap"),
15040 if (STRINGP (value
)
15041 && (!strcmp (SDATA (value
), "true")
15042 || !strcmp (SDATA (value
), "on")))
15043 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
15047 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
15048 dpyinfo
->visual
, AllocNone
);
15051 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
15052 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
15053 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
15054 dpyinfo
->resy
= pixels
* 25.4 / mm
;
15055 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
15056 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
15057 dpyinfo
->resx
= pixels
* 25.4 / mm
;
15060 dpyinfo
->Xatom_wm_protocols
15061 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
15062 dpyinfo
->Xatom_wm_take_focus
15063 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
15064 dpyinfo
->Xatom_wm_save_yourself
15065 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
15066 dpyinfo
->Xatom_wm_delete_window
15067 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
15068 dpyinfo
->Xatom_wm_change_state
15069 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
15070 dpyinfo
->Xatom_wm_configure_denied
15071 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
15072 dpyinfo
->Xatom_wm_window_moved
15073 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
15074 dpyinfo
->Xatom_editres
15075 = XInternAtom (dpyinfo
->display
, "Editres", False
);
15076 dpyinfo
->Xatom_CLIPBOARD
15077 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
15078 dpyinfo
->Xatom_TIMESTAMP
15079 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
15080 dpyinfo
->Xatom_TEXT
15081 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
15082 dpyinfo
->Xatom_COMPOUND_TEXT
15083 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
15084 dpyinfo
->Xatom_UTF8_STRING
15085 = XInternAtom (dpyinfo
->display
, "UTF8_STRING", False
);
15086 dpyinfo
->Xatom_DELETE
15087 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
15088 dpyinfo
->Xatom_MULTIPLE
15089 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
15090 dpyinfo
->Xatom_INCR
15091 = XInternAtom (dpyinfo
->display
, "INCR", False
);
15092 dpyinfo
->Xatom_EMACS_TMP
15093 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
15094 dpyinfo
->Xatom_TARGETS
15095 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
15096 dpyinfo
->Xatom_NULL
15097 = XInternAtom (dpyinfo
->display
, "NULL", False
);
15098 dpyinfo
->Xatom_ATOM_PAIR
15099 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
15100 /* For properties of font. */
15101 dpyinfo
->Xatom_PIXEL_SIZE
15102 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
15103 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
15104 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
15105 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
15106 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
15107 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
15108 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
15110 /* Ghostscript support. */
15111 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
15112 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
15114 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
15117 dpyinfo
->cut_buffers_initialized
= 0;
15119 connection
= ConnectionNumber (dpyinfo
->display
);
15120 dpyinfo
->connection
= connection
;
15125 null_bits
[0] = 0x00;
15127 dpyinfo
->null_pixel
15128 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
15129 null_bits
, 1, 1, (long) 0, (long) 0,
15134 extern int gray_bitmap_width
, gray_bitmap_height
;
15135 extern char *gray_bitmap_bits
;
15137 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
15139 gray_bitmap_width
, gray_bitmap_height
,
15140 (unsigned long) 1, (unsigned long) 0, 1);
15144 xim_initialize (dpyinfo
, resource_name
);
15147 #ifdef subprocesses
15148 /* This is only needed for distinguishing keyboard and process input. */
15149 if (connection
!= 0)
15150 add_keyboard_wait_descriptor (connection
);
15153 #ifndef F_SETOWN_BUG
15155 #ifdef F_SETOWN_SOCK_NEG
15156 /* stdin is a socket here */
15157 fcntl (connection
, F_SETOWN
, -getpid ());
15158 #else /* ! defined (F_SETOWN_SOCK_NEG) */
15159 fcntl (connection
, F_SETOWN
, getpid ());
15160 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
15161 #endif /* ! defined (F_SETOWN) */
15162 #endif /* F_SETOWN_BUG */
15165 if (interrupt_input
)
15166 init_sigio (connection
);
15167 #endif /* ! defined (SIGIO) */
15170 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
15171 /* Make sure that we have a valid font for dialog boxes
15172 so that Xt does not crash. */
15174 Display
*dpy
= dpyinfo
->display
;
15175 XrmValue d
, fr
, to
;
15179 d
.addr
= (XPointer
)&dpy
;
15180 d
.size
= sizeof (Display
*);
15181 fr
.addr
= XtDefaultFont
;
15182 fr
.size
= sizeof (XtDefaultFont
);
15183 to
.size
= sizeof (Font
*);
15184 to
.addr
= (XPointer
)&font
;
15185 count
= x_catch_errors (dpy
);
15186 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
15188 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
15189 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
15190 x_uncatch_errors (dpy
, count
);
15195 /* See if we should run in synchronous mode. This is useful
15196 for debugging X code. */
15199 value
= display_x_get_resource (dpyinfo
,
15200 build_string ("synchronous"),
15201 build_string ("Synchronous"),
15203 if (STRINGP (value
)
15204 && (!strcmp (SDATA (value
), "true")
15205 || !strcmp (SDATA (value
), "on")))
15206 XSynchronize (dpyinfo
->display
, True
);
15214 /* Get rid of display DPYINFO, assuming all frames are already gone,
15215 and without sending any more commands to the X server. */
15218 x_delete_display (dpyinfo
)
15219 struct x_display_info
*dpyinfo
;
15221 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
15223 /* Discard this display from x_display_name_list and x_display_list.
15224 We can't use Fdelq because that can quit. */
15225 if (! NILP (x_display_name_list
)
15226 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
15227 x_display_name_list
= XCDR (x_display_name_list
);
15232 tail
= x_display_name_list
;
15233 while (CONSP (tail
) && CONSP (XCDR (tail
)))
15235 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
15237 XSETCDR (tail
, XCDR (XCDR (tail
)));
15240 tail
= XCDR (tail
);
15244 if (next_noop_dpyinfo
== dpyinfo
)
15245 next_noop_dpyinfo
= dpyinfo
->next
;
15247 if (x_display_list
== dpyinfo
)
15248 x_display_list
= dpyinfo
->next
;
15251 struct x_display_info
*tail
;
15253 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
15254 if (tail
->next
== dpyinfo
)
15255 tail
->next
= tail
->next
->next
;
15258 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
15259 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
15260 XrmDestroyDatabase (dpyinfo
->xrdb
);
15263 #ifdef MULTI_KBOARD
15264 if (--dpyinfo
->kboard
->reference_count
== 0)
15265 delete_kboard (dpyinfo
->kboard
);
15269 xim_close_dpy (dpyinfo
);
15272 xfree (dpyinfo
->font_table
);
15273 xfree (dpyinfo
->x_id_name
);
15274 xfree (dpyinfo
->color_cells
);
15279 /* Set up use of X before we make the first connection. */
15281 static struct redisplay_interface x_redisplay_interface
=
15286 x_clear_end_of_line
,
15288 x_after_update_window_line
,
15289 x_update_window_begin
,
15290 x_update_window_end
,
15293 x_clear_mouse_face
,
15294 x_get_glyph_overhangs
,
15295 x_fix_overlapping_area
15301 rif
= &x_redisplay_interface
;
15303 clear_frame_hook
= x_clear_frame
;
15304 ins_del_lines_hook
= x_ins_del_lines
;
15305 delete_glyphs_hook
= x_delete_glyphs
;
15306 ring_bell_hook
= XTring_bell
;
15307 reset_terminal_modes_hook
= XTreset_terminal_modes
;
15308 set_terminal_modes_hook
= XTset_terminal_modes
;
15309 update_begin_hook
= x_update_begin
;
15310 update_end_hook
= x_update_end
;
15311 set_terminal_window_hook
= XTset_terminal_window
;
15312 read_socket_hook
= XTread_socket
;
15313 frame_up_to_date_hook
= XTframe_up_to_date
;
15314 mouse_position_hook
= XTmouse_position
;
15315 frame_rehighlight_hook
= XTframe_rehighlight
;
15316 frame_raise_lower_hook
= XTframe_raise_lower
;
15317 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
15318 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
15319 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
15320 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
15321 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
15323 scroll_region_ok
= 1; /* we'll scroll partial frames */
15324 char_ins_del_ok
= 1;
15325 line_ins_del_ok
= 1; /* we'll just blt 'em */
15326 fast_clear_end_of_line
= 1; /* X does this well */
15327 memory_below_frame
= 0; /* we don't remember what scrolls
15332 last_tool_bar_item
= -1;
15333 any_help_event_p
= 0;
15335 /* Try to use interrupt input; if we can't, then start polling. */
15336 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
15338 #ifdef USE_X_TOOLKIT
15339 XtToolkitInitialize ();
15341 Xt_app_con
= XtCreateApplicationContext ();
15343 /* Register a converter from strings to pixels, which uses
15344 Emacs' color allocation infrastructure. */
15345 XtAppSetTypeConverter (Xt_app_con
,
15346 XtRString
, XtRPixel
, cvt_string_to_pixel
,
15347 cvt_string_to_pixel_args
,
15348 XtNumber (cvt_string_to_pixel_args
),
15349 XtCacheByDisplay
, cvt_pixel_dtor
);
15351 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
15353 /* Install an asynchronous timer that processes Xt timeout events
15354 every 0.1s. This is necessary because some widget sets use
15355 timeouts internally, for example the LessTif menu bar, or the
15356 Xaw3d scroll bar. When Xt timouts aren't processed, these
15357 widgets don't behave normally. */
15359 EMACS_TIME interval
;
15360 EMACS_SET_SECS_USECS (interval
, 0, 100000);
15361 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
15365 #ifdef USE_TOOLKIT_SCROLL_BARS
15366 xaw3d_arrow_scroll
= False
;
15367 xaw3d_pick_top
= True
;
15370 /* Note that there is no real way portable across R3/R4 to get the
15371 original error handler. */
15372 XSetErrorHandler (x_error_handler
);
15373 XSetIOErrorHandler (x_io_error_quitter
);
15375 /* Disable Window Change signals; they are handled by X events. */
15377 signal (SIGWINCH
, SIG_DFL
);
15378 #endif /* SIGWINCH */
15380 signal (SIGPIPE
, x_connection_signal
);
15383 x_session_initialize ();
15391 staticpro (&x_error_message_string
);
15392 x_error_message_string
= Qnil
;
15394 staticpro (&x_display_name_list
);
15395 x_display_name_list
= Qnil
;
15397 staticpro (&last_mouse_scroll_bar
);
15398 last_mouse_scroll_bar
= Qnil
;
15400 staticpro (&Qvendor_specific_keysyms
);
15401 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
15403 staticpro (&Qutf_8
);
15404 Qutf_8
= intern ("utf-8");
15405 staticpro (&Qlatin_1
);
15406 Qlatin_1
= intern ("latin-1");
15408 staticpro (&last_mouse_press_frame
);
15409 last_mouse_press_frame
= Qnil
;
15412 staticpro (&help_echo
);
15413 help_echo_object
= Qnil
;
15414 staticpro (&help_echo_object
);
15415 help_echo_window
= Qnil
;
15416 staticpro (&help_echo_window
);
15417 previous_help_echo
= Qnil
;
15418 staticpro (&previous_help_echo
);
15419 help_echo_pos
= -1;
15421 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
15422 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
15423 mouse_autoselect_window
= 0;
15425 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
15426 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
15427 For example, if a block cursor is over a tab, it will be drawn as
15428 wide as that tab on the display. */);
15429 x_stretch_cursor_p
= 0;
15431 DEFVAR_BOOL ("x-use-underline-position-properties",
15432 &x_use_underline_position_properties
,
15433 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
15434 nil means ignore them. If you encounter fonts with bogus
15435 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
15436 to 4.1, set this to nil. */);
15437 x_use_underline_position_properties
= 1;
15439 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
15440 doc
: /* What X toolkit scroll bars Emacs uses.
15441 A value of nil means Emacs doesn't use X toolkit scroll bars.
15442 Otherwise, value is a symbol describing the X toolkit. */);
15443 #ifdef USE_TOOLKIT_SCROLL_BARS
15445 Vx_toolkit_scroll_bars
= intern ("motif");
15446 #elif defined HAVE_XAW3D
15447 Vx_toolkit_scroll_bars
= intern ("xaw3d");
15449 Vx_toolkit_scroll_bars
= intern ("xaw");
15452 Vx_toolkit_scroll_bars
= Qnil
;
15455 staticpro (&last_mouse_motion_frame
);
15456 last_mouse_motion_frame
= Qnil
;
15458 Qmodifier_value
= intern ("modifier-value");
15459 Qalt
= intern ("alt");
15460 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
15461 Qhyper
= intern ("hyper");
15462 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
15463 Qmeta
= intern ("meta");
15464 Fput (Qmeta
, Qmodifier_value
, make_number (meta_modifier
));
15465 Qsuper
= intern ("super");
15466 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
15468 DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym
,
15469 doc
: /* Which keys Emacs uses for the alt modifier.
15470 This should be one of the symbols `alt', `hyper', `meta', `super'.
15471 For example, `alt' means use the Alt_L and Alt_R keysyms. The default
15472 is nil, which is the same as `alt'. */);
15473 Vx_alt_keysym
= Qnil
;
15475 DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym
,
15476 doc
: /* Which keys Emacs uses for the hyper modifier.
15477 This should be one of the symbols `alt', `hyper', `meta', `super'.
15478 For example, `hyper' means use the Hyper_L and Hyper_R keysyms. The
15479 default is nil, which is the same as `hyper'. */);
15480 Vx_hyper_keysym
= Qnil
;
15482 DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym
,
15483 doc
: /* Which keys Emacs uses for the meta modifier.
15484 This should be one of the symbols `alt', `hyper', `meta', `super'.
15485 For example, `meta' means use the Meta_L and Meta_R keysyms. The
15486 default is nil, which is the same as `meta'. */);
15487 Vx_meta_keysym
= Qnil
;
15489 DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym
,
15490 doc
: /* Which keys Emacs uses for the super modifier.
15491 This should be one of the symbols `alt', `hyper', `meta', `super'.
15492 For example, `super' means use the Super_L and Super_R keysyms. The
15493 default is nil, which is the same as `super'. */);
15494 Vx_super_keysym
= Qnil
;
15496 DEFVAR_LISP ("x-keysym-table", &Vx_keysym_table
,
15497 doc
: /* Hash table of character codes indexed by X keysym codes. */);
15498 Vx_keysym_table
= make_hash_table (Qeql
, make_number (900),
15499 make_float (DEFAULT_REHASH_SIZE
),
15500 make_float (DEFAULT_REHASH_THRESHOLD
),
15504 #endif /* HAVE_X_WINDOWS */