1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
23 /* Xt features made by Fred Pierresteguy. */
27 /* On 4.3 these lose if they come after xterm.h. */
28 /* Putting these at the beginning seems to be standard for other .c files. */
36 #include "blockinput.h"
38 /* Need syssignal.h for various externs and definitions that may be required
39 by some configurations for calls to signal later in this source file. */
40 #include "syssignal.h"
42 /* This may include sys/types.h, and that somehow loses
43 if this is not done before the other system files. */
45 #include <X11/cursorfont.h>
47 /* Load sys/types.h if not already loaded.
48 In some systems loading it twice is suicidal. */
50 #include <sys/types.h>
54 #include <sys/ioctl.h>
55 #endif /* ! defined (BSD_SYSTEM) */
60 #ifndef INCLUDED_FCNTL
67 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
68 /* #include <sys/param.h> */
74 #include "dispextern.h"
76 #include "termhooks.h"
88 #include "intervals.h"
93 #include <X11/Shell.h>
96 #ifdef HAVE_SYS_TIME_H
105 extern void free_frame_menubar
P_ ((struct frame
*));
106 extern struct frame
*x_menubar_window_to_frame
P_ ((struct x_display_info
*,
109 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
111 extern void _XEditResCheckMessages ();
112 #endif /* not NO_EDITRES */
114 /* Include toolkit specific headers for the scroll bar widget. */
116 #ifdef USE_TOOLKIT_SCROLL_BARS
117 #if defined USE_MOTIF
118 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
119 #include <Xm/ScrollBar.h>
120 #else /* !USE_MOTIF i.e. use Xaw */
123 #include <X11/Xaw3d/Simple.h>
124 #include <X11/Xaw3d/Scrollbar.h>
125 #define ARROW_SCROLLBAR
126 #include <X11/Xaw3d/ScrollbarP.h>
127 #else /* !HAVE_XAW3D */
128 #include <X11/Xaw/Simple.h>
129 #include <X11/Xaw/Scrollbar.h>
130 #endif /* !HAVE_XAW3D */
132 #define XtNpickTop "pickTop"
133 #endif /* !XtNpickTop */
134 #endif /* !USE_MOTIF */
135 #endif /* USE_TOOLKIT_SCROLL_BARS */
137 #endif /* USE_X_TOOLKIT */
139 #ifndef USE_X_TOOLKIT
140 #define x_any_window_to_frame x_window_to_frame
141 #define x_top_window_to_frame x_window_to_frame
146 #ifndef XtNinitialState
147 #define XtNinitialState "initialState"
152 #define min(a,b) ((a) < (b) ? (a) : (b))
155 #define max(a,b) ((a) > (b) ? (a) : (b))
158 #define abs(x) ((x) < 0 ? -(x) : (x))
160 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
163 /* Bitmaps for truncated lines. */
168 LEFT_TRUNCATION_BITMAP
,
169 RIGHT_TRUNCATION_BITMAP
,
170 OVERLAY_ARROW_BITMAP
,
171 CONTINUED_LINE_BITMAP
,
172 CONTINUATION_LINE_BITMAP
,
176 /* Bitmap drawn to indicate lines not displaying text if
177 `indicate-empty-lines' is non-nil. */
181 static unsigned char zv_bits
[] = {
182 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
184 /* An arrow like this: `<-'. */
187 #define left_height 8
188 static unsigned char left_bits
[] = {
189 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
191 /* Right truncation arrow bitmap `->'. */
193 #define right_width 8
194 #define right_height 8
195 static unsigned char right_bits
[] = {
196 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
198 /* Marker for continued lines. */
200 #define continued_width 8
201 #define continued_height 8
202 static unsigned char continued_bits
[] = {
203 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
205 /* Marker for continuation lines. */
207 #define continuation_width 8
208 #define continuation_height 8
209 static unsigned char continuation_bits
[] = {
210 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
212 /* Overlay arrow bitmap. */
218 static unsigned char ov_bits
[] = {
219 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
221 /* A triangular arrow. */
224 static unsigned char ov_bits
[] = {
225 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
229 extern Lisp_Object Qhelp_echo
;
232 /* Non-nil means Emacs uses toolkit scroll bars. */
234 Lisp_Object Vx_toolkit_scroll_bars
;
236 /* If a string, XTread_socket generates an event to display that string.
237 (The display is done in read_char.) */
239 static Lisp_Object help_echo
;
240 static Lisp_Object help_echo_window
;
241 static Lisp_Object help_echo_object
;
242 static int help_echo_pos
;
244 /* Temporary variable for XTread_socket. */
246 static Lisp_Object previous_help_echo
;
248 /* Non-zero means that a HELP_EVENT has been generated since Emacs
251 static int any_help_event_p
;
253 /* Non-zero means draw block and hollow cursor as wide as the glyph
254 under it. For example, if a block cursor is over a tab, it will be
255 drawn as wide as that tab on the display. */
257 int x_stretch_cursor_p
;
259 /* This is a chain of structures for all the X displays currently in
262 struct x_display_info
*x_display_list
;
264 /* This is a list of cons cells, each of the form (NAME
265 . FONT-LIST-CACHE), one for each element of x_display_list and in
266 the same order. NAME is the name of the frame. FONT-LIST-CACHE
267 records previous values returned by x-list-fonts. */
269 Lisp_Object x_display_name_list
;
271 /* Frame being updated by update_frame. This is declared in term.c.
272 This is set by update_begin and looked at by all the XT functions.
273 It is zero while not inside an update. In that case, the XT
274 functions assume that `selected_frame' is the frame to apply to. */
276 extern struct frame
*updating_frame
;
278 extern int waiting_for_input
;
280 /* This is a frame waiting to be auto-raised, within XTread_socket. */
282 struct frame
*pending_autoraise_frame
;
285 /* The application context for Xt use. */
286 XtAppContext Xt_app_con
;
287 static String Xt_default_resources
[] = {0};
288 #endif /* USE_X_TOOLKIT */
290 /* Nominal cursor position -- where to draw output.
291 HPOS and VPOS are window relative glyph matrix coordinates.
292 X and Y are window relative pixel coordinates. */
294 struct cursor_pos output_cursor
;
296 /* Non-zero means user is interacting with a toolkit scroll bar. */
298 static int toolkit_scroll_bar_interaction
;
302 Formerly, we used PointerMotionHintMask (in standard_event_mask)
303 so that we would have to call XQueryPointer after each MotionNotify
304 event to ask for another such event. However, this made mouse tracking
305 slow, and there was a bug that made it eventually stop.
307 Simply asking for MotionNotify all the time seems to work better.
309 In order to avoid asking for motion events and then throwing most
310 of them away or busy-polling the server for mouse positions, we ask
311 the server for pointer motion hints. This means that we get only
312 one event per group of mouse movements. "Groups" are delimited by
313 other kinds of events (focus changes and button clicks, for
314 example), or by XQueryPointer calls; when one of these happens, we
315 get another MotionNotify event the next time the mouse moves. This
316 is at least as efficient as getting motion events when mouse
317 tracking is on, and I suspect only negligibly worse when tracking
320 /* Where the mouse was last time we reported a mouse event. */
322 FRAME_PTR last_mouse_frame
;
323 static XRectangle last_mouse_glyph
;
324 static Lisp_Object last_mouse_press_frame
;
326 /* The scroll bar in which the last X motion event occurred.
328 If the last X motion event occurred in a scroll bar, we set this so
329 XTmouse_position can know whether to report a scroll bar motion or
332 If the last X motion event didn't occur in a scroll bar, we set
333 this to Qnil, to tell XTmouse_position to return an ordinary motion
336 static Lisp_Object last_mouse_scroll_bar
;
338 /* This is a hack. We would really prefer that XTmouse_position would
339 return the time associated with the position it returns, but there
340 doesn't seem to be any way to wrest the time-stamp from the server
341 along with the position query. So, we just keep track of the time
342 of the last movement we received, and return that in hopes that
343 it's somewhat accurate. */
345 static Time last_mouse_movement_time
;
347 /* Incremented by XTread_socket whenever it really tries to read
351 static int volatile input_signal_count
;
353 static int input_signal_count
;
356 /* Used locally within XTread_socket. */
358 static int x_noop_count
;
360 /* Initial values of argv and argc. */
362 extern char **initial_argv
;
363 extern int initial_argc
;
365 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
367 /* Tells if a window manager is present or not. */
369 extern Lisp_Object Vx_no_window_manager
;
371 extern Lisp_Object Qface
, Qmouse_face
;
375 /* A mask of extra modifier bits to put into every keyboard char. */
377 extern int extra_keyboard_modifiers
;
379 static Lisp_Object Qvendor_specific_keysyms
;
381 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
382 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
385 /* Enumeration for overriding/changing the face to use for drawing
386 glyphs in x_draw_glyphs. */
388 enum draw_glyphs_face
398 static void x_set_window_size_1
P_ ((struct frame
*, int, int, int));
399 static const XColor
*x_color_cells
P_ ((struct frame
*, int *));
400 static void x_update_window_end
P_ ((struct window
*, int, int));
401 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
402 void x_delete_display
P_ ((struct x_display_info
*));
403 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
405 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
407 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
408 int *, int *, int *, int *, int));
409 static void set_output_cursor
P_ ((struct cursor_pos
*));
410 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
411 int *, int *, int *, int));
412 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
413 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
414 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
415 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
416 static void show_mouse_face
P_ ((struct x_display_info
*,
417 enum draw_glyphs_face
));
418 static int x_io_error_quitter
P_ ((Display
*));
419 int x_catch_errors
P_ ((Display
*));
420 void x_uncatch_errors
P_ ((Display
*, int));
421 void x_lower_frame
P_ ((struct frame
*));
422 void x_scroll_bar_clear
P_ ((struct frame
*));
423 int x_had_errors_p
P_ ((Display
*));
424 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
425 void x_raise_frame
P_ ((struct frame
*));
426 void x_set_window_size
P_ ((struct frame
*, int, int, int));
427 void x_wm_set_window_state
P_ ((struct frame
*, int));
428 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
429 void x_initialize
P_ ((void));
430 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
431 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
432 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
434 enum draw_glyphs_face
));
435 static void x_update_end
P_ ((struct frame
*));
436 static void XTframe_up_to_date
P_ ((struct frame
*));
437 static void XTreassert_line_highlight
P_ ((int, int));
438 static void x_change_line_highlight
P_ ((int, int, int, int));
439 static void XTset_terminal_modes
P_ ((void));
440 static void XTreset_terminal_modes
P_ ((void));
441 static void XTcursor_to
P_ ((int, int, int, int));
442 static void x_write_glyphs
P_ ((struct glyph
*, int));
443 static void x_clear_end_of_line
P_ ((int));
444 static void x_clear_frame
P_ ((void));
445 static void x_clear_cursor
P_ ((struct window
*));
446 static void frame_highlight
P_ ((struct frame
*));
447 static void frame_unhighlight
P_ ((struct frame
*));
448 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
449 static void XTframe_rehighlight
P_ ((struct frame
*));
450 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
451 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
452 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
453 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
455 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
456 static void expose_window_tree
P_ ((struct window
*, XRectangle
*));
457 static void expose_window
P_ ((struct window
*, XRectangle
*));
458 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
459 XRectangle
*, enum glyph_row_area
));
460 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
462 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
463 static void x_update_window_cursor
P_ ((struct window
*, int));
464 static void x_erase_phys_cursor
P_ ((struct window
*));
465 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
466 static void x_draw_bitmap
P_ ((struct window
*, struct glyph_row
*,
469 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
471 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
472 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
473 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
474 static void x_flush
P_ ((struct frame
*f
));
475 static void x_update_begin
P_ ((struct frame
*));
476 static void x_update_window_begin
P_ ((struct window
*));
477 static void x_draw_vertical_border
P_ ((struct window
*));
478 static void x_after_update_window_line
P_ ((struct glyph_row
*));
479 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
480 static void x_produce_stretch_glyph
P_ ((struct it
*));
481 static struct scroll_bar
*x_window_to_scroll_bar
P_ ((Window
));
482 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
483 enum scroll_bar_part
*,
484 Lisp_Object
*, Lisp_Object
*,
487 /* Flush display of frame F, or of all frames if F is null. */
496 Lisp_Object rest
, frame
;
497 FOR_EACH_FRAME (rest
, frame
)
498 x_flush (XFRAME (frame
));
500 else if (FRAME_X_P (f
))
501 XFlush (FRAME_X_DISPLAY (f
));
506 /* Remove calls to XFlush by defining XFlush to an empty replacement.
507 Calls to XFlush should be unnecessary because the X output buffer
508 is flushed automatically as needed by calls to XPending,
509 XNextEvent, or XWindowEvent according to the XFlush man page.
510 XTread_socket calls XPending. Removing XFlush improves
513 #define XFlush(DISPLAY) (void) 0
516 /***********************************************************************
518 ***********************************************************************/
522 /* This is a function useful for recording debugging information about
523 the sequence of occurrences in this file. */
531 struct record event_record
[100];
533 int event_record_index
;
535 record_event (locus
, type
)
539 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
540 event_record_index
= 0;
542 event_record
[event_record_index
].locus
= locus
;
543 event_record
[event_record_index
].type
= type
;
544 event_record_index
++;
551 /* Return the struct x_display_info corresponding to DPY. */
553 struct x_display_info
*
554 x_display_info_for_display (dpy
)
557 struct x_display_info
*dpyinfo
;
559 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
560 if (dpyinfo
->display
== dpy
)
568 /***********************************************************************
569 Starting and ending an update
570 ***********************************************************************/
572 /* Start an update of frame F. This function is installed as a hook
573 for update_begin, i.e. it is called when update_begin is called.
574 This function is called prior to calls to x_update_window_begin for
575 each window being updated. Currently, there is nothing to do here
576 because all interesting stuff is done on a window basis. */
586 /* Start update of window W. Set the global variable updated_window
587 to the window being updated and set output_cursor to the cursor
591 x_update_window_begin (w
)
594 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
595 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
598 set_output_cursor (&w
->cursor
);
602 if (f
== display_info
->mouse_face_mouse_frame
)
604 /* Don't do highlighting for mouse motion during the update. */
605 display_info
->mouse_face_defer
= 1;
607 /* If F needs to be redrawn, simply forget about any prior mouse
609 if (FRAME_GARBAGED_P (f
))
610 display_info
->mouse_face_window
= Qnil
;
612 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
613 their mouse_face_p flag set, which means that they are always
614 unequal to rows in a desired matrix which never have that
615 flag set. So, rows containing mouse-face glyphs are never
616 scrolled, and we don't have to switch the mouse highlight off
617 here to prevent it from being scrolled. */
619 /* Can we tell that this update does not affect the window
620 where the mouse highlight is? If so, no need to turn off.
621 Likewise, don't do anything if the frame is garbaged;
622 in that case, the frame's current matrix that we would use
623 is all wrong, and we will redisplay that line anyway. */
624 if (!NILP (display_info
->mouse_face_window
)
625 && w
== XWINDOW (display_info
->mouse_face_window
))
629 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
630 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
633 if (i
< w
->desired_matrix
->nrows
)
634 clear_mouse_face (display_info
);
643 /* Draw a vertical window border to the right of window W if W doesn't
644 have vertical scroll bars. */
647 x_draw_vertical_border (w
)
650 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
652 /* Redraw borders between horizontally adjacent windows. Don't
653 do it for frames with vertical scroll bars because either the
654 right scroll bar of a window, or the left scroll bar of its
655 neighbor will suffice as a border. */
656 if (!WINDOW_RIGHTMOST_P (w
)
657 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
661 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
662 x1
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
665 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
666 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
671 /* End update of window W (which is equal to updated_window).
673 Draw vertical borders between horizontally adjacent windows, and
674 display W's cursor if CURSOR_ON_P is non-zero.
676 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
677 glyphs in mouse-face were overwritten. In that case we have to
678 make sure that the mouse-highlight is properly redrawn.
680 W may be a menu bar pseudo-window in case we don't have X toolkit
681 support. Such windows don't have a cursor, so don't display it
685 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
687 int cursor_on_p
, mouse_face_overwritten_p
;
689 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
691 if (!w
->pseudo_window_p
)
696 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
698 output_cursor
.x
, output_cursor
.y
);
700 x_draw_vertical_border (w
);
704 /* If a row with mouse-face was overwritten, arrange for
705 XTframe_up_to_date to redisplay the mouse highlight. */
706 if (mouse_face_overwritten_p
)
708 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
709 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
710 dpyinfo
->mouse_face_window
= Qnil
;
713 updated_window
= NULL
;
717 /* End update of frame F. This function is installed as a hook in
724 /* Mouse highlight may be displayed again. */
725 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
728 XFlush (FRAME_X_DISPLAY (f
));
733 /* This function is called from various places in xdisp.c whenever a
734 complete update has been performed. The global variable
735 updated_window is not available here. */
738 XTframe_up_to_date (f
)
743 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
745 if (dpyinfo
->mouse_face_deferred_gc
746 || f
== dpyinfo
->mouse_face_mouse_frame
)
749 if (dpyinfo
->mouse_face_mouse_frame
)
750 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
751 dpyinfo
->mouse_face_mouse_x
,
752 dpyinfo
->mouse_face_mouse_y
);
753 dpyinfo
->mouse_face_deferred_gc
= 0;
760 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
761 arrow bitmaps, or clear the areas where they would be displayed
762 before DESIRED_ROW is made current. The window being updated is
763 found in updated_window. This function It is called from
764 update_window_line only if it is known that there are differences
765 between bitmaps to be drawn between current row and DESIRED_ROW. */
768 x_after_update_window_line (desired_row
)
769 struct glyph_row
*desired_row
;
771 struct window
*w
= updated_window
;
775 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
781 x_draw_row_bitmaps (w
, desired_row
);
783 /* When a window has disappeared, make sure that no rest of
784 full-width rows stays visible in the internal border. */
785 if (windows_or_buffers_changed
786 && (f
= XFRAME (w
->frame
),
787 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
790 int height
= desired_row
->visible_height
;
791 int x
= (window_box_right (w
, -1)
792 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
793 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
795 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
796 x
, y
, width
, height
, False
);
804 /* Draw the bitmap WHICH in one of the areas to the left or right of
805 window W. ROW is the glyph row for which to display the bitmap; it
806 determines the vertical position at which the bitmap has to be
810 x_draw_bitmap (w
, row
, which
)
812 struct glyph_row
*row
;
813 enum bitmap_type which
;
815 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
816 Display
*display
= FRAME_X_DISPLAY (f
);
817 Window window
= FRAME_X_WINDOW (f
);
821 GC gc
= f
->output_data
.x
->normal_gc
;
823 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
825 /* Must clip because of partially visible lines. */
826 x_clip_to_row (w
, row
, gc
, 1);
830 case LEFT_TRUNCATION_BITMAP
:
834 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
836 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
839 case OVERLAY_ARROW_BITMAP
:
843 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
845 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
848 case RIGHT_TRUNCATION_BITMAP
:
852 x
= window_box_right (w
, -1);
853 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
856 case CONTINUED_LINE_BITMAP
:
859 bits
= continued_bits
;
860 x
= window_box_right (w
, -1);
861 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
864 case CONTINUATION_LINE_BITMAP
:
865 wd
= continuation_width
;
866 h
= continuation_height
;
867 bits
= continuation_bits
;
868 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
870 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
877 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
879 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
886 /* Convert to frame coordinates. Set dy to the offset in the row to
887 start drawing the bitmap. */
888 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
889 dy
= (row
->height
- h
) / 2;
891 /* Draw the bitmap. I believe these small pixmaps can be cached
893 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
894 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
896 face
->background
, depth
);
897 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
898 XFreePixmap (display
, pixmap
);
899 XSetClipMask (display
, gc
, None
);
903 /* Draw flags bitmaps for glyph row ROW on window W. Call this
904 function with input blocked. */
907 x_draw_row_bitmaps (w
, row
)
909 struct glyph_row
*row
;
911 struct frame
*f
= XFRAME (w
->frame
);
912 enum bitmap_type bitmap
;
914 int header_line_height
= -1;
916 xassert (interrupt_input_blocked
);
918 /* If row is completely invisible, because of vscrolling, we
919 don't have to draw anything. */
920 if (row
->visible_height
<= 0)
923 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
924 PREPARE_FACE_FOR_DISPLAY (f
, face
);
926 /* Decide which bitmap to draw at the left side. */
927 if (row
->overlay_arrow_p
)
928 bitmap
= OVERLAY_ARROW_BITMAP
;
929 else if (row
->truncated_on_left_p
)
930 bitmap
= LEFT_TRUNCATION_BITMAP
;
931 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
932 bitmap
= CONTINUATION_LINE_BITMAP
;
933 else if (row
->indicate_empty_line_p
)
934 bitmap
= ZV_LINE_BITMAP
;
938 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
940 if (bitmap
== NO_BITMAP
941 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
942 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
944 /* If W has a vertical border to its left, don't draw over it. */
945 int border
= ((XFASTINT (w
->left
) > 0
946 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
948 int left
= window_box_left (w
, -1);
950 if (header_line_height
< 0)
951 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
953 /* In case the same realized face is used for bitmap areas and
954 for something displayed in the text (e.g. face `region' on
955 mono-displays, the fill style may have been changed to
956 FillSolid in x_draw_glyph_string_background. */
958 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
960 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
962 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
965 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
967 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
969 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
970 row
->visible_height
);
972 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
975 /* Draw the left bitmap. */
976 if (bitmap
!= NO_BITMAP
)
977 x_draw_bitmap (w
, row
, bitmap
);
979 /* Decide which bitmap to draw at the right side. */
980 if (row
->truncated_on_right_p
)
981 bitmap
= RIGHT_TRUNCATION_BITMAP
;
982 else if (row
->continued_p
)
983 bitmap
= CONTINUED_LINE_BITMAP
;
987 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
989 if (bitmap
== NO_BITMAP
990 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
991 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
993 int right
= window_box_right (w
, -1);
995 if (header_line_height
< 0)
996 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
998 /* In case the same realized face is used for bitmap areas and
999 for something displayed in the text (e.g. face `region' on
1000 mono-displays, the fill style may have been changed to
1001 FillSolid in x_draw_glyph_string_background. */
1003 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1005 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1006 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1009 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1011 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
1012 row
->visible_height
);
1014 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1017 /* Draw the right bitmap. */
1018 if (bitmap
!= NO_BITMAP
)
1019 x_draw_bitmap (w
, row
, bitmap
);
1023 /***********************************************************************
1025 ***********************************************************************/
1027 /* External interface to control of standout mode. Not used for X
1028 frames. Aborts when called. */
1031 XTreassert_line_highlight (new, vpos
)
1038 /* Call this when about to modify line at position VPOS and change
1039 whether it is highlighted. Not used for X frames. Aborts when
1043 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1044 int new_highlight
, vpos
, y
, first_unused_hpos
;
1050 /* This is called when starting Emacs and when restarting after
1051 suspend. When starting Emacs, no X window is mapped. And nothing
1052 must be done to Emacs's own window if it is suspended (though that
1056 XTset_terminal_modes ()
1060 /* This is called when exiting or suspending Emacs. Exiting will make
1061 the X-windows go away, and suspending requires no action. */
1064 XTreset_terminal_modes ()
1070 /***********************************************************************
1072 ***********************************************************************/
1074 /* Set the global variable output_cursor to CURSOR. All cursor
1075 positions are relative to updated_window. */
1078 set_output_cursor (cursor
)
1079 struct cursor_pos
*cursor
;
1081 output_cursor
.hpos
= cursor
->hpos
;
1082 output_cursor
.vpos
= cursor
->vpos
;
1083 output_cursor
.x
= cursor
->x
;
1084 output_cursor
.y
= cursor
->y
;
1088 /* Set a nominal cursor position.
1090 HPOS and VPOS are column/row positions in a window glyph matrix. X
1091 and Y are window text area relative pixel positions.
1093 If this is done during an update, updated_window will contain the
1094 window that is being updated and the position is the future output
1095 cursor position for that window. If updated_window is null, use
1096 selected_window and display the cursor at the given position. */
1099 XTcursor_to (vpos
, hpos
, y
, x
)
1100 int vpos
, hpos
, y
, x
;
1104 /* If updated_window is not set, work on selected_window. */
1108 w
= XWINDOW (selected_window
);
1110 /* Set the output cursor. */
1111 output_cursor
.hpos
= hpos
;
1112 output_cursor
.vpos
= vpos
;
1113 output_cursor
.x
= x
;
1114 output_cursor
.y
= y
;
1116 /* If not called as part of an update, really display the cursor.
1117 This will also set the cursor position of W. */
1118 if (updated_window
== NULL
)
1121 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1122 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1129 /***********************************************************************
1131 ***********************************************************************/
1133 /* Function prototypes of this page. */
1135 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1139 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1140 int, XChar2b
*, int));
1141 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1142 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1143 static void x_append_glyph
P_ ((struct it
*));
1144 static void x_append_composite_glyph
P_ ((struct it
*));
1145 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1147 static void x_produce_glyphs
P_ ((struct it
*));
1148 static void x_produce_image_glyph
P_ ((struct it
*it
));
1151 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1152 is not contained in the font. */
1154 static INLINE XCharStruct
*
1155 x_per_char_metric (font
, char2b
)
1159 /* The result metric information. */
1160 XCharStruct
*pcm
= NULL
;
1162 xassert (font
&& char2b
);
1164 if (font
->per_char
!= NULL
)
1166 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1168 /* min_char_or_byte2 specifies the linear character index
1169 corresponding to the first element of the per_char array,
1170 max_char_or_byte2 is the index of the last character. A
1171 character with non-zero CHAR2B->byte1 is not in the font.
1172 A character with byte2 less than min_char_or_byte2 or
1173 greater max_char_or_byte2 is not in the font. */
1174 if (char2b
->byte1
== 0
1175 && char2b
->byte2
>= font
->min_char_or_byte2
1176 && char2b
->byte2
<= font
->max_char_or_byte2
)
1177 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1181 /* If either min_byte1 or max_byte1 are nonzero, both
1182 min_char_or_byte2 and max_char_or_byte2 are less than
1183 256, and the 2-byte character index values corresponding
1184 to the per_char array element N (counting from 0) are:
1186 byte1 = N/D + min_byte1
1187 byte2 = N\D + min_char_or_byte2
1191 D = max_char_or_byte2 - min_char_or_byte2 + 1
1192 / = integer division
1193 \ = integer modulus */
1194 if (char2b
->byte1
>= font
->min_byte1
1195 && char2b
->byte1
<= font
->max_byte1
1196 && char2b
->byte2
>= font
->min_char_or_byte2
1197 && char2b
->byte2
<= font
->max_char_or_byte2
)
1199 pcm
= (font
->per_char
1200 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1201 * (char2b
->byte1
- font
->min_byte1
))
1202 + (char2b
->byte2
- font
->min_char_or_byte2
));
1208 /* If the per_char pointer is null, all glyphs between the first
1209 and last character indexes inclusive have the same
1210 information, as given by both min_bounds and max_bounds. */
1211 if (char2b
->byte2
>= font
->min_char_or_byte2
1212 && char2b
->byte2
<= font
->max_char_or_byte2
)
1213 pcm
= &font
->max_bounds
;
1216 return ((pcm
== NULL
1217 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1222 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1223 the two-byte form of C. Encoding is returned in *CHAR2B. */
1226 x_encode_char (c
, char2b
, font_info
)
1229 struct font_info
*font_info
;
1231 int charset
= CHAR_CHARSET (c
);
1232 XFontStruct
*font
= font_info
->font
;
1234 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1235 This may be either a program in a special encoder language or a
1237 if (font_info
->font_encoder
)
1239 /* It's a program. */
1240 struct ccl_program
*ccl
= font_info
->font_encoder
;
1242 if (CHARSET_DIMENSION (charset
) == 1)
1244 ccl
->reg
[0] = charset
;
1245 ccl
->reg
[1] = char2b
->byte2
;
1249 ccl
->reg
[0] = charset
;
1250 ccl
->reg
[1] = char2b
->byte1
;
1251 ccl
->reg
[2] = char2b
->byte2
;
1254 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1256 /* We assume that MSBs are appropriately set/reset by CCL
1258 if (font
->max_byte1
== 0) /* 1-byte font */
1259 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1261 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1263 else if (font_info
->encoding
[charset
])
1265 /* Fixed encoding scheme. See fontset.h for the meaning of the
1266 encoding numbers. */
1267 int enc
= font_info
->encoding
[charset
];
1269 if ((enc
== 1 || enc
== 2)
1270 && CHARSET_DIMENSION (charset
) == 2)
1271 char2b
->byte1
|= 0x80;
1273 if (enc
== 1 || enc
== 3)
1274 char2b
->byte2
|= 0x80;
1279 /* Get face and two-byte form of character C in face FACE_ID on frame
1280 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1281 means we want to display multibyte text. Value is a pointer to a
1282 realized face that is ready for display. */
1284 static INLINE
struct face
*
1285 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1291 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1295 /* Unibyte case. We don't have to encode, but we have to make
1296 sure to use a face suitable for unibyte. */
1299 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1300 face
= FACE_FROM_ID (f
, face_id
);
1302 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1304 /* Case of ASCII in a face known to fit ASCII. */
1310 int c1
, c2
, charset
;
1312 /* Split characters into bytes. If c2 is -1 afterwards, C is
1313 really a one-byte character so that byte1 is zero. */
1314 SPLIT_CHAR (c
, charset
, c1
, c2
);
1316 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1318 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1320 /* Maybe encode the character in *CHAR2B. */
1321 if (face
->font
!= NULL
)
1323 struct font_info
*font_info
1324 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1326 x_encode_char (c
, char2b
, font_info
);
1330 /* Make sure X resources of the face are allocated. */
1331 xassert (face
!= NULL
);
1332 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1338 /* Get face and two-byte form of character glyph GLYPH on frame F.
1339 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1340 a pointer to a realized face that is ready for display. */
1342 static INLINE
struct face
*
1343 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1345 struct glyph
*glyph
;
1351 xassert (glyph
->type
== CHAR_GLYPH
);
1352 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1357 if (!glyph
->multibyte_p
)
1359 /* Unibyte case. We don't have to encode, but we have to make
1360 sure to use a face suitable for unibyte. */
1362 char2b
->byte2
= glyph
->u
.ch
;
1364 else if (glyph
->u
.ch
< 128
1365 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1367 /* Case of ASCII in a face known to fit ASCII. */
1369 char2b
->byte2
= glyph
->u
.ch
;
1373 int c1
, c2
, charset
;
1375 /* Split characters into bytes. If c2 is -1 afterwards, C is
1376 really a one-byte character so that byte1 is zero. */
1377 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1379 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1381 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1383 /* Maybe encode the character in *CHAR2B. */
1384 if (charset
!= CHARSET_ASCII
)
1386 struct font_info
*font_info
1387 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1390 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1393 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1398 /* Make sure X resources of the face are allocated. */
1399 xassert (face
!= NULL
);
1400 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1405 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1406 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1412 struct glyph
*glyph
;
1413 enum glyph_row_area area
= it
->area
;
1415 xassert (it
->glyph_row
);
1416 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1418 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1419 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1421 glyph
->charpos
= CHARPOS (it
->position
);
1422 glyph
->object
= it
->object
;
1423 glyph
->pixel_width
= it
->pixel_width
;
1424 glyph
->voffset
= it
->voffset
;
1425 glyph
->type
= CHAR_GLYPH
;
1426 glyph
->multibyte_p
= it
->multibyte_p
;
1427 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1428 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1429 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1430 || it
->phys_descent
> it
->descent
);
1431 glyph
->padding_p
= 0;
1432 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1433 glyph
->face_id
= it
->face_id
;
1434 glyph
->u
.ch
= it
->char_to_display
;
1435 ++it
->glyph_row
->used
[area
];
1439 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1440 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1443 x_append_composite_glyph (it
)
1446 struct glyph
*glyph
;
1447 enum glyph_row_area area
= it
->area
;
1449 xassert (it
->glyph_row
);
1451 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1452 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1454 glyph
->charpos
= CHARPOS (it
->position
);
1455 glyph
->object
= it
->object
;
1456 glyph
->pixel_width
= it
->pixel_width
;
1457 glyph
->voffset
= it
->voffset
;
1458 glyph
->type
= COMPOSITE_GLYPH
;
1459 glyph
->multibyte_p
= it
->multibyte_p
;
1460 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1461 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1462 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1463 || it
->phys_descent
> it
->descent
);
1464 glyph
->padding_p
= 0;
1465 glyph
->glyph_not_available_p
= 0;
1466 glyph
->face_id
= it
->face_id
;
1467 glyph
->u
.cmp_id
= it
->cmp_id
;
1468 ++it
->glyph_row
->used
[area
];
1473 /* Change IT->ascent and IT->height according to the setting of
1477 take_vertical_position_into_account (it
)
1482 if (it
->voffset
< 0)
1483 /* Increase the ascent so that we can display the text higher
1485 it
->ascent
+= abs (it
->voffset
);
1487 /* Increase the descent so that we can display the text lower
1489 it
->descent
+= it
->voffset
;
1494 /* Produce glyphs/get display metrics for the image IT is loaded with.
1495 See the description of struct display_iterator in dispextern.h for
1496 an overview of struct display_iterator. */
1499 x_produce_image_glyph (it
)
1505 xassert (it
->what
== IT_IMAGE
);
1507 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1508 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1511 /* Make sure X resources of the face and image are loaded. */
1512 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1513 prepare_image_for_display (it
->f
, img
);
1515 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1516 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1517 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1521 if (face
->box
!= FACE_NO_BOX
)
1523 if (face
->box_line_width
> 0)
1525 it
->ascent
+= face
->box_line_width
;
1526 it
->descent
+= face
->box_line_width
;
1529 if (it
->start_of_box_run_p
)
1530 it
->pixel_width
+= abs (face
->box_line_width
);
1531 if (it
->end_of_box_run_p
)
1532 it
->pixel_width
+= abs (face
->box_line_width
);
1535 take_vertical_position_into_account (it
);
1539 struct glyph
*glyph
;
1540 enum glyph_row_area area
= it
->area
;
1542 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1543 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1545 glyph
->charpos
= CHARPOS (it
->position
);
1546 glyph
->object
= it
->object
;
1547 glyph
->pixel_width
= it
->pixel_width
;
1548 glyph
->voffset
= it
->voffset
;
1549 glyph
->type
= IMAGE_GLYPH
;
1550 glyph
->multibyte_p
= it
->multibyte_p
;
1551 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1552 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1553 glyph
->overlaps_vertically_p
= 0;
1554 glyph
->padding_p
= 0;
1555 glyph
->glyph_not_available_p
= 0;
1556 glyph
->face_id
= it
->face_id
;
1557 glyph
->u
.img_id
= img
->id
;
1558 ++it
->glyph_row
->used
[area
];
1564 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1565 of the glyph, WIDTH and HEIGHT are the width and height of the
1566 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1567 ascent of the glyph (0 <= ASCENT <= 1). */
1570 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1576 struct glyph
*glyph
;
1577 enum glyph_row_area area
= it
->area
;
1579 xassert (ascent
>= 0 && ascent
<= 1);
1581 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1582 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1584 glyph
->charpos
= CHARPOS (it
->position
);
1585 glyph
->object
= object
;
1586 glyph
->pixel_width
= width
;
1587 glyph
->voffset
= it
->voffset
;
1588 glyph
->type
= STRETCH_GLYPH
;
1589 glyph
->multibyte_p
= it
->multibyte_p
;
1590 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1591 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1592 glyph
->overlaps_vertically_p
= 0;
1593 glyph
->padding_p
= 0;
1594 glyph
->glyph_not_available_p
= 0;
1595 glyph
->face_id
= it
->face_id
;
1596 glyph
->u
.stretch
.ascent
= height
* ascent
;
1597 glyph
->u
.stretch
.height
= height
;
1598 ++it
->glyph_row
->used
[area
];
1603 /* Produce a stretch glyph for iterator IT. IT->object is the value
1604 of the glyph property displayed. The value must be a list
1605 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1608 1. `:width WIDTH' specifies that the space should be WIDTH *
1609 canonical char width wide. WIDTH may be an integer or floating
1612 2. `:relative-width FACTOR' specifies that the width of the stretch
1613 should be computed from the width of the first character having the
1614 `glyph' property, and should be FACTOR times that width.
1616 3. `:align-to HPOS' specifies that the space should be wide enough
1617 to reach HPOS, a value in canonical character units.
1619 Exactly one of the above pairs must be present.
1621 4. `:height HEIGHT' specifies that the height of the stretch produced
1622 should be HEIGHT, measured in canonical character units.
1624 5. `:relative-height FACTOR' specifies that the height of the the
1625 stretch should be FACTOR times the height of the characters having
1628 Either none or exactly one of 4 or 5 must be present.
1630 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1631 of the stretch should be used for the ascent of the stretch.
1632 ASCENT must be in the range 0 <= ASCENT <= 100. */
1635 ((INTEGERP (X) || FLOATP (X)) \
1641 x_produce_stretch_glyph (it
)
1644 /* (space :width WIDTH :height HEIGHT. */
1646 extern Lisp_Object Qspace
;
1648 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1649 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1650 extern Lisp_Object QCalign_to
;
1651 Lisp_Object prop
, plist
;
1652 double width
= 0, height
= 0, ascent
= 0;
1653 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1654 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1656 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1658 /* List should start with `space'. */
1659 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1660 plist
= XCDR (it
->object
);
1662 /* Compute the width of the stretch. */
1663 if (prop
= Fplist_get (plist
, QCwidth
),
1665 /* Absolute width `:width WIDTH' specified and valid. */
1666 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1667 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1670 /* Relative width `:relative-width FACTOR' specified and valid.
1671 Compute the width of the characters having the `glyph'
1674 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1677 if (it
->multibyte_p
)
1679 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1680 - IT_BYTEPOS (*it
));
1681 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1684 it2
.c
= *p
, it2
.len
= 1;
1686 it2
.glyph_row
= NULL
;
1687 it2
.what
= IT_CHARACTER
;
1688 x_produce_glyphs (&it2
);
1689 width
= NUMVAL (prop
) * it2
.pixel_width
;
1691 else if (prop
= Fplist_get (plist
, QCalign_to
),
1693 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1695 /* Nothing specified -> width defaults to canonical char width. */
1696 width
= CANON_X_UNIT (it
->f
);
1698 /* Compute height. */
1699 if (prop
= Fplist_get (plist
, QCheight
),
1701 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1702 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1704 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1706 height
= FONT_HEIGHT (font
);
1708 /* Compute percentage of height used for ascent. If
1709 `:ascent ASCENT' is present and valid, use that. Otherwise,
1710 derive the ascent from the font in use. */
1711 if (prop
= Fplist_get (plist
, QCascent
),
1712 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1713 ascent
= NUMVAL (prop
) / 100.0;
1715 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1724 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1725 if (!STRINGP (object
))
1726 object
= it
->w
->buffer
;
1727 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1730 it
->pixel_width
= width
;
1731 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1732 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1735 if (face
->box
!= FACE_NO_BOX
)
1737 if (face
->box_line_width
> 0)
1739 it
->ascent
+= face
->box_line_width
;
1740 it
->descent
+= face
->box_line_width
;
1743 if (it
->start_of_box_run_p
)
1744 it
->pixel_width
+= abs (face
->box_line_width
);
1745 if (it
->end_of_box_run_p
)
1746 it
->pixel_width
+= abs (face
->box_line_width
);
1749 take_vertical_position_into_account (it
);
1752 /* Return proper value to be used as baseline offset of font that has
1753 ASCENT and DESCENT to draw characters by the font at the vertical
1754 center of the line of frame F.
1756 Here, out task is to find the value of BOFF in the following figure;
1758 -------------------------+-----------+-
1759 -+-+---------+-+ | |
1761 | | | | F_ASCENT F_HEIGHT
1764 | | |-|-+------+-----------|------- baseline
1766 | |---------|-+-+ | |
1768 -+-+---------+-+ F_DESCENT |
1769 -------------------------+-----------+-
1771 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1772 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1773 DESCENT = FONT->descent
1774 HEIGHT = FONT_HEIGHT (FONT)
1775 F_DESCENT = (F->output_data.x->font->descent
1776 - F->output_data.x->baseline_offset)
1777 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1780 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1782 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1783 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1784 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1786 /* Produce glyphs/get display metrics for the display element IT is
1787 loaded with. See the description of struct display_iterator in
1788 dispextern.h for an overview of struct display_iterator. */
1791 x_produce_glyphs (it
)
1794 it
->glyph_not_available_p
= 0;
1796 if (it
->what
== IT_CHARACTER
)
1800 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1802 int font_not_found_p
;
1803 struct font_info
*font_info
;
1804 int boff
; /* baseline offset */
1805 /* We may change it->multibyte_p upon unibyte<->multibyte
1806 conversion. So, save the current value now and restore it
1809 Note: It seems that we don't have to record multibyte_p in
1810 struct glyph because the character code itself tells if or
1811 not the character is multibyte. Thus, in the future, we must
1812 consider eliminating the field `multibyte_p' in the struct
1815 int saved_multibyte_p
= it
->multibyte_p
;
1817 /* Maybe translate single-byte characters to multibyte, or the
1819 it
->char_to_display
= it
->c
;
1820 if (!ASCII_BYTE_P (it
->c
))
1822 if (unibyte_display_via_language_environment
1823 && SINGLE_BYTE_CHAR_P (it
->c
)
1825 || !NILP (Vnonascii_translation_table
)))
1827 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1828 it
->multibyte_p
= 1;
1829 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1830 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1832 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1833 && !it
->multibyte_p
)
1835 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1836 it
->multibyte_p
= 0;
1837 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1838 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1842 /* Get font to use. Encode IT->char_to_display. */
1843 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1844 it
->face_id
, &char2b
,
1848 /* When no suitable font found, use the default font. */
1849 font_not_found_p
= font
== NULL
;
1850 if (font_not_found_p
)
1852 font
= FRAME_FONT (it
->f
);
1853 boff
= it
->f
->output_data
.x
->baseline_offset
;
1858 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1859 boff
= font_info
->baseline_offset
;
1860 if (font_info
->vertical_centering
)
1861 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1864 if (it
->char_to_display
>= ' '
1865 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1867 /* Either unibyte or ASCII. */
1872 pcm
= x_per_char_metric (font
, &char2b
);
1873 it
->ascent
= font
->ascent
+ boff
;
1874 it
->descent
= font
->descent
- boff
;
1878 it
->phys_ascent
= pcm
->ascent
+ boff
;
1879 it
->phys_descent
= pcm
->descent
- boff
;
1880 it
->pixel_width
= pcm
->width
;
1884 it
->glyph_not_available_p
= 1;
1885 it
->phys_ascent
= font
->ascent
+ boff
;
1886 it
->phys_descent
= font
->descent
- boff
;
1887 it
->pixel_width
= FONT_WIDTH (font
);
1890 /* If this is a space inside a region of text with
1891 `space-width' property, change its width. */
1892 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1894 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1896 /* If face has a box, add the box thickness to the character
1897 height. If character has a box line to the left and/or
1898 right, add the box line width to the character's width. */
1899 if (face
->box
!= FACE_NO_BOX
)
1901 int thick
= face
->box_line_width
;
1905 it
->ascent
+= thick
;
1906 it
->descent
+= thick
;
1911 if (it
->start_of_box_run_p
)
1912 it
->pixel_width
+= thick
;
1913 if (it
->end_of_box_run_p
)
1914 it
->pixel_width
+= thick
;
1917 /* If face has an overline, add the height of the overline
1918 (1 pixel) and a 1 pixel margin to the character height. */
1919 if (face
->overline_p
)
1922 take_vertical_position_into_account (it
);
1924 /* If we have to actually produce glyphs, do it. */
1929 /* Translate a space with a `space-width' property
1930 into a stretch glyph. */
1931 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1932 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1933 it
->ascent
+ it
->descent
, ascent
);
1936 x_append_glyph (it
);
1938 /* If characters with lbearing or rbearing are displayed
1939 in this line, record that fact in a flag of the
1940 glyph row. This is used to optimize X output code. */
1941 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1942 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1945 else if (it
->char_to_display
== '\n')
1947 /* A newline has no width but we need the height of the line. */
1948 it
->pixel_width
= 0;
1950 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1951 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1953 if (face
->box
!= FACE_NO_BOX
1954 && face
->box_line_width
> 0)
1956 it
->ascent
+= face
->box_line_width
;
1957 it
->descent
+= face
->box_line_width
;
1960 else if (it
->char_to_display
== '\t')
1962 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1963 int x
= it
->current_x
+ it
->continuation_lines_width
;
1964 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1966 /* If the distance from the current position to the next tab
1967 stop is less than a canonical character width, use the
1968 tab stop after that. */
1969 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1970 next_tab_x
+= tab_width
;
1972 it
->pixel_width
= next_tab_x
- x
;
1974 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1975 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1979 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1980 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1981 it
->ascent
+ it
->descent
, ascent
);
1986 /* A multi-byte character. Assume that the display width of the
1987 character is the width of the character multiplied by the
1988 width of the font. */
1990 /* If we found a font, this font should give us the right
1991 metrics. If we didn't find a font, use the frame's
1992 default font and calculate the width of the character
1993 from the charset width; this is what old redisplay code
1995 pcm
= x_per_char_metric (font
, &char2b
);
1996 if (font_not_found_p
|| !pcm
)
1998 int charset
= CHAR_CHARSET (it
->char_to_display
);
2000 it
->glyph_not_available_p
= 1;
2001 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2002 * CHARSET_WIDTH (charset
));
2003 it
->phys_ascent
= font
->ascent
+ boff
;
2004 it
->phys_descent
= font
->descent
- boff
;
2008 it
->pixel_width
= pcm
->width
;
2009 it
->phys_ascent
= pcm
->ascent
+ boff
;
2010 it
->phys_descent
= pcm
->descent
- boff
;
2012 && (pcm
->lbearing
< 0
2013 || pcm
->rbearing
> pcm
->width
))
2014 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2017 it
->ascent
= font
->ascent
+ boff
;
2018 it
->descent
= font
->descent
- boff
;
2019 if (face
->box
!= FACE_NO_BOX
)
2021 int thick
= face
->box_line_width
;
2025 it
->ascent
+= thick
;
2026 it
->descent
+= thick
;
2031 if (it
->start_of_box_run_p
)
2032 it
->pixel_width
+= thick
;
2033 if (it
->end_of_box_run_p
)
2034 it
->pixel_width
+= thick
;
2037 /* If face has an overline, add the height of the overline
2038 (1 pixel) and a 1 pixel margin to the character height. */
2039 if (face
->overline_p
)
2042 take_vertical_position_into_account (it
);
2045 x_append_glyph (it
);
2047 it
->multibyte_p
= saved_multibyte_p
;
2049 else if (it
->what
== IT_COMPOSITION
)
2051 /* Note: A composition is represented as one glyph in the
2052 glyph matrix. There are no padding glyphs. */
2055 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2057 int font_not_found_p
;
2058 struct font_info
*font_info
;
2059 int boff
; /* baseline offset */
2060 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2062 /* Maybe translate single-byte characters to multibyte. */
2063 it
->char_to_display
= it
->c
;
2064 if (unibyte_display_via_language_environment
2065 && SINGLE_BYTE_CHAR_P (it
->c
)
2068 && !NILP (Vnonascii_translation_table
))))
2070 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2073 /* Get face and font to use. Encode IT->char_to_display. */
2074 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2075 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2076 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2077 it
->face_id
, &char2b
, it
->multibyte_p
);
2080 /* When no suitable font found, use the default font. */
2081 font_not_found_p
= font
== NULL
;
2082 if (font_not_found_p
)
2084 font
= FRAME_FONT (it
->f
);
2085 boff
= it
->f
->output_data
.x
->baseline_offset
;
2090 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2091 boff
= font_info
->baseline_offset
;
2092 if (font_info
->vertical_centering
)
2093 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2096 /* There are no padding glyphs, so there is only one glyph to
2097 produce for the composition. Important is that pixel_width,
2098 ascent and descent are the values of what is drawn by
2099 draw_glyphs (i.e. the values of the overall glyphs composed). */
2102 /* If we have not yet calculated pixel size data of glyphs of
2103 the composition for the current face font, calculate them
2104 now. Theoretically, we have to check all fonts for the
2105 glyphs, but that requires much time and memory space. So,
2106 here we check only the font of the first glyph. This leads
2107 to incorrect display very rarely, and C-l (recenter) can
2108 correct the display anyway. */
2109 if (cmp
->font
!= (void *) font
)
2111 /* Ascent and descent of the font of the first character of
2112 this composition (adjusted by baseline offset). Ascent
2113 and descent of overall glyphs should not be less than
2114 them respectively. */
2115 int font_ascent
= font
->ascent
+ boff
;
2116 int font_descent
= font
->descent
- boff
;
2117 /* Bounding box of the overall glyphs. */
2118 int leftmost
, rightmost
, lowest
, highest
;
2119 int i
, width
, ascent
, descent
;
2121 cmp
->font
= (void *) font
;
2123 /* Initialize the bounding box. */
2125 && (pcm
= x_per_char_metric (font
, &char2b
)))
2128 ascent
= pcm
->ascent
;
2129 descent
= pcm
->descent
;
2133 width
= FONT_WIDTH (font
);
2134 ascent
= font
->ascent
;
2135 descent
= font
->descent
;
2139 lowest
= - descent
+ boff
;
2140 highest
= ascent
+ boff
;
2144 && font_info
->default_ascent
2145 && CHAR_TABLE_P (Vuse_default_ascent
)
2146 && !NILP (Faref (Vuse_default_ascent
,
2147 make_number (it
->char_to_display
))))
2148 highest
= font_info
->default_ascent
+ boff
;
2150 /* Draw the first glyph at the normal position. It may be
2151 shifted to right later if some other glyphs are drawn at
2153 cmp
->offsets
[0] = 0;
2154 cmp
->offsets
[1] = boff
;
2156 /* Set cmp->offsets for the remaining glyphs. */
2157 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2159 int left
, right
, btm
, top
;
2160 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2161 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2163 face
= FACE_FROM_ID (it
->f
, face_id
);
2164 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2169 font
= FRAME_FONT (it
->f
);
2170 boff
= it
->f
->output_data
.x
->baseline_offset
;
2176 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2177 boff
= font_info
->baseline_offset
;
2178 if (font_info
->vertical_centering
)
2179 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2183 && (pcm
= x_per_char_metric (font
, &char2b
)))
2186 ascent
= pcm
->ascent
;
2187 descent
= pcm
->descent
;
2191 width
= FONT_WIDTH (font
);
2196 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2198 /* Relative composition with or without
2200 left
= (leftmost
+ rightmost
- width
) / 2;
2201 btm
= - descent
+ boff
;
2202 if (font_info
&& font_info
->relative_compose
2203 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2204 || NILP (Faref (Vignore_relative_composition
,
2205 make_number (ch
)))))
2208 if (- descent
>= font_info
->relative_compose
)
2209 /* One extra pixel between two glyphs. */
2211 else if (ascent
<= 0)
2212 /* One extra pixel between two glyphs. */
2213 btm
= lowest
- 1 - ascent
- descent
;
2218 /* A composition rule is specified by an integer
2219 value that encodes global and new reference
2220 points (GREF and NREF). GREF and NREF are
2221 specified by numbers as below:
2229 ---3---4---5--- baseline
2231 6---7---8 -- descent
2233 int rule
= COMPOSITION_RULE (cmp
, i
);
2234 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2236 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2237 grefx
= gref
% 3, nrefx
= nref
% 3;
2238 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2241 + grefx
* (rightmost
- leftmost
) / 2
2242 - nrefx
* width
/ 2);
2243 btm
= ((grefy
== 0 ? highest
2245 : grefy
== 2 ? lowest
2246 : (highest
+ lowest
) / 2)
2247 - (nrefy
== 0 ? ascent
+ descent
2248 : nrefy
== 1 ? descent
- boff
2250 : (ascent
+ descent
) / 2));
2253 cmp
->offsets
[i
* 2] = left
;
2254 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2256 /* Update the bounding box of the overall glyphs. */
2257 right
= left
+ width
;
2258 top
= btm
+ descent
+ ascent
;
2259 if (left
< leftmost
)
2261 if (right
> rightmost
)
2269 /* If there are glyphs whose x-offsets are negative,
2270 shift all glyphs to the right and make all x-offsets
2274 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2275 cmp
->offsets
[i
* 2] -= leftmost
;
2276 rightmost
-= leftmost
;
2279 cmp
->pixel_width
= rightmost
;
2280 cmp
->ascent
= highest
;
2281 cmp
->descent
= - lowest
;
2282 if (cmp
->ascent
< font_ascent
)
2283 cmp
->ascent
= font_ascent
;
2284 if (cmp
->descent
< font_descent
)
2285 cmp
->descent
= font_descent
;
2288 it
->pixel_width
= cmp
->pixel_width
;
2289 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2290 it
->descent
= it
->phys_descent
= cmp
->descent
;
2292 if (face
->box
!= FACE_NO_BOX
)
2294 int thick
= face
->box_line_width
;
2298 it
->ascent
+= thick
;
2299 it
->descent
+= thick
;
2304 if (it
->start_of_box_run_p
)
2305 it
->pixel_width
+= thick
;
2306 if (it
->end_of_box_run_p
)
2307 it
->pixel_width
+= thick
;
2310 /* If face has an overline, add the height of the overline
2311 (1 pixel) and a 1 pixel margin to the character height. */
2312 if (face
->overline_p
)
2315 take_vertical_position_into_account (it
);
2318 x_append_composite_glyph (it
);
2320 else if (it
->what
== IT_IMAGE
)
2321 x_produce_image_glyph (it
);
2322 else if (it
->what
== IT_STRETCH
)
2323 x_produce_stretch_glyph (it
);
2325 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2326 because this isn't true for images with `:ascent 100'. */
2327 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2328 if (it
->area
== TEXT_AREA
)
2329 it
->current_x
+= it
->pixel_width
;
2331 it
->descent
+= it
->extra_line_spacing
;
2333 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2334 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2335 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2336 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2340 /* Estimate the pixel height of the mode or top line on frame F.
2341 FACE_ID specifies what line's height to estimate. */
2344 x_estimate_mode_line_height (f
, face_id
)
2346 enum face_id face_id
;
2348 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2350 /* This function is called so early when Emacs starts that the face
2351 cache and mode line face are not yet initialized. */
2352 if (FRAME_FACE_CACHE (f
))
2354 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2358 height
= FONT_HEIGHT (face
->font
);
2359 if (face
->box_line_width
> 0)
2360 height
+= 2 * face
->box_line_width
;
2368 /***********************************************************************
2370 ***********************************************************************/
2372 /* A sequence of glyphs to be drawn in the same face.
2374 This data structure is not really completely X specific, so it
2375 could possibly, at least partially, be useful for other systems. It
2376 is currently not part of the external redisplay interface because
2377 it's not clear what other systems will need. */
2381 /* X-origin of the string. */
2384 /* Y-origin and y-position of the base line of this string. */
2387 /* The width of the string, not including a face extension. */
2390 /* The width of the string, including a face extension. */
2391 int background_width
;
2393 /* The height of this string. This is the height of the line this
2394 string is drawn in, and can be different from the height of the
2395 font the string is drawn in. */
2398 /* Number of pixels this string overwrites in front of its x-origin.
2399 This number is zero if the string has an lbearing >= 0; it is
2400 -lbearing, if the string has an lbearing < 0. */
2403 /* Number of pixels this string overwrites past its right-most
2404 nominal x-position, i.e. x + width. Zero if the string's
2405 rbearing is <= its nominal width, rbearing - width otherwise. */
2408 /* The frame on which the glyph string is drawn. */
2411 /* The window on which the glyph string is drawn. */
2414 /* X display and window for convenience. */
2418 /* The glyph row for which this string was built. It determines the
2419 y-origin and height of the string. */
2420 struct glyph_row
*row
;
2422 /* The area within row. */
2423 enum glyph_row_area area
;
2425 /* Characters to be drawn, and number of characters. */
2429 /* A face-override for drawing cursors, mouse face and similar. */
2430 enum draw_glyphs_face hl
;
2432 /* Face in which this string is to be drawn. */
2435 /* Font in which this string is to be drawn. */
2438 /* Font info for this string. */
2439 struct font_info
*font_info
;
2441 /* Non-null means this string describes (part of) a composition.
2442 All characters from char2b are drawn composed. */
2443 struct composition
*cmp
;
2445 /* Index of this glyph string's first character in the glyph
2446 definition of CMP. If this is zero, this glyph string describes
2447 the first character of a composition. */
2450 /* 1 means this glyph strings face has to be drawn to the right end
2451 of the window's drawing area. */
2452 unsigned extends_to_end_of_line_p
: 1;
2454 /* 1 means the background of this string has been drawn. */
2455 unsigned background_filled_p
: 1;
2457 /* 1 means glyph string must be drawn with 16-bit functions. */
2458 unsigned two_byte_p
: 1;
2460 /* 1 means that the original font determined for drawing this glyph
2461 string could not be loaded. The member `font' has been set to
2462 the frame's default font in this case. */
2463 unsigned font_not_found_p
: 1;
2465 /* 1 means that the face in which this glyph string is drawn has a
2467 unsigned stippled_p
: 1;
2469 /* 1 means only the foreground of this glyph string must be drawn,
2470 and we should use the physical height of the line this glyph
2471 string appears in as clip rect. */
2472 unsigned for_overlaps_p
: 1;
2474 /* The GC to use for drawing this glyph string. */
2477 /* A pointer to the first glyph in the string. This glyph
2478 corresponds to char2b[0]. Needed to draw rectangles if
2479 font_not_found_p is 1. */
2480 struct glyph
*first_glyph
;
2482 /* Image, if any. */
2485 struct glyph_string
*next
, *prev
;
2492 x_dump_glyph_string (s
)
2493 struct glyph_string
*s
;
2495 fprintf (stderr
, "glyph string\n");
2496 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2497 s
->x
, s
->y
, s
->width
, s
->height
);
2498 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2499 fprintf (stderr
, " hl = %d\n", s
->hl
);
2500 fprintf (stderr
, " left overhang = %d, right = %d\n",
2501 s
->left_overhang
, s
->right_overhang
);
2502 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2503 fprintf (stderr
, " extends to end of line = %d\n",
2504 s
->extends_to_end_of_line_p
);
2505 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2506 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2509 #endif /* GLYPH_DEBUG */
2513 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2514 struct glyph_string
**,
2515 struct glyph_string
*,
2516 struct glyph_string
*));
2517 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2518 struct glyph_string
**,
2519 struct glyph_string
*,
2520 struct glyph_string
*));
2521 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2522 struct glyph_string
**,
2523 struct glyph_string
*));
2524 static int x_left_overwritten
P_ ((struct glyph_string
*));
2525 static int x_left_overwriting
P_ ((struct glyph_string
*));
2526 static int x_right_overwritten
P_ ((struct glyph_string
*));
2527 static int x_right_overwriting
P_ ((struct glyph_string
*));
2528 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2530 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2531 XChar2b
*, struct window
*,
2533 enum glyph_row_area
, int,
2534 enum draw_glyphs_face
));
2535 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2536 enum glyph_row_area
, int, int,
2537 enum draw_glyphs_face
, int *, int *, int));
2538 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2539 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2540 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2542 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2543 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2544 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2545 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2546 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2547 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2548 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2549 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2550 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2552 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2553 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2554 unsigned long *, double, int));
2555 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2556 double, int, unsigned long));
2557 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2558 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2559 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2560 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2561 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2562 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2563 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2565 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2566 int, int, int, int, XRectangle
*));
2567 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2568 int, int, int, XRectangle
*));
2569 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2570 enum glyph_row_area
));
2571 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2573 enum glyph_row_area
, int, int));
2576 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2580 /* Append the list of glyph strings with head H and tail T to the list
2581 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2584 x_append_glyph_string_lists (head
, tail
, h
, t
)
2585 struct glyph_string
**head
, **tail
;
2586 struct glyph_string
*h
, *t
;
2600 /* Prepend the list of glyph strings with head H and tail T to the
2601 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2605 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2606 struct glyph_string
**head
, **tail
;
2607 struct glyph_string
*h
, *t
;
2621 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2622 Set *HEAD and *TAIL to the resulting list. */
2625 x_append_glyph_string (head
, tail
, s
)
2626 struct glyph_string
**head
, **tail
;
2627 struct glyph_string
*s
;
2629 s
->next
= s
->prev
= NULL
;
2630 x_append_glyph_string_lists (head
, tail
, s
, s
);
2634 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2639 struct glyph_string
*s
;
2641 if (s
->font
== FRAME_FONT (s
->f
)
2642 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2643 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2645 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2648 /* Cursor on non-default face: must merge. */
2652 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2653 xgcv
.foreground
= s
->face
->background
;
2655 /* If the glyph would be invisible, try a different foreground. */
2656 if (xgcv
.foreground
== xgcv
.background
)
2657 xgcv
.foreground
= s
->face
->foreground
;
2658 if (xgcv
.foreground
== xgcv
.background
)
2659 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2660 if (xgcv
.foreground
== xgcv
.background
)
2661 xgcv
.foreground
= s
->face
->foreground
;
2663 /* Make sure the cursor is distinct from text in this face. */
2664 if (xgcv
.background
== s
->face
->background
2665 && xgcv
.foreground
== s
->face
->foreground
)
2667 xgcv
.background
= s
->face
->foreground
;
2668 xgcv
.foreground
= s
->face
->background
;
2671 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2672 xgcv
.font
= s
->font
->fid
;
2673 xgcv
.graphics_exposures
= False
;
2674 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2676 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2677 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2680 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2681 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2683 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2688 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2691 x_set_mouse_face_gc (s
)
2692 struct glyph_string
*s
;
2697 /* What face has to be used last for the mouse face? */
2698 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2699 face
= FACE_FROM_ID (s
->f
, face_id
);
2701 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2703 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2704 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2706 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2707 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2708 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2710 /* If font in this face is same as S->font, use it. */
2711 if (s
->font
== s
->face
->font
)
2712 s
->gc
= s
->face
->gc
;
2715 /* Otherwise construct scratch_cursor_gc with values from FACE
2720 xgcv
.background
= s
->face
->background
;
2721 xgcv
.foreground
= s
->face
->foreground
;
2722 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2723 xgcv
.font
= s
->font
->fid
;
2724 xgcv
.graphics_exposures
= False
;
2725 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2727 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2728 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2731 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2732 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2734 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2737 xassert (s
->gc
!= 0);
2741 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2742 Faces to use in the mode line have already been computed when the
2743 matrix was built, so there isn't much to do, here. */
2746 x_set_mode_line_face_gc (s
)
2747 struct glyph_string
*s
;
2749 s
->gc
= s
->face
->gc
;
2753 /* Set S->gc of glyph string S for drawing that glyph string. Set
2754 S->stippled_p to a non-zero value if the face of S has a stipple
2758 x_set_glyph_string_gc (s
)
2759 struct glyph_string
*s
;
2761 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2763 if (s
->hl
== DRAW_NORMAL_TEXT
)
2765 s
->gc
= s
->face
->gc
;
2766 s
->stippled_p
= s
->face
->stipple
!= 0;
2768 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2770 x_set_mode_line_face_gc (s
);
2771 s
->stippled_p
= s
->face
->stipple
!= 0;
2773 else if (s
->hl
== DRAW_CURSOR
)
2775 x_set_cursor_gc (s
);
2778 else if (s
->hl
== DRAW_MOUSE_FACE
)
2780 x_set_mouse_face_gc (s
);
2781 s
->stippled_p
= s
->face
->stipple
!= 0;
2783 else if (s
->hl
== DRAW_IMAGE_RAISED
2784 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2786 s
->gc
= s
->face
->gc
;
2787 s
->stippled_p
= s
->face
->stipple
!= 0;
2791 s
->gc
= s
->face
->gc
;
2792 s
->stippled_p
= s
->face
->stipple
!= 0;
2795 /* GC must have been set. */
2796 xassert (s
->gc
!= 0);
2800 /* Return in *R the clipping rectangle for glyph string S. */
2803 x_get_glyph_string_clip_rect (s
, r
)
2804 struct glyph_string
*s
;
2807 if (s
->row
->full_width_p
)
2809 /* Draw full-width. X coordinates are relative to S->w->left. */
2810 int canon_x
= CANON_X_UNIT (s
->f
);
2812 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2813 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2815 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2817 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2818 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2822 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2824 /* Unless displaying a mode or menu bar line, which are always
2825 fully visible, clip to the visible part of the row. */
2826 if (s
->w
->pseudo_window_p
)
2827 r
->height
= s
->row
->visible_height
;
2829 r
->height
= s
->height
;
2833 /* This is a text line that may be partially visible. */
2834 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2835 r
->width
= window_box_width (s
->w
, s
->area
);
2836 r
->height
= s
->row
->visible_height
;
2839 /* Don't use S->y for clipping because it doesn't take partially
2840 visible lines into account. For example, it can be negative for
2841 partially visible lines at the top of a window. */
2842 if (!s
->row
->full_width_p
2843 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2844 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2846 r
->y
= max (0, s
->row
->y
);
2848 /* If drawing a tool-bar window, draw it over the internal border
2849 at the top of the window. */
2850 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2851 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2853 /* If S draws overlapping rows, it's sufficient to use the top and
2854 bottom of the window for clipping because this glyph string
2855 intentionally draws over other lines. */
2856 if (s
->for_overlaps_p
)
2858 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2859 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2862 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2866 /* Set clipping for output of glyph string S. S may be part of a mode
2867 line or menu if we don't have X toolkit support. */
2870 x_set_glyph_string_clipping (s
)
2871 struct glyph_string
*s
;
2874 x_get_glyph_string_clip_rect (s
, &r
);
2875 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2879 /* Compute left and right overhang of glyph string S. If S is a glyph
2880 string for a composition, assume overhangs don't exist. */
2883 x_compute_glyph_string_overhangs (s
)
2884 struct glyph_string
*s
;
2887 && s
->first_glyph
->type
== CHAR_GLYPH
)
2890 int direction
, font_ascent
, font_descent
;
2891 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2892 &font_ascent
, &font_descent
, &cs
);
2893 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2894 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2899 /* Compute overhangs and x-positions for glyph string S and its
2900 predecessors, or successors. X is the starting x-position for S.
2901 BACKWARD_P non-zero means process predecessors. */
2904 x_compute_overhangs_and_x (s
, x
, backward_p
)
2905 struct glyph_string
*s
;
2913 x_compute_glyph_string_overhangs (s
);
2923 x_compute_glyph_string_overhangs (s
);
2932 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2933 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2934 assumed to be zero. */
2937 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2938 struct glyph
*glyph
;
2944 if (glyph
->type
== CHAR_GLYPH
)
2948 struct font_info
*font_info
;
2952 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2954 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2956 && (pcm
= x_per_char_metric (font
, &char2b
)))
2958 if (pcm
->rbearing
> pcm
->width
)
2959 *right
= pcm
->rbearing
- pcm
->width
;
2960 if (pcm
->lbearing
< 0)
2961 *left
= -pcm
->lbearing
;
2967 /* Return the index of the first glyph preceding glyph string S that
2968 is overwritten by S because of S's left overhang. Value is -1
2969 if no glyphs are overwritten. */
2972 x_left_overwritten (s
)
2973 struct glyph_string
*s
;
2977 if (s
->left_overhang
)
2980 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2981 int first
= s
->first_glyph
- glyphs
;
2983 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2984 x
-= glyphs
[i
].pixel_width
;
2995 /* Return the index of the first glyph preceding glyph string S that
2996 is overwriting S because of its right overhang. Value is -1 if no
2997 glyph in front of S overwrites S. */
3000 x_left_overwriting (s
)
3001 struct glyph_string
*s
;
3004 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3005 int first
= s
->first_glyph
- glyphs
;
3009 for (i
= first
- 1; i
>= 0; --i
)
3012 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3015 x
-= glyphs
[i
].pixel_width
;
3022 /* Return the index of the last glyph following glyph string S that is
3023 not overwritten by S because of S's right overhang. Value is -1 if
3024 no such glyph is found. */
3027 x_right_overwritten (s
)
3028 struct glyph_string
*s
;
3032 if (s
->right_overhang
)
3035 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3036 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3037 int end
= s
->row
->used
[s
->area
];
3039 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3040 x
+= glyphs
[i
].pixel_width
;
3049 /* Return the index of the last glyph following glyph string S that
3050 overwrites S because of its left overhang. Value is negative
3051 if no such glyph is found. */
3054 x_right_overwriting (s
)
3055 struct glyph_string
*s
;
3058 int end
= s
->row
->used
[s
->area
];
3059 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3060 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3064 for (i
= first
; i
< end
; ++i
)
3067 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3070 x
+= glyphs
[i
].pixel_width
;
3077 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3080 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3081 struct glyph_string
*s
;
3085 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3086 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3087 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3088 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3092 /* Draw the background of glyph_string S. If S->background_filled_p
3093 is non-zero don't draw it. FORCE_P non-zero means draw the
3094 background even if it wouldn't be drawn normally. This is used
3095 when a string preceding S draws into the background of S, or S
3096 contains the first component of a composition. */
3099 x_draw_glyph_string_background (s
, force_p
)
3100 struct glyph_string
*s
;
3103 /* Nothing to do if background has already been drawn or if it
3104 shouldn't be drawn in the first place. */
3105 if (!s
->background_filled_p
)
3107 int box_line_width
= max (s
->face
->box_line_width
, 0);
3111 /* Fill background with a stipple pattern. */
3112 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3113 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3114 s
->y
+ box_line_width
,
3115 s
->background_width
,
3116 s
->height
- 2 * box_line_width
);
3117 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3118 s
->background_filled_p
= 1;
3120 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3121 || s
->font_not_found_p
3122 || s
->extends_to_end_of_line_p
3125 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3126 s
->background_width
,
3127 s
->height
- 2 * box_line_width
);
3128 s
->background_filled_p
= 1;
3134 /* Draw the foreground of glyph string S. */
3137 x_draw_glyph_string_foreground (s
)
3138 struct glyph_string
*s
;
3142 /* If first glyph of S has a left box line, start drawing the text
3143 of S to the right of that box line. */
3144 if (s
->face
->box
!= FACE_NO_BOX
3145 && s
->first_glyph
->left_box_line_p
)
3146 x
= s
->x
+ abs (s
->face
->box_line_width
);
3150 /* Draw characters of S as rectangles if S's font could not be
3152 if (s
->font_not_found_p
)
3154 for (i
= 0; i
< s
->nchars
; ++i
)
3156 struct glyph
*g
= s
->first_glyph
+ i
;
3157 XDrawRectangle (s
->display
, s
->window
,
3158 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3160 x
+= g
->pixel_width
;
3165 char *char1b
= (char *) s
->char2b
;
3166 int boff
= s
->font_info
->baseline_offset
;
3168 if (s
->font_info
->vertical_centering
)
3169 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3171 /* If we can use 8-bit functions, condense S->char2b. */
3173 for (i
= 0; i
< s
->nchars
; ++i
)
3174 char1b
[i
] = s
->char2b
[i
].byte2
;
3176 /* Draw text with XDrawString if background has already been
3177 filled. Otherwise, use XDrawImageString. (Note that
3178 XDrawImageString is usually faster than XDrawString.) Always
3179 use XDrawImageString when drawing the cursor so that there is
3180 no chance that characters under a box cursor are invisible. */
3181 if (s
->for_overlaps_p
3182 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3184 /* Draw characters with 16-bit or 8-bit functions. */
3186 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3187 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3189 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3190 s
->ybase
- boff
, char1b
, s
->nchars
);
3195 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3196 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3198 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3199 s
->ybase
- boff
, char1b
, s
->nchars
);
3204 /* Draw the foreground of composite glyph string S. */
3207 x_draw_composite_glyph_string_foreground (s
)
3208 struct glyph_string
*s
;
3212 /* If first glyph of S has a left box line, start drawing the text
3213 of S to the right of that box line. */
3214 if (s
->face
->box
!= FACE_NO_BOX
3215 && s
->first_glyph
->left_box_line_p
)
3216 x
= s
->x
+ abs (s
->face
->box_line_width
);
3220 /* S is a glyph string for a composition. S->gidx is the index of
3221 the first character drawn for glyphs of this composition.
3222 S->gidx == 0 means we are drawing the very first character of
3223 this composition. */
3225 /* Draw a rectangle for the composition if the font for the very
3226 first character of the composition could not be loaded. */
3227 if (s
->font_not_found_p
)
3230 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3231 s
->width
- 1, s
->height
- 1);
3235 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3236 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3237 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3238 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3244 #ifdef USE_X_TOOLKIT
3246 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3249 /* Return the frame on which widget WIDGET is used.. Abort if frame
3250 cannot be determined. */
3252 static struct frame
*
3253 x_frame_of_widget (widget
)
3256 struct x_display_info
*dpyinfo
;
3260 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3262 /* Find the top-level shell of the widget. Note that this function
3263 can be called when the widget is not yet realized, so XtWindow
3264 (widget) == 0. That's the reason we can't simply use
3265 x_any_window_to_frame. */
3266 while (!XtIsTopLevelShell (widget
))
3267 widget
= XtParent (widget
);
3269 /* Look for a frame with that top-level widget. Allocate the color
3270 on that frame to get the right gamma correction value. */
3271 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3272 if (GC_FRAMEP (XCAR (tail
))
3273 && (f
= XFRAME (XCAR (tail
)),
3274 (f
->output_data
.nothing
!= 1
3275 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3276 && f
->output_data
.x
->widget
== widget
)
3283 /* Allocate the color COLOR->pixel on the screen and display of
3284 widget WIDGET in colormap CMAP. If an exact match cannot be
3285 allocated, try the nearest color available. Value is non-zero
3286 if successful. This is called from lwlib. */
3289 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3294 struct frame
*f
= x_frame_of_widget (widget
);
3295 return x_alloc_nearest_color (f
, cmap
, color
);
3299 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3300 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3301 If this produces the same color as PIXEL, try a color where all RGB
3302 values have DELTA added. Return the allocated color in *PIXEL.
3303 DISPLAY is the X display, CMAP is the colormap to operate on.
3304 Value is non-zero if successful. */
3307 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3311 unsigned long *pixel
;
3315 struct frame
*f
= x_frame_of_widget (widget
);
3316 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3320 #endif /* USE_X_TOOLKIT */
3323 /* Value is an array of XColor structures for the contents of the
3324 color map of frame F. Set *NCELLS to the size of the array.
3325 Note that this probably shouldn't be called for large color maps,
3326 say a 24-bit TrueColor map. */
3328 static const XColor
*
3329 x_color_cells (f
, ncells
)
3333 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3335 if (dpyinfo
->color_cells
== NULL
)
3337 Display
*display
= FRAME_X_DISPLAY (f
);
3338 Screen
*screen
= FRAME_X_SCREEN (f
);
3341 dpyinfo
->ncolor_cells
3342 = XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3343 dpyinfo
->color_cells
3344 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3345 * sizeof *dpyinfo
->color_cells
);
3347 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3348 dpyinfo
->color_cells
[i
].pixel
= i
;
3350 XQueryColors (display
, FRAME_X_COLORMAP (f
),
3351 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3354 *ncells
= dpyinfo
->ncolor_cells
;
3355 return dpyinfo
->color_cells
;
3359 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3360 colors in COLORS. Use cached information, if available. */
3363 x_query_colors (f
, colors
, ncolors
)
3368 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3370 if (dpyinfo
->color_cells
)
3373 for (i
= 0; i
< ncolors
; ++i
)
3375 unsigned long pixel
= colors
[i
].pixel
;
3376 xassert (pixel
< dpyinfo
->ncolor_cells
);
3377 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3378 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3382 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3386 /* On frame F, translate pixel color to RGB values for the color in
3387 COLOR. Use cached information, if available. */
3390 x_query_color (f
, color
)
3394 x_query_colors (f
, color
, 1);
3398 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3399 CMAP. If an exact match can't be allocated, try the nearest color
3400 available. Value is non-zero if successful. Set *COLOR to the
3404 x_alloc_nearest_color (f
, cmap
, color
)
3409 Display
*display
= FRAME_X_DISPLAY (f
);
3410 Screen
*screen
= FRAME_X_SCREEN (f
);
3413 gamma_correct (f
, color
);
3414 rc
= XAllocColor (display
, cmap
, color
);
3417 /* If we got to this point, the colormap is full, so we're going
3418 to try to get the next closest color. The algorithm used is
3419 a least-squares matching, which is what X uses for closest
3420 color matching with StaticColor visuals. */
3422 unsigned long nearest_delta
= ~0;
3424 const XColor
*cells
= x_color_cells (f
, &ncells
);
3426 for (nearest
= i
= 0; i
< ncells
; ++i
)
3428 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3429 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3430 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3431 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3433 if (delta
< nearest_delta
)
3436 nearest_delta
= delta
;
3440 color
->red
= cells
[nearest
].red
;
3441 color
->green
= cells
[nearest
].green
;
3442 color
->blue
= cells
[nearest
].blue
;
3443 rc
= XAllocColor (display
, cmap
, color
);
3447 /* If allocation succeeded, and the allocated pixel color is not
3448 equal to a cached pixel color recorded earlier, there was a
3449 change in the colormap, so clear the color cache. */
3450 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3451 XColor
*cached_color
;
3453 if (dpyinfo
->color_cells
3454 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3455 (cached_color
->red
!= color
->red
3456 || cached_color
->blue
!= color
->blue
3457 || cached_color
->green
!= color
->green
)))
3459 xfree (dpyinfo
->color_cells
);
3460 dpyinfo
->color_cells
= NULL
;
3461 dpyinfo
->ncolor_cells
= 0;
3465 #ifdef DEBUG_X_COLORS
3467 register_color (color
->pixel
);
3468 #endif /* DEBUG_X_COLORS */
3474 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3475 It's necessary to do this instead of just using PIXEL directly to
3476 get color reference counts right. */
3479 x_copy_color (f
, pixel
)
3481 unsigned long pixel
;
3485 color
.pixel
= pixel
;
3487 x_query_color (f
, &color
);
3488 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3490 #ifdef DEBUG_X_COLORS
3491 register_color (pixel
);
3497 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3498 It's necessary to do this instead of just using PIXEL directly to
3499 get color reference counts right. */
3502 x_copy_dpy_color (dpy
, cmap
, pixel
)
3505 unsigned long pixel
;
3509 color
.pixel
= pixel
;
3511 XQueryColor (dpy
, cmap
, &color
);
3512 XAllocColor (dpy
, cmap
, &color
);
3514 #ifdef DEBUG_X_COLORS
3515 register_color (pixel
);
3521 /* Brightness beyond which a color won't have its highlight brightness
3524 Nominally, highlight colors for `3d' faces are calculated by
3525 brightening an object's color by a constant scale factor, but this
3526 doesn't yield good results for dark colors, so for colors who's
3527 brightness is less than this value (on a scale of 0-65535) have an
3528 use an additional additive factor.
3530 The value here is set so that the default menu-bar/mode-line color
3531 (grey75) will not have its highlights changed at all. */
3532 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
3535 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3536 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3537 If this produces the same color as PIXEL, try a color where all RGB
3538 values have DELTA added. Return the allocated color in *PIXEL.
3539 DISPLAY is the X display, CMAP is the colormap to operate on.
3540 Value is non-zero if successful. */
3543 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3547 unsigned long *pixel
;
3555 /* Get RGB color values. */
3556 color
.pixel
= *pixel
;
3557 x_query_color (f
, &color
);
3559 /* Change RGB values by specified FACTOR. Avoid overflow! */
3560 xassert (factor
>= 0);
3561 new.red
= min (0xffff, factor
* color
.red
);
3562 new.green
= min (0xffff, factor
* color
.green
);
3563 new.blue
= min (0xffff, factor
* color
.blue
);
3565 /* Calculate brightness of COLOR. */
3566 bright
= (2 * color
.red
+ 3 * color
.green
+ color
.blue
) / 6;
3568 /* We only boost colors that are darker than
3569 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3570 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3571 /* Make an additive adjustment to NEW, because it's dark enough so
3572 that scaling by FACTOR alone isn't enough. */
3574 /* How far below the limit this color is (0 - 1, 1 being darker). */
3575 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3576 /* The additive adjustment. */
3577 int min_delta
= delta
* dimness
* factor
/ 2;
3581 new.red
= max (0, new.red
- min_delta
);
3582 new.green
= max (0, new.green
- min_delta
);
3583 new.blue
= max (0, new.blue
- min_delta
);
3587 new.red
= min (0xffff, min_delta
+ new.red
);
3588 new.green
= min (0xffff, min_delta
+ new.green
);
3589 new.blue
= min (0xffff, min_delta
+ new.blue
);
3593 /* Try to allocate the color. */
3594 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3597 if (new.pixel
== *pixel
)
3599 /* If we end up with the same color as before, try adding
3600 delta to the RGB values. */
3601 x_free_colors (f
, &new.pixel
, 1);
3603 new.red
= min (0xffff, delta
+ color
.red
);
3604 new.green
= min (0xffff, delta
+ color
.green
);
3605 new.blue
= min (0xffff, delta
+ color
.blue
);
3606 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3617 /* Set up the foreground color for drawing relief lines of glyph
3618 string S. RELIEF is a pointer to a struct relief containing the GC
3619 with which lines will be drawn. Use a color that is FACTOR or
3620 DELTA lighter or darker than the relief's background which is found
3621 in S->f->output_data.x->relief_background. If such a color cannot
3622 be allocated, use DEFAULT_PIXEL, instead. */
3625 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3627 struct relief
*relief
;
3630 unsigned long default_pixel
;
3633 struct x_output
*di
= f
->output_data
.x
;
3634 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3635 unsigned long pixel
;
3636 unsigned long background
= di
->relief_background
;
3637 Colormap cmap
= FRAME_X_COLORMAP (f
);
3638 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3639 Display
*dpy
= FRAME_X_DISPLAY (f
);
3641 xgcv
.graphics_exposures
= False
;
3642 xgcv
.line_width
= 1;
3644 /* Free previously allocated color. The color cell will be reused
3645 when it has been freed as many times as it was allocated, so this
3646 doesn't affect faces using the same colors. */
3648 && relief
->allocated_p
)
3650 x_free_colors (f
, &relief
->pixel
, 1);
3651 relief
->allocated_p
= 0;
3654 /* Allocate new color. */
3655 xgcv
.foreground
= default_pixel
;
3657 if (dpyinfo
->n_planes
!= 1
3658 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3660 relief
->allocated_p
= 1;
3661 xgcv
.foreground
= relief
->pixel
= pixel
;
3664 if (relief
->gc
== 0)
3666 xgcv
.stipple
= dpyinfo
->gray
;
3668 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3671 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3675 /* Set up colors for the relief lines around glyph string S. */
3678 x_setup_relief_colors (s
)
3679 struct glyph_string
*s
;
3681 struct x_output
*di
= s
->f
->output_data
.x
;
3682 unsigned long color
;
3684 if (s
->face
->use_box_color_for_shadows_p
)
3685 color
= s
->face
->box_color
;
3690 /* Get the background color of the face. */
3691 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3692 color
= xgcv
.background
;
3695 if (di
->white_relief
.gc
== 0
3696 || color
!= di
->relief_background
)
3698 di
->relief_background
= color
;
3699 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3700 WHITE_PIX_DEFAULT (s
->f
));
3701 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3702 BLACK_PIX_DEFAULT (s
->f
));
3707 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3708 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3709 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3710 relief. LEFT_P non-zero means draw a relief on the left side of
3711 the rectangle. RIGHT_P non-zero means draw a relief on the right
3712 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3716 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3717 raised_p
, left_p
, right_p
, clip_rect
)
3719 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3720 XRectangle
*clip_rect
;
3726 gc
= f
->output_data
.x
->white_relief
.gc
;
3728 gc
= f
->output_data
.x
->black_relief
.gc
;
3729 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3732 for (i
= 0; i
< width
; ++i
)
3733 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3734 left_x
+ i
* left_p
, top_y
+ i
,
3735 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3739 for (i
= 0; i
< width
; ++i
)
3740 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3741 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
3743 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3745 gc
= f
->output_data
.x
->black_relief
.gc
;
3747 gc
= f
->output_data
.x
->white_relief
.gc
;
3748 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3751 for (i
= 0; i
< width
; ++i
)
3752 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3753 left_x
+ i
* left_p
, bottom_y
- i
,
3754 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3758 for (i
= 0; i
< width
; ++i
)
3759 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3760 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3762 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3766 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3767 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3768 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3769 left side of the rectangle. RIGHT_P non-zero means draw a line
3770 on the right side of the rectangle. CLIP_RECT is the clipping
3771 rectangle to use when drawing. */
3774 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3775 left_p
, right_p
, clip_rect
)
3776 struct glyph_string
*s
;
3777 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3778 XRectangle
*clip_rect
;
3782 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3783 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3784 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3787 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3788 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3792 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3793 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3796 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3797 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3801 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3802 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3804 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3805 XSetClipMask (s
->display
, s
->gc
, None
);
3809 /* Draw a box around glyph string S. */
3812 x_draw_glyph_string_box (s
)
3813 struct glyph_string
*s
;
3815 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3816 int left_p
, right_p
;
3817 struct glyph
*last_glyph
;
3818 XRectangle clip_rect
;
3820 last_x
= window_box_right (s
->w
, s
->area
);
3821 if (s
->row
->full_width_p
3822 && !s
->w
->pseudo_window_p
)
3824 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3825 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3826 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3829 /* The glyph that may have a right box line. */
3830 last_glyph
= (s
->cmp
|| s
->img
3832 : s
->first_glyph
+ s
->nchars
- 1);
3834 width
= abs (s
->face
->box_line_width
);
3835 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3837 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3839 : min (last_x
, s
->x
+ s
->background_width
) - 1);
3841 bottom_y
= top_y
+ s
->height
- 1;
3843 left_p
= (s
->first_glyph
->left_box_line_p
3844 || (s
->hl
== DRAW_MOUSE_FACE
3846 || s
->prev
->hl
!= s
->hl
)));
3847 right_p
= (last_glyph
->right_box_line_p
3848 || (s
->hl
== DRAW_MOUSE_FACE
3850 || s
->next
->hl
!= s
->hl
)));
3852 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3854 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3855 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3856 left_p
, right_p
, &clip_rect
);
3859 x_setup_relief_colors (s
);
3860 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3861 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3866 /* Draw foreground of image glyph string S. */
3869 x_draw_image_foreground (s
)
3870 struct glyph_string
*s
;
3873 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3875 /* If first glyph of S has a left box line, start drawing it to the
3876 right of that line. */
3877 if (s
->face
->box
!= FACE_NO_BOX
3878 && s
->first_glyph
->left_box_line_p
)
3879 x
= s
->x
+ abs (s
->face
->box_line_width
);
3883 /* If there is a margin around the image, adjust x- and y-position
3885 x
+= s
->img
->hmargin
;
3886 y
+= s
->img
->vmargin
;
3892 /* We can't set both a clip mask and use XSetClipRectangles
3893 because the latter also sets a clip mask. We also can't
3894 trust on the shape extension to be available
3895 (XShapeCombineRegion). So, compute the rectangle to draw
3897 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3900 XRectangle clip_rect
, image_rect
, r
;
3902 xgcv
.clip_mask
= s
->img
->mask
;
3903 xgcv
.clip_x_origin
= x
;
3904 xgcv
.clip_y_origin
= y
;
3905 xgcv
.function
= GXcopy
;
3906 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3908 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3911 image_rect
.width
= s
->img
->width
;
3912 image_rect
.height
= s
->img
->height
;
3913 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3914 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3915 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3919 unsigned long mask
= GCClipXOrigin
| GCClipYOrigin
| GCFunction
;
3921 XRectangle clip_rect
, image_rect
, r
;
3923 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3926 image_rect
.width
= s
->img
->width
;
3927 image_rect
.height
= s
->img
->height
;
3928 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3929 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3930 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3932 /* When the image has a mask, we can expect that at
3933 least part of a mouse highlight or a block cursor will
3934 be visible. If the image doesn't have a mask, make
3935 a block cursor visible by drawing a rectangle around
3936 the image. I believe it's looking better if we do
3937 nothing here for mouse-face. */
3938 if (s
->hl
== DRAW_CURSOR
)
3939 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3940 s
->img
->width
- 1, s
->img
->height
- 1);
3944 /* Draw a rectangle if image could not be loaded. */
3945 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3946 s
->img
->width
- 1, s
->img
->height
- 1);
3950 /* Draw a relief around the image glyph string S. */
3953 x_draw_image_relief (s
)
3954 struct glyph_string
*s
;
3956 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3959 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3961 /* If first glyph of S has a left box line, start drawing it to the
3962 right of that line. */
3963 if (s
->face
->box
!= FACE_NO_BOX
3964 && s
->first_glyph
->left_box_line_p
)
3965 x
= s
->x
+ abs (s
->face
->box_line_width
);
3969 /* If there is a margin around the image, adjust x- and y-position
3971 x
+= s
->img
->hmargin
;
3972 y
+= s
->img
->vmargin
;
3974 if (s
->hl
== DRAW_IMAGE_SUNKEN
3975 || s
->hl
== DRAW_IMAGE_RAISED
)
3977 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3978 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3982 thick
= abs (s
->img
->relief
);
3983 raised_p
= s
->img
->relief
> 0;
3988 x1
= x
+ s
->img
->width
+ thick
- 1;
3989 y1
= y
+ s
->img
->height
+ thick
- 1;
3991 x_setup_relief_colors (s
);
3992 x_get_glyph_string_clip_rect (s
, &r
);
3993 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3997 /* Draw the foreground of image glyph string S to PIXMAP. */
4000 x_draw_image_foreground_1 (s
, pixmap
)
4001 struct glyph_string
*s
;
4005 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4007 /* If first glyph of S has a left box line, start drawing it to the
4008 right of that line. */
4009 if (s
->face
->box
!= FACE_NO_BOX
4010 && s
->first_glyph
->left_box_line_p
)
4011 x
= abs (s
->face
->box_line_width
);
4015 /* If there is a margin around the image, adjust x- and y-position
4017 x
+= s
->img
->hmargin
;
4018 y
+= s
->img
->vmargin
;
4024 /* We can't set both a clip mask and use XSetClipRectangles
4025 because the latter also sets a clip mask. We also can't
4026 trust on the shape extension to be available
4027 (XShapeCombineRegion). So, compute the rectangle to draw
4029 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4033 xgcv
.clip_mask
= s
->img
->mask
;
4034 xgcv
.clip_x_origin
= x
;
4035 xgcv
.clip_y_origin
= y
;
4036 xgcv
.function
= GXcopy
;
4037 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4039 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4040 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4041 XSetClipMask (s
->display
, s
->gc
, None
);
4045 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4046 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4048 /* When the image has a mask, we can expect that at
4049 least part of a mouse highlight or a block cursor will
4050 be visible. If the image doesn't have a mask, make
4051 a block cursor visible by drawing a rectangle around
4052 the image. I believe it's looking better if we do
4053 nothing here for mouse-face. */
4054 if (s
->hl
== DRAW_CURSOR
)
4055 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4056 s
->img
->width
- 1, s
->img
->height
- 1);
4060 /* Draw a rectangle if image could not be loaded. */
4061 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4062 s
->img
->width
- 1, s
->img
->height
- 1);
4066 /* Draw part of the background of glyph string S. X, Y, W, and H
4067 give the rectangle to draw. */
4070 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4071 struct glyph_string
*s
;
4076 /* Fill background with a stipple pattern. */
4077 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4078 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4079 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4082 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4086 /* Draw image glyph string S.
4089 s->x +-------------------------
4092 | +-------------------------
4095 | | +-------------------
4101 x_draw_image_glyph_string (s
)
4102 struct glyph_string
*s
;
4105 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4106 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4108 Pixmap pixmap
= None
;
4110 height
= s
->height
- 2 * box_line_vwidth
;
4112 /* Fill background with face under the image. Do it only if row is
4113 taller than image or if image has a clip mask to reduce
4115 s
->stippled_p
= s
->face
->stipple
!= 0;
4116 if (height
> s
->img
->height
4120 || s
->img
->pixmap
== 0
4121 || s
->width
!= s
->background_width
)
4123 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4124 x
= s
->x
+ box_line_hwidth
;
4128 y
= s
->y
+ box_line_vwidth
;
4132 /* Create a pixmap as large as the glyph string. Fill it
4133 with the background color. Copy the image to it, using
4134 its mask. Copy the temporary pixmap to the display. */
4135 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4136 int depth
= DefaultDepthOfScreen (screen
);
4138 /* Create a pixmap as large as the glyph string. */
4139 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4140 s
->background_width
,
4143 /* Don't clip in the following because we're working on the
4145 XSetClipMask (s
->display
, s
->gc
, None
);
4147 /* Fill the pixmap with the background color/stipple. */
4150 /* Fill background with a stipple pattern. */
4151 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4152 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4153 0, 0, s
->background_width
, s
->height
);
4154 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4159 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4161 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4162 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4163 0, 0, s
->background_width
, s
->height
);
4164 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4168 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4170 s
->background_filled_p
= 1;
4173 /* Draw the foreground. */
4176 x_draw_image_foreground_1 (s
, pixmap
);
4177 x_set_glyph_string_clipping (s
);
4178 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4179 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4180 XFreePixmap (s
->display
, pixmap
);
4183 x_draw_image_foreground (s
);
4185 /* If we must draw a relief around the image, do it. */
4187 || s
->hl
== DRAW_IMAGE_RAISED
4188 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4189 x_draw_image_relief (s
);
4193 /* Draw stretch glyph string S. */
4196 x_draw_stretch_glyph_string (s
)
4197 struct glyph_string
*s
;
4199 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4200 s
->stippled_p
= s
->face
->stipple
!= 0;
4202 if (s
->hl
== DRAW_CURSOR
4203 && !x_stretch_cursor_p
)
4205 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4206 as wide as the stretch glyph. */
4207 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4210 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4212 /* Clear rest using the GC of the original non-cursor face. */
4213 if (width
< s
->background_width
)
4215 GC gc
= s
->face
->gc
;
4216 int x
= s
->x
+ width
, y
= s
->y
;
4217 int w
= s
->background_width
- width
, h
= s
->height
;
4220 x_get_glyph_string_clip_rect (s
, &r
);
4221 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4223 if (s
->face
->stipple
)
4225 /* Fill background with a stipple pattern. */
4226 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4227 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4228 XSetFillStyle (s
->display
, gc
, FillSolid
);
4233 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4234 XSetForeground (s
->display
, gc
, xgcv
.background
);
4235 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4236 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4241 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4244 s
->background_filled_p
= 1;
4248 /* Draw glyph string S. */
4251 x_draw_glyph_string (s
)
4252 struct glyph_string
*s
;
4254 int relief_drawn_p
= 0;
4256 /* If S draws into the background of its successor, draw the
4257 background of the successor first so that S can draw into it.
4258 This makes S->next use XDrawString instead of XDrawImageString. */
4259 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4261 xassert (s
->next
->img
== NULL
);
4262 x_set_glyph_string_gc (s
->next
);
4263 x_set_glyph_string_clipping (s
->next
);
4264 x_draw_glyph_string_background (s
->next
, 1);
4267 /* Set up S->gc, set clipping and draw S. */
4268 x_set_glyph_string_gc (s
);
4269 x_set_glyph_string_clipping (s
);
4271 /* Draw relief (if any) in advance for char/composition so that the
4272 glyph string can be drawn over it. */
4273 if (!s
->for_overlaps_p
4274 && s
->face
->box
!= FACE_NO_BOX
4275 && (s
->first_glyph
->type
== CHAR_GLYPH
4276 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4279 x_draw_glyph_string_background (s
, 1);
4280 x_draw_glyph_string_box (s
);
4284 switch (s
->first_glyph
->type
)
4287 x_draw_image_glyph_string (s
);
4291 x_draw_stretch_glyph_string (s
);
4295 if (s
->for_overlaps_p
)
4296 s
->background_filled_p
= 1;
4298 x_draw_glyph_string_background (s
, 0);
4299 x_draw_glyph_string_foreground (s
);
4302 case COMPOSITE_GLYPH
:
4303 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4304 s
->background_filled_p
= 1;
4306 x_draw_glyph_string_background (s
, 1);
4307 x_draw_composite_glyph_string_foreground (s
);
4314 if (!s
->for_overlaps_p
)
4316 /* Draw underline. */
4317 if (s
->face
->underline_p
)
4319 unsigned long tem
, h
;
4322 /* Get the underline thickness. Default is 1 pixel. */
4323 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4326 /* Get the underline position. This is the recommended
4327 vertical offset in pixels from the baseline to the top of
4328 the underline. This is a signed value according to the
4329 specs, and its default is
4331 ROUND ((maximum descent) / 2), with
4332 ROUND(x) = floor (x + 0.5) */
4334 if (XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4335 y
= s
->ybase
+ (long) tem
;
4336 else if (s
->face
->font
)
4337 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4341 if (s
->face
->underline_defaulted_p
)
4342 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4343 s
->x
, y
, s
->width
, h
);
4347 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4348 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4349 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4350 s
->x
, y
, s
->width
, h
);
4351 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4355 /* Draw overline. */
4356 if (s
->face
->overline_p
)
4358 unsigned long dy
= 0, h
= 1;
4360 if (s
->face
->overline_color_defaulted_p
)
4361 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4366 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4367 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4368 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4370 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4374 /* Draw strike-through. */
4375 if (s
->face
->strike_through_p
)
4377 unsigned long h
= 1;
4378 unsigned long dy
= (s
->height
- h
) / 2;
4380 if (s
->face
->strike_through_color_defaulted_p
)
4381 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4386 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4387 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4388 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4390 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4394 /* Draw relief if not yet drawn. */
4395 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4396 x_draw_glyph_string_box (s
);
4399 /* Reset clipping. */
4400 XSetClipMask (s
->display
, s
->gc
, None
);
4404 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4405 struct face
**, int));
4408 /* Fill glyph string S with composition components specified by S->cmp.
4410 FACES is an array of faces for all components of this composition.
4411 S->gidx is the index of the first component for S.
4412 OVERLAPS_P non-zero means S should draw the foreground only, and
4413 use its physical height for clipping.
4415 Value is the index of a component not in S. */
4418 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4419 struct glyph_string
*s
;
4420 struct face
**faces
;
4427 s
->for_overlaps_p
= overlaps_p
;
4429 s
->face
= faces
[s
->gidx
];
4430 s
->font
= s
->face
->font
;
4431 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4433 /* For all glyphs of this composition, starting at the offset
4434 S->gidx, until we reach the end of the definition or encounter a
4435 glyph that requires the different face, add it to S. */
4437 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4440 /* All glyph strings for the same composition has the same width,
4441 i.e. the width set for the first component of the composition. */
4443 s
->width
= s
->first_glyph
->pixel_width
;
4445 /* If the specified font could not be loaded, use the frame's
4446 default font, but record the fact that we couldn't load it in
4447 the glyph string so that we can draw rectangles for the
4448 characters of the glyph string. */
4449 if (s
->font
== NULL
)
4451 s
->font_not_found_p
= 1;
4452 s
->font
= FRAME_FONT (s
->f
);
4455 /* Adjust base line for subscript/superscript text. */
4456 s
->ybase
+= s
->first_glyph
->voffset
;
4458 xassert (s
->face
&& s
->face
->gc
);
4460 /* This glyph string must always be drawn with 16-bit functions. */
4463 return s
->gidx
+ s
->nchars
;
4467 /* Fill glyph string S from a sequence of character glyphs.
4469 FACE_ID is the face id of the string. START is the index of the
4470 first glyph to consider, END is the index of the last + 1.
4471 OVERLAPS_P non-zero means S should draw the foreground only, and
4472 use its physical height for clipping.
4474 Value is the index of the first glyph not in S. */
4477 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4478 struct glyph_string
*s
;
4480 int start
, end
, overlaps_p
;
4482 struct glyph
*glyph
, *last
;
4484 int glyph_not_available_p
;
4486 xassert (s
->f
== XFRAME (s
->w
->frame
));
4487 xassert (s
->nchars
== 0);
4488 xassert (start
>= 0 && end
> start
);
4490 s
->for_overlaps_p
= overlaps_p
,
4491 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4492 last
= s
->row
->glyphs
[s
->area
] + end
;
4493 voffset
= glyph
->voffset
;
4495 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4498 && glyph
->type
== CHAR_GLYPH
4499 && glyph
->voffset
== voffset
4500 /* Same face id implies same font, nowadays. */
4501 && glyph
->face_id
== face_id
4502 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4506 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4507 s
->char2b
+ s
->nchars
,
4509 s
->two_byte_p
= two_byte_p
;
4511 xassert (s
->nchars
<= end
- start
);
4512 s
->width
+= glyph
->pixel_width
;
4516 s
->font
= s
->face
->font
;
4517 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4519 /* If the specified font could not be loaded, use the frame's font,
4520 but record the fact that we couldn't load it in
4521 S->font_not_found_p so that we can draw rectangles for the
4522 characters of the glyph string. */
4523 if (s
->font
== NULL
|| glyph_not_available_p
)
4525 s
->font_not_found_p
= 1;
4526 s
->font
= FRAME_FONT (s
->f
);
4529 /* Adjust base line for subscript/superscript text. */
4530 s
->ybase
+= voffset
;
4532 xassert (s
->face
&& s
->face
->gc
);
4533 return glyph
- s
->row
->glyphs
[s
->area
];
4537 /* Fill glyph string S from image glyph S->first_glyph. */
4540 x_fill_image_glyph_string (s
)
4541 struct glyph_string
*s
;
4543 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4544 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4546 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4547 s
->font
= s
->face
->font
;
4548 s
->width
= s
->first_glyph
->pixel_width
;
4550 /* Adjust base line for subscript/superscript text. */
4551 s
->ybase
+= s
->first_glyph
->voffset
;
4555 /* Fill glyph string S from a sequence of stretch glyphs.
4557 ROW is the glyph row in which the glyphs are found, AREA is the
4558 area within the row. START is the index of the first glyph to
4559 consider, END is the index of the last + 1.
4561 Value is the index of the first glyph not in S. */
4564 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4565 struct glyph_string
*s
;
4566 struct glyph_row
*row
;
4567 enum glyph_row_area area
;
4570 struct glyph
*glyph
, *last
;
4571 int voffset
, face_id
;
4573 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4575 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4576 last
= s
->row
->glyphs
[s
->area
] + end
;
4577 face_id
= glyph
->face_id
;
4578 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4579 s
->font
= s
->face
->font
;
4580 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4581 s
->width
= glyph
->pixel_width
;
4582 voffset
= glyph
->voffset
;
4586 && glyph
->type
== STRETCH_GLYPH
4587 && glyph
->voffset
== voffset
4588 && glyph
->face_id
== face_id
);
4590 s
->width
+= glyph
->pixel_width
;
4592 /* Adjust base line for subscript/superscript text. */
4593 s
->ybase
+= voffset
;
4595 xassert (s
->face
&& s
->face
->gc
);
4596 return glyph
- s
->row
->glyphs
[s
->area
];
4600 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4601 of XChar2b structures for S; it can't be allocated in
4602 x_init_glyph_string because it must be allocated via `alloca'. W
4603 is the window on which S is drawn. ROW and AREA are the glyph row
4604 and area within the row from which S is constructed. START is the
4605 index of the first glyph structure covered by S. HL is a
4606 face-override for drawing S. */
4609 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4610 struct glyph_string
*s
;
4613 struct glyph_row
*row
;
4614 enum glyph_row_area area
;
4616 enum draw_glyphs_face hl
;
4618 bzero (s
, sizeof *s
);
4620 s
->f
= XFRAME (w
->frame
);
4621 s
->display
= FRAME_X_DISPLAY (s
->f
);
4622 s
->window
= FRAME_X_WINDOW (s
->f
);
4627 s
->first_glyph
= row
->glyphs
[area
] + start
;
4628 s
->height
= row
->height
;
4629 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4631 /* Display the internal border below the tool-bar window. */
4632 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4633 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4635 s
->ybase
= s
->y
+ row
->ascent
;
4639 /* Set background width of glyph string S. START is the index of the
4640 first glyph following S. LAST_X is the right-most x-position + 1
4641 in the drawing area. */
4644 x_set_glyph_string_background_width (s
, start
, last_x
)
4645 struct glyph_string
*s
;
4649 /* If the face of this glyph string has to be drawn to the end of
4650 the drawing area, set S->extends_to_end_of_line_p. */
4651 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4653 if (start
== s
->row
->used
[s
->area
]
4654 && s
->hl
== DRAW_NORMAL_TEXT
4655 && s
->area
== TEXT_AREA
4656 && (s
->row
->fill_line_p
4657 || s
->face
->background
!= default_face
->background
4658 || s
->face
->stipple
!= default_face
->stipple
))
4659 s
->extends_to_end_of_line_p
= 1;
4661 /* If S extends its face to the end of the line, set its
4662 background_width to the distance to the right edge of the drawing
4664 if (s
->extends_to_end_of_line_p
)
4665 s
->background_width
= last_x
- s
->x
+ 1;
4667 s
->background_width
= s
->width
;
4671 /* Add a glyph string for a stretch glyph to the list of strings
4672 between HEAD and TAIL. START is the index of the stretch glyph in
4673 row area AREA of glyph row ROW. END is the index of the last glyph
4674 in that glyph row area. X is the current output position assigned
4675 to the new glyph string constructed. HL overrides that face of the
4676 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4677 is the right-most x-position of the drawing area. */
4679 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4680 and below -- keep them on one line. */
4681 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4684 s = (struct glyph_string *) alloca (sizeof *s); \
4685 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4686 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4687 x_append_glyph_string (&HEAD, &TAIL, s); \
4693 /* Add a glyph string for an image glyph to the list of strings
4694 between HEAD and TAIL. START is the index of the image glyph in
4695 row area AREA of glyph row ROW. END is the index of the last glyph
4696 in that glyph row area. X is the current output position assigned
4697 to the new glyph string constructed. HL overrides that face of the
4698 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4699 is the right-most x-position of the drawing area. */
4701 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4704 s = (struct glyph_string *) alloca (sizeof *s); \
4705 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4706 x_fill_image_glyph_string (s); \
4707 x_append_glyph_string (&HEAD, &TAIL, s); \
4714 /* Add a glyph string for a sequence of character glyphs to the list
4715 of strings between HEAD and TAIL. START is the index of the first
4716 glyph in row area AREA of glyph row ROW that is part of the new
4717 glyph string. END is the index of the last glyph in that glyph row
4718 area. X is the current output position assigned to the new glyph
4719 string constructed. HL overrides that face of the glyph; e.g. it
4720 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4721 right-most x-position of the drawing area. */
4723 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4729 c = (ROW)->glyphs[AREA][START].u.ch; \
4730 face_id = (ROW)->glyphs[AREA][START].face_id; \
4732 s = (struct glyph_string *) alloca (sizeof *s); \
4733 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4734 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4735 x_append_glyph_string (&HEAD, &TAIL, s); \
4737 START = x_fill_glyph_string (s, face_id, START, END, \
4743 /* Add a glyph string for a composite sequence to the list of strings
4744 between HEAD and TAIL. START is the index of the first glyph in
4745 row area AREA of glyph row ROW that is part of the new glyph
4746 string. END is the index of the last glyph in that glyph row area.
4747 X is the current output position assigned to the new glyph string
4748 constructed. HL overrides that face of the glyph; e.g. it is
4749 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4750 x-position of the drawing area. */
4752 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4754 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4755 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4756 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4757 struct composition *cmp = composition_table[cmp_id]; \
4758 int glyph_len = cmp->glyph_len; \
4760 struct face **faces; \
4761 struct glyph_string *first_s = NULL; \
4764 base_face = base_face->ascii_face; \
4765 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4766 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4767 /* At first, fill in `char2b' and `faces'. */ \
4768 for (n = 0; n < glyph_len; n++) \
4770 int c = COMPOSITION_GLYPH (cmp, n); \
4771 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4772 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4773 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4774 this_face_id, char2b + n, 1); \
4777 /* Make glyph_strings for each glyph sequence that is drawable by \
4778 the same face, and append them to HEAD/TAIL. */ \
4779 for (n = 0; n < cmp->glyph_len;) \
4781 s = (struct glyph_string *) alloca (sizeof *s); \
4782 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4783 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4791 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4799 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4800 of AREA of glyph row ROW on window W between indices START and END.
4801 HL overrides the face for drawing glyph strings, e.g. it is
4802 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4803 x-positions of the drawing area.
4805 This is an ugly monster macro construct because we must use alloca
4806 to allocate glyph strings (because x_draw_glyphs can be called
4809 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4812 HEAD = TAIL = NULL; \
4813 while (START < END) \
4815 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4816 switch (first_glyph->type) \
4819 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4820 TAIL, HL, X, LAST_X, \
4824 case COMPOSITE_GLYPH: \
4825 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
4826 HEAD, TAIL, HL, X, LAST_X,\
4830 case STRETCH_GLYPH: \
4831 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
4832 HEAD, TAIL, HL, X, LAST_X); \
4836 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
4837 TAIL, HL, X, LAST_X); \
4844 x_set_glyph_string_background_width (s, START, LAST_X); \
4851 /* Draw glyphs between START and END in AREA of ROW on window W,
4852 starting at x-position X. X is relative to AREA in W. HL is a
4853 face-override with the following meaning:
4855 DRAW_NORMAL_TEXT draw normally
4856 DRAW_CURSOR draw in cursor face
4857 DRAW_MOUSE_FACE draw in mouse face.
4858 DRAW_INVERSE_VIDEO draw in mode line face
4859 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4860 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4862 If REAL_START is non-null, return in *REAL_START the real starting
4863 position for display. This can be different from START in case
4864 overlapping glyphs must be displayed. If REAL_END is non-null,
4865 return in *REAL_END the real end position for display. This can be
4866 different from END in case overlapping glyphs must be displayed.
4868 If OVERLAPS_P is non-zero, draw only the foreground of characters
4869 and clip to the physical height of ROW.
4871 Value is the x-position reached, relative to AREA of W. */
4874 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4878 struct glyph_row
*row
;
4879 enum glyph_row_area area
;
4881 enum draw_glyphs_face hl
;
4882 int *real_start
, *real_end
;
4885 struct glyph_string
*head
, *tail
;
4886 struct glyph_string
*s
;
4887 int last_x
, area_width
;
4891 /* Let's rather be paranoid than getting a SEGV. */
4892 end
= min (end
, row
->used
[area
]);
4893 start
= max (0, start
);
4894 start
= min (end
, start
);
4896 *real_start
= start
;
4900 /* Translate X to frame coordinates. Set last_x to the right
4901 end of the drawing area. */
4902 if (row
->full_width_p
)
4904 /* X is relative to the left edge of W, without scroll bars
4906 struct frame
*f
= XFRAME (w
->frame
);
4907 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4908 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4911 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4912 last_x
= window_left_x
+ area_width
;
4914 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4916 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4917 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4923 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4924 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4928 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4929 area_width
= window_box_width (w
, area
);
4930 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4933 /* Build a doubly-linked list of glyph_string structures between
4934 head and tail from what we have to draw. Note that the macro
4935 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4936 the reason we use a separate variable `i'. */
4938 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4941 x_reached
= tail
->x
+ tail
->background_width
;
4945 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4946 the row, redraw some glyphs in front or following the glyph
4947 strings built above. */
4948 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4951 struct glyph_string
*h
, *t
;
4953 /* Compute overhangs for all glyph strings. */
4954 for (s
= head
; s
; s
= s
->next
)
4955 x_compute_glyph_string_overhangs (s
);
4957 /* Prepend glyph strings for glyphs in front of the first glyph
4958 string that are overwritten because of the first glyph
4959 string's left overhang. The background of all strings
4960 prepended must be drawn because the first glyph string
4962 i
= x_left_overwritten (head
);
4966 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
4967 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4971 *real_start
= start
;
4972 x_compute_overhangs_and_x (t
, head
->x
, 1);
4973 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4976 /* Prepend glyph strings for glyphs in front of the first glyph
4977 string that overwrite that glyph string because of their
4978 right overhang. For these strings, only the foreground must
4979 be drawn, because it draws over the glyph string at `head'.
4980 The background must not be drawn because this would overwrite
4981 right overhangs of preceding glyphs for which no glyph
4983 i
= x_left_overwriting (head
);
4986 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
4987 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4989 for (s
= h
; s
; s
= s
->next
)
4990 s
->background_filled_p
= 1;
4993 x_compute_overhangs_and_x (t
, head
->x
, 1);
4994 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4997 /* Append glyphs strings for glyphs following the last glyph
4998 string tail that are overwritten by tail. The background of
4999 these strings has to be drawn because tail's foreground draws
5001 i
= x_right_overwritten (tail
);
5004 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5005 DRAW_NORMAL_TEXT
, x
, last_x
,
5007 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5008 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5013 /* Append glyph strings for glyphs following the last glyph
5014 string tail that overwrite tail. The foreground of such
5015 glyphs has to be drawn because it writes into the background
5016 of tail. The background must not be drawn because it could
5017 paint over the foreground of following glyphs. */
5018 i
= x_right_overwriting (tail
);
5021 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5022 DRAW_NORMAL_TEXT
, x
, last_x
,
5024 for (s
= h
; s
; s
= s
->next
)
5025 s
->background_filled_p
= 1;
5026 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5027 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5033 /* Draw all strings. */
5034 for (s
= head
; s
; s
= s
->next
)
5035 x_draw_glyph_string (s
);
5037 /* Value is the x-position up to which drawn, relative to AREA of W.
5038 This doesn't include parts drawn because of overhangs. */
5039 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5040 if (!row
->full_width_p
)
5042 if (area
> LEFT_MARGIN_AREA
)
5043 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5044 if (area
> TEXT_AREA
)
5045 x_reached
-= window_box_width (w
, TEXT_AREA
);
5052 /* Fix the display of area AREA of overlapping row ROW in window W. */
5055 x_fix_overlapping_area (w
, row
, area
)
5057 struct glyph_row
*row
;
5058 enum glyph_row_area area
;
5064 if (area
== LEFT_MARGIN_AREA
)
5066 else if (area
== TEXT_AREA
)
5067 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5069 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5070 + window_box_width (w
, TEXT_AREA
));
5072 for (i
= 0; i
< row
->used
[area
];)
5074 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5076 int start
= i
, start_x
= x
;
5080 x
+= row
->glyphs
[area
][i
].pixel_width
;
5083 while (i
< row
->used
[area
]
5084 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5086 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5088 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5093 x
+= row
->glyphs
[area
][i
].pixel_width
;
5102 /* Output LEN glyphs starting at START at the nominal cursor position.
5103 Advance the nominal cursor over the text. The global variable
5104 updated_window contains the window being updated, updated_row is
5105 the glyph row being updated, and updated_area is the area of that
5106 row being updated. */
5109 x_write_glyphs (start
, len
)
5110 struct glyph
*start
;
5113 int x
, hpos
, real_start
, real_end
;
5115 xassert (updated_window
&& updated_row
);
5120 hpos
= start
- updated_row
->glyphs
[updated_area
];
5121 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5122 updated_row
, updated_area
,
5124 (updated_row
->inverse_p
5125 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5126 &real_start
, &real_end
, 0);
5128 /* If we drew over the cursor, note that it is not visible any more. */
5129 note_overwritten_text_cursor (updated_window
, real_start
,
5130 real_end
- real_start
);
5134 /* Advance the output cursor. */
5135 output_cursor
.hpos
+= len
;
5136 output_cursor
.x
= x
;
5140 /* Insert LEN glyphs from START at the nominal cursor position. */
5143 x_insert_glyphs (start
, len
)
5144 struct glyph
*start
;
5149 int line_height
, shift_by_width
, shifted_region_width
;
5150 struct glyph_row
*row
;
5151 struct glyph
*glyph
;
5152 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5154 xassert (updated_window
&& updated_row
);
5157 f
= XFRAME (WINDOW_FRAME (w
));
5159 /* Get the height of the line we are in. */
5161 line_height
= row
->height
;
5163 /* Get the width of the glyphs to insert. */
5165 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5166 shift_by_width
+= glyph
->pixel_width
;
5168 /* Get the width of the region to shift right. */
5169 shifted_region_width
= (window_box_width (w
, updated_area
)
5174 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5175 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5176 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5177 f
->output_data
.x
->normal_gc
,
5179 shifted_region_width
, line_height
,
5180 frame_x
+ shift_by_width
, frame_y
);
5182 /* Write the glyphs. */
5183 hpos
= start
- row
->glyphs
[updated_area
];
5184 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5185 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5186 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5188 /* Advance the output cursor. */
5189 output_cursor
.hpos
+= len
;
5190 output_cursor
.x
+= shift_by_width
;
5195 /* Delete N glyphs at the nominal cursor position. Not implemented
5206 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
5207 If they are <= 0, this is probably an error. */
5210 x_clear_area (dpy
, window
, x
, y
, width
, height
, exposures
)
5217 xassert (width
> 0 && height
> 0);
5218 XClearArea (dpy
, window
, x
, y
, width
, height
, exposures
);
5222 /* Erase the current text line from the nominal cursor position
5223 (inclusive) to pixel column TO_X (exclusive). The idea is that
5224 everything from TO_X onward is already erased.
5226 TO_X is a pixel position relative to updated_area of
5227 updated_window. TO_X == -1 means clear to the end of this area. */
5230 x_clear_end_of_line (to_x
)
5234 struct window
*w
= updated_window
;
5235 int max_x
, min_y
, max_y
;
5236 int from_x
, from_y
, to_y
;
5238 xassert (updated_window
&& updated_row
);
5239 f
= XFRAME (w
->frame
);
5241 if (updated_row
->full_width_p
)
5243 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5244 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5245 && !w
->pseudo_window_p
)
5246 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5249 max_x
= window_box_width (w
, updated_area
);
5250 max_y
= window_text_bottom_y (w
);
5252 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5253 of window. For TO_X > 0, truncate to end of drawing area. */
5259 to_x
= min (to_x
, max_x
);
5261 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5263 /* Notice if the cursor will be cleared by this operation. */
5264 if (!updated_row
->full_width_p
)
5265 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5267 from_x
= output_cursor
.x
;
5269 /* Translate to frame coordinates. */
5270 if (updated_row
->full_width_p
)
5272 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5273 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5277 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5278 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5281 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5282 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5283 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5285 /* Prevent inadvertently clearing to end of the X window. */
5286 if (to_x
> from_x
&& to_y
> from_y
)
5289 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5290 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5297 /* Clear entire frame. If updating_frame is non-null, clear that
5298 frame. Otherwise clear the selected frame. */
5308 f
= SELECTED_FRAME ();
5310 /* Clearing the frame will erase any cursor, so mark them all as no
5312 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5313 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5314 output_cursor
.x
= -1;
5316 /* We don't set the output cursor here because there will always
5317 follow an explicit cursor_to. */
5319 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5321 /* We have to clear the scroll bars, too. If we have changed
5322 colors or something like that, then they should be notified. */
5323 x_scroll_bar_clear (f
);
5325 XFlush (FRAME_X_DISPLAY (f
));
5331 /* Invert the middle quarter of the frame for .15 sec. */
5333 /* We use the select system call to do the waiting, so we have to make
5334 sure it's available. If it isn't, we just won't do visual bells. */
5336 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5339 /* Subtract the `struct timeval' values X and Y, storing the result in
5340 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5343 timeval_subtract (result
, x
, y
)
5344 struct timeval
*result
, x
, y
;
5346 /* Perform the carry for the later subtraction by updating y. This
5347 is safer because on some systems the tv_sec member is unsigned. */
5348 if (x
.tv_usec
< y
.tv_usec
)
5350 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5351 y
.tv_usec
-= 1000000 * nsec
;
5355 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5357 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5358 y
.tv_usec
+= 1000000 * nsec
;
5362 /* Compute the time remaining to wait. tv_usec is certainly
5364 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5365 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5367 /* Return indication of whether the result should be considered
5369 return x
.tv_sec
< y
.tv_sec
;
5381 /* Create a GC that will use the GXxor function to flip foreground
5382 pixels into background pixels. */
5386 values
.function
= GXxor
;
5387 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5388 ^ f
->output_data
.x
->background_pixel
);
5390 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5391 GCFunction
| GCForeground
, &values
);
5395 /* Get the height not including a menu bar widget. */
5396 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5397 /* Height of each line to flash. */
5398 int flash_height
= FRAME_LINE_HEIGHT (f
);
5399 /* These will be the left and right margins of the rectangles. */
5400 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5401 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5405 /* Don't flash the area between a scroll bar and the frame
5406 edge it is next to. */
5407 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5409 case vertical_scroll_bar_left
:
5410 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5413 case vertical_scroll_bar_right
:
5414 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5421 width
= flash_right
- flash_left
;
5423 /* If window is tall, flash top and bottom line. */
5424 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5426 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5428 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5429 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5430 width
, flash_height
);
5431 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5433 (height
- flash_height
5434 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5435 width
, flash_height
);
5438 /* If it is short, flash it all. */
5439 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5440 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5441 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5446 struct timeval wakeup
;
5448 EMACS_GET_TIME (wakeup
);
5450 /* Compute time to wait until, propagating carry from usecs. */
5451 wakeup
.tv_usec
+= 150000;
5452 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5453 wakeup
.tv_usec
%= 1000000;
5455 /* Keep waiting until past the time wakeup or any input gets
5457 while (! detect_input_pending ())
5459 struct timeval current
;
5460 struct timeval timeout
;
5462 EMACS_GET_TIME (current
);
5464 /* Break if result would be negative. */
5465 if (timeval_subtract (¤t
, wakeup
, current
))
5468 /* How long `select' should wait. */
5470 timeout
.tv_usec
= 10000;
5472 /* Try to wait that long--but we might wake up sooner. */
5473 select (0, NULL
, NULL
, NULL
, &timeout
);
5477 /* If window is tall, flash top and bottom line. */
5478 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5480 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5482 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5483 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5484 width
, flash_height
);
5485 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5487 (height
- flash_height
5488 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5489 width
, flash_height
);
5492 /* If it is short, flash it all. */
5493 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5494 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5495 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5497 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5505 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5508 /* Make audible bell. */
5513 struct frame
*f
= SELECTED_FRAME ();
5515 if (FRAME_X_DISPLAY (f
))
5517 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5524 XBell (FRAME_X_DISPLAY (f
), 0);
5525 XFlush (FRAME_X_DISPLAY (f
));
5532 /* Specify how many text lines, from the top of the window,
5533 should be affected by insert-lines and delete-lines operations.
5534 This, and those operations, are used only within an update
5535 that is bounded by calls to x_update_begin and x_update_end. */
5538 XTset_terminal_window (n
)
5541 /* This function intentionally left blank. */
5546 /***********************************************************************
5548 ***********************************************************************/
5550 /* Perform an insert-lines or delete-lines operation, inserting N
5551 lines or deleting -N lines at vertical position VPOS. */
5554 x_ins_del_lines (vpos
, n
)
5561 /* Scroll part of the display as described by RUN. */
5564 x_scroll_run (w
, run
)
5568 struct frame
*f
= XFRAME (w
->frame
);
5569 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5571 /* Get frame-relative bounding box of the text display area of W,
5572 without mode lines. Include in this box the flags areas to the
5573 left and right of W. */
5574 window_box (w
, -1, &x
, &y
, &width
, &height
);
5575 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5576 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5578 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5579 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5580 bottom_y
= y
+ height
;
5584 /* Scrolling up. Make sure we don't copy part of the mode
5585 line at the bottom. */
5586 if (from_y
+ run
->height
> bottom_y
)
5587 height
= bottom_y
- from_y
;
5589 height
= run
->height
;
5593 /* Scolling down. Make sure we don't copy over the mode line.
5595 if (to_y
+ run
->height
> bottom_y
)
5596 height
= bottom_y
- to_y
;
5598 height
= run
->height
;
5603 /* Cursor off. Will be switched on again in x_update_window_end. */
5607 XCopyArea (FRAME_X_DISPLAY (f
),
5608 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5609 f
->output_data
.x
->normal_gc
,
5619 /***********************************************************************
5621 ***********************************************************************/
5623 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5624 corner of the exposed rectangle. W and H are width and height of
5625 the exposed area. All are pixel values. W or H zero means redraw
5626 the entire frame. */
5629 expose_frame (f
, x
, y
, w
, h
)
5635 TRACE ((stderr
, "expose_frame "));
5637 /* No need to redraw if frame will be redrawn soon. */
5638 if (FRAME_GARBAGED_P (f
))
5640 TRACE ((stderr
, " garbaged\n"));
5644 /* If basic faces haven't been realized yet, there is no point in
5645 trying to redraw anything. This can happen when we get an expose
5646 event while Emacs is starting, e.g. by moving another window. */
5647 if (FRAME_FACE_CACHE (f
) == NULL
5648 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5650 TRACE ((stderr
, " no faces\n"));
5654 if (w
== 0 || h
== 0)
5657 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5658 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5668 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5669 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5671 if (WINDOWP (f
->tool_bar_window
))
5673 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5674 XRectangle window_rect
;
5675 XRectangle intersection_rect
;
5676 int window_x
, window_y
, window_width
, window_height
;
5679 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5680 window_rect
.x
= window_x
;
5681 window_rect
.y
= window_y
;
5682 window_rect
.width
= window_width
;
5683 window_rect
.height
= window_height
;
5685 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5686 expose_window (w
, &intersection_rect
);
5689 #ifndef USE_X_TOOLKIT
5690 if (WINDOWP (f
->menu_bar_window
))
5692 struct window
*w
= XWINDOW (f
->menu_bar_window
);
5693 XRectangle window_rect
;
5694 XRectangle intersection_rect
;
5695 int window_x
, window_y
, window_width
, window_height
;
5698 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5699 window_rect
.x
= window_x
;
5700 window_rect
.y
= window_y
;
5701 window_rect
.width
= window_width
;
5702 window_rect
.height
= window_height
;
5704 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5705 expose_window (w
, &intersection_rect
);
5707 #endif /* not USE_X_TOOLKIT */
5711 /* Redraw (parts) of all windows in the window tree rooted at W that
5712 intersect R. R contains frame pixel coordinates. */
5715 expose_window_tree (w
, r
)
5721 if (!NILP (w
->hchild
))
5722 expose_window_tree (XWINDOW (w
->hchild
), r
);
5723 else if (!NILP (w
->vchild
))
5724 expose_window_tree (XWINDOW (w
->vchild
), r
);
5727 XRectangle window_rect
;
5728 XRectangle intersection_rect
;
5729 struct frame
*f
= XFRAME (w
->frame
);
5730 int window_x
, window_y
, window_width
, window_height
;
5732 /* Frame-relative pixel rectangle of W. */
5733 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5737 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5738 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5739 window_rect
.y
= window_y
;
5742 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5743 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5745 = window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5747 if (x_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
5748 expose_window (w
, &intersection_rect
);
5751 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5756 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5757 which intersects rectangle R. R is in window-relative coordinates. */
5760 expose_area (w
, row
, r
, area
)
5762 struct glyph_row
*row
;
5764 enum glyph_row_area area
;
5766 struct glyph
*first
= row
->glyphs
[area
];
5767 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5769 int first_x
, start_x
, x
;
5771 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5772 /* If row extends face to end of line write the whole line. */
5773 x_draw_glyphs (w
, 0, row
, area
,
5775 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5779 /* Set START_X to the window-relative start position for drawing glyphs of
5780 AREA. The first glyph of the text area can be partially visible.
5781 The first glyphs of other areas cannot. */
5782 if (area
== LEFT_MARGIN_AREA
)
5784 else if (area
== TEXT_AREA
)
5785 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5787 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5788 + window_box_width (w
, TEXT_AREA
));
5791 /* Find the first glyph that must be redrawn. */
5793 && x
+ first
->pixel_width
< r
->x
)
5795 x
+= first
->pixel_width
;
5799 /* Find the last one. */
5803 && x
< r
->x
+ r
->width
)
5805 x
+= last
->pixel_width
;
5811 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5812 first
- row
->glyphs
[area
],
5813 last
- row
->glyphs
[area
],
5814 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5820 /* Redraw the parts of the glyph row ROW on window W intersecting
5821 rectangle R. R is in window-relative coordinates. */
5824 expose_line (w
, row
, r
)
5826 struct glyph_row
*row
;
5829 xassert (row
->enabled_p
);
5831 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5832 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5833 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5837 if (row
->used
[LEFT_MARGIN_AREA
])
5838 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5839 if (row
->used
[TEXT_AREA
])
5840 expose_area (w
, row
, r
, TEXT_AREA
);
5841 if (row
->used
[RIGHT_MARGIN_AREA
])
5842 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5843 x_draw_row_bitmaps (w
, row
);
5848 /* Return non-zero if W's cursor intersects rectangle R. */
5851 x_phys_cursor_in_rect_p (w
, r
)
5855 XRectangle cr
, result
;
5856 struct glyph
*cursor_glyph
;
5858 cursor_glyph
= get_phys_cursor_glyph (w
);
5861 cr
.x
= w
->phys_cursor
.x
;
5862 cr
.y
= w
->phys_cursor
.y
;
5863 cr
.width
= cursor_glyph
->pixel_width
;
5864 cr
.height
= w
->phys_cursor_height
;
5865 return x_intersect_rectangles (&cr
, r
, &result
);
5872 /* Redraw a rectangle of window W. R is a rectangle in window
5873 relative coordinates. Call this function with input blocked. */
5876 expose_window (w
, r
)
5880 struct glyph_row
*row
;
5882 int yb
= window_text_bottom_y (w
);
5883 int cursor_cleared_p
;
5885 /* If window is not yet fully initialized, do nothing. This can
5886 happen when toolkit scroll bars are used and a window is split.
5887 Reconfiguring the scroll bar will generate an expose for a newly
5889 if (w
->current_matrix
== NULL
|| w
== updated_window
)
5892 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5893 r
->x
, r
->y
, r
->width
, r
->height
));
5895 /* Convert to window coordinates. */
5896 r
->x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->x
);
5897 r
->y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->y
);
5899 /* Turn off the cursor. */
5900 if (!w
->pseudo_window_p
5901 && x_phys_cursor_in_rect_p (w
, r
))
5904 cursor_cleared_p
= 1;
5907 cursor_cleared_p
= 0;
5909 /* Find the first row intersecting the rectangle R. */
5910 row
= w
->current_matrix
->rows
;
5912 while (row
->enabled_p
5914 && y
+ row
->height
< r
->y
)
5920 /* Display the text in the rectangle, one text line at a time. */
5921 while (row
->enabled_p
5923 && y
< r
->y
+ r
->height
)
5925 expose_line (w
, row
, r
);
5930 /* Display the mode line if there is one. */
5931 if (WINDOW_WANTS_MODELINE_P (w
)
5932 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5934 && row
->y
< r
->y
+ r
->height
)
5935 expose_line (w
, row
, r
);
5937 if (!w
->pseudo_window_p
)
5939 /* Draw border between windows. */
5940 x_draw_vertical_border (w
);
5942 /* Turn the cursor on again. */
5943 if (cursor_cleared_p
)
5944 x_update_window_cursor (w
, 1);
5949 /* Determine the intersection of two rectangles R1 and R2. Return
5950 the intersection in *RESULT. Value is non-zero if RESULT is not
5954 x_intersect_rectangles (r1
, r2
, result
)
5955 XRectangle
*r1
, *r2
, *result
;
5957 XRectangle
*left
, *right
;
5958 XRectangle
*upper
, *lower
;
5959 int intersection_p
= 0;
5961 /* Rearrange so that R1 is the left-most rectangle. */
5963 left
= r1
, right
= r2
;
5965 left
= r2
, right
= r1
;
5967 /* X0 of the intersection is right.x0, if this is inside R1,
5968 otherwise there is no intersection. */
5969 if (right
->x
<= left
->x
+ left
->width
)
5971 result
->x
= right
->x
;
5973 /* The right end of the intersection is the minimum of the
5974 the right ends of left and right. */
5975 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
5978 /* Same game for Y. */
5980 upper
= r1
, lower
= r2
;
5982 upper
= r2
, lower
= r1
;
5984 /* The upper end of the intersection is lower.y0, if this is inside
5985 of upper. Otherwise, there is no intersection. */
5986 if (lower
->y
<= upper
->y
+ upper
->height
)
5988 result
->y
= lower
->y
;
5990 /* The lower end of the intersection is the minimum of the lower
5991 ends of upper and lower. */
5992 result
->height
= (min (lower
->y
+ lower
->height
,
5993 upper
->y
+ upper
->height
)
5999 return intersection_p
;
6010 /* We used to only do this if Vx_no_window_manager was non-nil, but
6011 the ICCCM (section 4.1.6) says that the window's border pixmap
6012 and border pixel are window attributes which are "private to the
6013 client", so we can always change it to whatever we want. */
6015 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6016 f
->output_data
.x
->border_pixel
);
6018 x_update_cursor (f
, 1);
6022 frame_unhighlight (f
)
6025 /* We used to only do this if Vx_no_window_manager was non-nil, but
6026 the ICCCM (section 4.1.6) says that the window's border pixmap
6027 and border pixel are window attributes which are "private to the
6028 client", so we can always change it to whatever we want. */
6030 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6031 f
->output_data
.x
->border_tile
);
6033 x_update_cursor (f
, 1);
6036 /* The focus has changed. Update the frames as necessary to reflect
6037 the new situation. Note that we can't change the selected frame
6038 here, because the Lisp code we are interrupting might become confused.
6039 Each event gets marked with the frame in which it occurred, so the
6040 Lisp code can tell when the switch took place by examining the events. */
6043 x_new_focus_frame (dpyinfo
, frame
)
6044 struct x_display_info
*dpyinfo
;
6045 struct frame
*frame
;
6047 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6049 if (frame
!= dpyinfo
->x_focus_frame
)
6051 /* Set this before calling other routines, so that they see
6052 the correct value of x_focus_frame. */
6053 dpyinfo
->x_focus_frame
= frame
;
6055 if (old_focus
&& old_focus
->auto_lower
)
6056 x_lower_frame (old_focus
);
6059 selected_frame
= frame
;
6060 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6062 Fselect_window (selected_frame
->selected_window
);
6063 choose_minibuf_frame ();
6066 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6067 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6069 pending_autoraise_frame
= 0;
6072 x_frame_rehighlight (dpyinfo
);
6075 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6078 x_mouse_leave (dpyinfo
)
6079 struct x_display_info
*dpyinfo
;
6081 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6084 /* The focus has changed, or we have redirected a frame's focus to
6085 another frame (this happens when a frame uses a surrogate
6086 mini-buffer frame). Shift the highlight as appropriate.
6088 The FRAME argument doesn't necessarily have anything to do with which
6089 frame is being highlighted or un-highlighted; we only use it to find
6090 the appropriate X display info. */
6093 XTframe_rehighlight (frame
)
6094 struct frame
*frame
;
6096 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6100 x_frame_rehighlight (dpyinfo
)
6101 struct x_display_info
*dpyinfo
;
6103 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6105 if (dpyinfo
->x_focus_frame
)
6107 dpyinfo
->x_highlight_frame
6108 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6109 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6110 : dpyinfo
->x_focus_frame
);
6111 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6113 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6114 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6118 dpyinfo
->x_highlight_frame
= 0;
6120 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6123 frame_unhighlight (old_highlight
);
6124 if (dpyinfo
->x_highlight_frame
)
6125 frame_highlight (dpyinfo
->x_highlight_frame
);
6131 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6133 /* Initialize mode_switch_bit and modifier_meaning. */
6135 x_find_modifier_meanings (dpyinfo
)
6136 struct x_display_info
*dpyinfo
;
6138 int min_code
, max_code
;
6141 XModifierKeymap
*mods
;
6143 dpyinfo
->meta_mod_mask
= 0;
6144 dpyinfo
->shift_lock_mask
= 0;
6145 dpyinfo
->alt_mod_mask
= 0;
6146 dpyinfo
->super_mod_mask
= 0;
6147 dpyinfo
->hyper_mod_mask
= 0;
6150 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6152 min_code
= dpyinfo
->display
->min_keycode
;
6153 max_code
= dpyinfo
->display
->max_keycode
;
6156 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6157 min_code
, max_code
- min_code
+ 1,
6159 mods
= XGetModifierMapping (dpyinfo
->display
);
6161 /* Scan the modifier table to see which modifier bits the Meta and
6162 Alt keysyms are on. */
6164 int row
, col
; /* The row and column in the modifier table. */
6166 for (row
= 3; row
< 8; row
++)
6167 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6170 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6172 /* Zeroes are used for filler. Skip them. */
6176 /* Are any of this keycode's keysyms a meta key? */
6180 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6182 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6188 dpyinfo
->meta_mod_mask
|= (1 << row
);
6193 dpyinfo
->alt_mod_mask
|= (1 << row
);
6198 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6203 dpyinfo
->super_mod_mask
|= (1 << row
);
6207 /* Ignore this if it's not on the lock modifier. */
6208 if ((1 << row
) == LockMask
)
6209 dpyinfo
->shift_lock_mask
= LockMask
;
6217 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6218 if (! dpyinfo
->meta_mod_mask
)
6220 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6221 dpyinfo
->alt_mod_mask
= 0;
6224 /* If some keys are both alt and meta,
6225 make them just meta, not alt. */
6226 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6228 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6231 XFree ((char *) syms
);
6232 XFreeModifiermap (mods
);
6235 /* Convert between the modifier bits X uses and the modifier bits
6239 x_x_to_emacs_modifiers (dpyinfo
, state
)
6240 struct x_display_info
*dpyinfo
;
6243 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6244 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6245 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6246 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6247 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6248 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6252 x_emacs_to_x_modifiers (dpyinfo
, state
)
6253 struct x_display_info
*dpyinfo
;
6256 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6257 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6258 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6259 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6260 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6261 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6264 /* Convert a keysym to its name. */
6267 x_get_keysym_name (keysym
)
6273 value
= XKeysymToString (keysym
);
6281 /* Mouse clicks and mouse movement. Rah. */
6283 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6284 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6285 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6286 not force the value into range. */
6289 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6291 register int pix_x
, pix_y
;
6292 register int *x
, *y
;
6296 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6297 even for negative values. */
6299 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6301 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6303 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6304 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6308 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6309 bounds
->height
= f
->output_data
.x
->line_height
;
6310 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6311 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6318 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6319 pix_x
= FRAME_WINDOW_WIDTH (f
);
6323 else if (pix_y
> f
->height
)
6332 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6333 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6334 can't tell the positions because W's display is not up to date,
6338 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6341 int *frame_x
, *frame_y
;
6345 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6346 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6348 if (display_completed
)
6350 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6351 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6352 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6358 *frame_x
+= glyph
->pixel_width
;
6366 *frame_y
= *frame_x
= 0;
6370 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6371 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6376 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6378 If the event is a button press, then note that we have grabbed
6382 construct_mouse_click (result
, event
, f
)
6383 struct input_event
*result
;
6384 XButtonEvent
*event
;
6387 /* Make the event type no_event; we'll change that when we decide
6389 result
->kind
= mouse_click
;
6390 result
->code
= event
->button
- Button1
;
6391 result
->timestamp
= event
->time
;
6392 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6394 | (event
->type
== ButtonRelease
6398 XSETINT (result
->x
, event
->x
);
6399 XSETINT (result
->y
, event
->y
);
6400 XSETFRAME (result
->frame_or_window
, f
);
6406 /* Function to report a mouse movement to the mainstream Emacs code.
6407 The input handler calls this.
6409 We have received a mouse movement event, which is given in *event.
6410 If the mouse is over a different glyph than it was last time, tell
6411 the mainstream emacs code by setting mouse_moved. If not, ask for
6412 another motion event, so we can check again the next time it moves. */
6414 static XMotionEvent last_mouse_motion_event
;
6415 static Lisp_Object last_mouse_motion_frame
;
6418 note_mouse_movement (frame
, event
)
6420 XMotionEvent
*event
;
6422 last_mouse_movement_time
= event
->time
;
6423 last_mouse_motion_event
= *event
;
6424 XSETFRAME (last_mouse_motion_frame
, frame
);
6426 if (event
->window
!= FRAME_X_WINDOW (frame
))
6428 frame
->mouse_moved
= 1;
6429 last_mouse_scroll_bar
= Qnil
;
6430 note_mouse_highlight (frame
, -1, -1);
6433 /* Has the mouse moved off the glyph it was on at the last sighting? */
6434 else if (event
->x
< last_mouse_glyph
.x
6435 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6436 || event
->y
< last_mouse_glyph
.y
6437 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6439 frame
->mouse_moved
= 1;
6440 last_mouse_scroll_bar
= Qnil
;
6441 note_mouse_highlight (frame
, event
->x
, event
->y
);
6445 /* This is used for debugging, to turn off note_mouse_highlight. */
6447 int disable_mouse_highlight
;
6451 /************************************************************************
6453 ************************************************************************/
6455 /* Find the glyph under window-relative coordinates X/Y in window W.
6456 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6457 strings. Return in *HPOS and *VPOS the row and column number of
6458 the glyph found. Return in *AREA the glyph area containing X.
6459 Value is a pointer to the glyph found or null if X/Y is not on
6460 text, or we can't tell because W's current matrix is not up to
6463 static struct glyph
*
6464 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6467 int *hpos
, *vpos
, *area
;
6470 struct glyph
*glyph
, *end
;
6471 struct glyph_row
*row
= NULL
;
6472 int x0
, i
, left_area_width
;
6474 /* Find row containing Y. Give up if some row is not enabled. */
6475 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6477 row
= MATRIX_ROW (w
->current_matrix
, i
);
6478 if (!row
->enabled_p
)
6480 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6487 /* Give up if Y is not in the window. */
6488 if (i
== w
->current_matrix
->nrows
)
6491 /* Get the glyph area containing X. */
6492 if (w
->pseudo_window_p
)
6499 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6500 if (x
< left_area_width
)
6502 *area
= LEFT_MARGIN_AREA
;
6505 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6508 x0
= row
->x
+ left_area_width
;
6512 *area
= RIGHT_MARGIN_AREA
;
6513 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6517 /* Find glyph containing X. */
6518 glyph
= row
->glyphs
[*area
];
6519 end
= glyph
+ row
->used
[*area
];
6522 if (x
< x0
+ glyph
->pixel_width
)
6524 if (w
->pseudo_window_p
)
6526 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6530 x0
+= glyph
->pixel_width
;
6537 *hpos
= glyph
- row
->glyphs
[*area
];
6542 /* Convert frame-relative x/y to coordinates relative to window W.
6543 Takes pseudo-windows into account. */
6546 frame_to_window_pixel_xy (w
, x
, y
)
6550 if (w
->pseudo_window_p
)
6552 /* A pseudo-window is always full-width, and starts at the
6553 left edge of the frame, plus a frame border. */
6554 struct frame
*f
= XFRAME (w
->frame
);
6555 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6556 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6560 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6561 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6566 /* Take proper action when mouse has moved to the mode or header line of
6567 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6568 mode line. X is relative to the start of the text display area of
6569 W, so the width of bitmap areas and scroll bars must be subtracted
6570 to get a position relative to the start of the mode line. */
6573 note_mode_line_highlight (w
, x
, mode_line_p
)
6577 struct frame
*f
= XFRAME (w
->frame
);
6578 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6579 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6580 struct glyph_row
*row
;
6583 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6585 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6589 struct glyph
*glyph
, *end
;
6590 Lisp_Object help
, map
;
6593 /* Find the glyph under X. */
6594 glyph
= row
->glyphs
[TEXT_AREA
];
6595 end
= glyph
+ row
->used
[TEXT_AREA
];
6596 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6597 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6600 && x
>= x0
+ glyph
->pixel_width
)
6602 x0
+= glyph
->pixel_width
;
6607 && STRINGP (glyph
->object
)
6608 && XSTRING (glyph
->object
)->intervals
6609 && glyph
->charpos
>= 0
6610 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6612 /* If we're on a string with `help-echo' text property,
6613 arrange for the help to be displayed. This is done by
6614 setting the global variable help_echo to the help string. */
6615 help
= Fget_text_property (make_number (glyph
->charpos
),
6616 Qhelp_echo
, glyph
->object
);
6620 XSETWINDOW (help_echo_window
, w
);
6621 help_echo_object
= glyph
->object
;
6622 help_echo_pos
= glyph
->charpos
;
6625 /* Change the mouse pointer according to what is under X/Y. */
6626 map
= Fget_text_property (make_number (glyph
->charpos
),
6627 Qlocal_map
, glyph
->object
);
6629 cursor
= f
->output_data
.x
->nontext_cursor
;
6632 map
= Fget_text_property (make_number (glyph
->charpos
),
6633 Qkeymap
, glyph
->object
);
6635 cursor
= f
->output_data
.x
->nontext_cursor
;
6640 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6644 /* Take proper action when the mouse has moved to position X, Y on
6645 frame F as regards highlighting characters that have mouse-face
6646 properties. Also de-highlighting chars where the mouse was before.
6647 X and Y can be negative or out of range. */
6650 note_mouse_highlight (f
, x
, y
)
6654 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6659 /* When a menu is active, don't highlight because this looks odd. */
6660 #ifdef USE_X_TOOLKIT
6661 if (popup_activated ())
6665 if (disable_mouse_highlight
6666 || !f
->glyphs_initialized_p
)
6669 dpyinfo
->mouse_face_mouse_x
= x
;
6670 dpyinfo
->mouse_face_mouse_y
= y
;
6671 dpyinfo
->mouse_face_mouse_frame
= f
;
6673 if (dpyinfo
->mouse_face_defer
)
6678 dpyinfo
->mouse_face_deferred_gc
= 1;
6682 /* Which window is that in? */
6683 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6685 /* If we were displaying active text in another window, clear that. */
6686 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6687 clear_mouse_face (dpyinfo
);
6689 /* Not on a window -> return. */
6690 if (!WINDOWP (window
))
6693 /* Convert to window-relative pixel coordinates. */
6694 w
= XWINDOW (window
);
6695 frame_to_window_pixel_xy (w
, &x
, &y
);
6697 /* Handle tool-bar window differently since it doesn't display a
6699 if (EQ (window
, f
->tool_bar_window
))
6701 note_tool_bar_highlight (f
, x
, y
);
6705 if (portion
== 1 || portion
== 3)
6707 /* Mouse is on the mode or top line. */
6708 note_mode_line_highlight (w
, x
, portion
== 1);
6711 else if (portion
== 2)
6712 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6713 f
->output_data
.x
->horizontal_drag_cursor
);
6715 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6716 f
->output_data
.x
->text_cursor
);
6718 /* Are we in a window whose display is up to date?
6719 And verify the buffer's text has not changed. */
6720 if (/* Within text portion of the window. */
6722 && EQ (w
->window_end_valid
, w
->buffer
)
6723 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6724 && (XFASTINT (w
->last_overlay_modified
)
6725 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6727 int hpos
, vpos
, pos
, i
, area
;
6728 struct glyph
*glyph
;
6731 /* Find the glyph under X/Y. */
6732 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6734 /* Clear mouse face if X/Y not over text. */
6736 || area
!= TEXT_AREA
6737 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6739 clear_mouse_face (dpyinfo
);
6743 pos
= glyph
->charpos
;
6744 object
= glyph
->object
;
6745 if (!STRINGP (object
) && !BUFFERP (object
))
6749 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6750 Lisp_Object
*overlay_vec
= NULL
;
6752 struct buffer
*obuf
;
6755 /* If we get an out-of-range value, return now; avoid an error. */
6756 if (BUFFERP (object
) && pos
> BUF_Z (XBUFFER (w
->buffer
)))
6759 /* Make the window's buffer temporarily current for
6760 overlays_at and compute_char_face. */
6761 obuf
= current_buffer
;
6762 current_buffer
= XBUFFER (w
->buffer
);
6768 /* Is this char mouse-active or does it have help-echo? */
6769 position
= make_number (pos
);
6771 if (BUFFERP (object
))
6773 /* Put all the overlays we want in a vector in overlay_vec.
6774 Store the length in len. If there are more than 10, make
6775 enough space for all, and try again. */
6777 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6778 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6779 if (noverlays
> len
)
6782 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6783 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6786 /* Sort overlays into increasing priority order. */
6787 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6792 /* Check mouse-face highlighting. */
6793 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6794 && vpos
>= dpyinfo
->mouse_face_beg_row
6795 && vpos
<= dpyinfo
->mouse_face_end_row
6796 && (vpos
> dpyinfo
->mouse_face_beg_row
6797 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6798 && (vpos
< dpyinfo
->mouse_face_end_row
6799 || hpos
< dpyinfo
->mouse_face_end_col
6800 || dpyinfo
->mouse_face_past_end
))
6801 /* If there exists an overlay with mouse-face overlapping
6802 the one we are currently highlighting, we have to
6803 check if we enter the overlapping overlay, and then
6804 highlight only that. */
6805 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6806 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6809 /* Clear the display of the old active region, if any. */
6810 clear_mouse_face (dpyinfo
);
6812 /* Find the highest priority overlay that has a mouse-face
6815 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6817 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6818 if (!NILP (mouse_face
))
6819 overlay
= overlay_vec
[i
];
6821 dpyinfo
->mouse_face_overlay
= overlay
;
6823 /* If no overlay applies, get a text property. */
6825 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6827 /* Handle the overlay case. */
6828 if (!NILP (overlay
))
6830 /* Find the range of text around this char that
6831 should be active. */
6832 Lisp_Object before
, after
;
6835 before
= Foverlay_start (overlay
);
6836 after
= Foverlay_end (overlay
);
6837 /* Record this as the current active region. */
6838 fast_find_position (w
, XFASTINT (before
),
6839 &dpyinfo
->mouse_face_beg_col
,
6840 &dpyinfo
->mouse_face_beg_row
,
6841 &dpyinfo
->mouse_face_beg_x
,
6842 &dpyinfo
->mouse_face_beg_y
);
6843 dpyinfo
->mouse_face_past_end
6844 = !fast_find_position (w
, XFASTINT (after
),
6845 &dpyinfo
->mouse_face_end_col
,
6846 &dpyinfo
->mouse_face_end_row
,
6847 &dpyinfo
->mouse_face_end_x
,
6848 &dpyinfo
->mouse_face_end_y
);
6849 dpyinfo
->mouse_face_window
= window
;
6850 dpyinfo
->mouse_face_face_id
6851 = face_at_buffer_position (w
, pos
, 0, 0,
6852 &ignore
, pos
+ 1, 1);
6854 /* Display it as active. */
6855 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6857 /* Handle the text property case. */
6858 else if (!NILP (mouse_face
) && BUFFERP (object
))
6860 /* Find the range of text around this char that
6861 should be active. */
6862 Lisp_Object before
, after
, beginning
, end
;
6865 beginning
= Fmarker_position (w
->start
);
6866 end
= make_number (BUF_Z (XBUFFER (object
))
6867 - XFASTINT (w
->window_end_pos
));
6869 = Fprevious_single_property_change (make_number (pos
+ 1),
6873 = Fnext_single_property_change (position
, Qmouse_face
,
6876 /* Record this as the current active region. */
6877 fast_find_position (w
, XFASTINT (before
),
6878 &dpyinfo
->mouse_face_beg_col
,
6879 &dpyinfo
->mouse_face_beg_row
,
6880 &dpyinfo
->mouse_face_beg_x
,
6881 &dpyinfo
->mouse_face_beg_y
);
6882 dpyinfo
->mouse_face_past_end
6883 = !fast_find_position (w
, XFASTINT (after
),
6884 &dpyinfo
->mouse_face_end_col
,
6885 &dpyinfo
->mouse_face_end_row
,
6886 &dpyinfo
->mouse_face_end_x
,
6887 &dpyinfo
->mouse_face_end_y
);
6888 dpyinfo
->mouse_face_window
= window
;
6890 if (BUFFERP (object
))
6891 dpyinfo
->mouse_face_face_id
6892 = face_at_buffer_position (w
, pos
, 0, 0,
6893 &ignore
, pos
+ 1, 1);
6895 /* Display it as active. */
6896 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6898 else if (!NILP (mouse_face
) && STRINGP (object
))
6903 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6906 e
= Fnext_single_property_change (position
, Qmouse_face
,
6909 b
= make_number (0);
6911 e
= make_number (XSTRING (object
)->size
- 1);
6912 fast_find_string_pos (w
, XINT (b
), object
,
6913 &dpyinfo
->mouse_face_beg_col
,
6914 &dpyinfo
->mouse_face_beg_row
,
6915 &dpyinfo
->mouse_face_beg_x
,
6916 &dpyinfo
->mouse_face_beg_y
, 0);
6917 fast_find_string_pos (w
, XINT (e
), object
,
6918 &dpyinfo
->mouse_face_end_col
,
6919 &dpyinfo
->mouse_face_end_row
,
6920 &dpyinfo
->mouse_face_end_x
,
6921 &dpyinfo
->mouse_face_end_y
, 1);
6922 dpyinfo
->mouse_face_past_end
= 0;
6923 dpyinfo
->mouse_face_window
= window
;
6924 dpyinfo
->mouse_face_face_id
6925 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6927 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6931 /* Look for a `help-echo' property. */
6933 Lisp_Object help
, overlay
;
6935 /* Check overlays first. */
6936 help
= overlay
= Qnil
;
6937 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6939 overlay
= overlay_vec
[i
];
6940 help
= Foverlay_get (overlay
, Qhelp_echo
);
6946 help_echo_window
= window
;
6947 help_echo_object
= overlay
;
6948 help_echo_pos
= pos
;
6952 Lisp_Object object
= glyph
->object
;
6953 int charpos
= glyph
->charpos
;
6955 /* Try text properties. */
6956 if (STRINGP (object
)
6958 && charpos
< XSTRING (object
)->size
)
6960 help
= Fget_text_property (make_number (charpos
),
6961 Qhelp_echo
, object
);
6964 /* If the string itself doesn't specify a help-echo,
6965 see if the buffer text ``under'' it does. */
6967 = MATRIX_ROW (w
->current_matrix
, vpos
);
6968 int start
= MATRIX_ROW_START_CHARPOS (r
);
6969 int pos
= string_buffer_position (w
, object
, start
);
6972 help
= Fget_text_property (make_number (pos
),
6973 Qhelp_echo
, w
->buffer
);
6982 else if (BUFFERP (object
)
6985 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6991 help_echo_window
= window
;
6992 help_echo_object
= object
;
6993 help_echo_pos
= charpos
;
7000 current_buffer
= obuf
;
7006 redo_mouse_highlight ()
7008 if (!NILP (last_mouse_motion_frame
)
7009 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7010 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7011 last_mouse_motion_event
.x
,
7012 last_mouse_motion_event
.y
);
7017 /***********************************************************************
7019 ***********************************************************************/
7021 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7022 struct glyph
**, int *, int *, int *));
7024 /* Tool-bar item index of the item on which a mouse button was pressed
7027 static int last_tool_bar_item
;
7030 /* Get information about the tool-bar item at position X/Y on frame F.
7031 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7032 the current matrix of the tool-bar window of F, or NULL if not
7033 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7034 item in F->tool_bar_items. Value is
7036 -1 if X/Y is not on a tool-bar item
7037 0 if X/Y is on the same item that was highlighted before.
7041 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7044 struct glyph
**glyph
;
7045 int *hpos
, *vpos
, *prop_idx
;
7047 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7048 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7051 /* Find the glyph under X/Y. */
7052 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7056 /* Get the start of this tool-bar item's properties in
7057 f->tool_bar_items. */
7058 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7061 /* Is mouse on the highlighted item? */
7062 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7063 && *vpos
>= dpyinfo
->mouse_face_beg_row
7064 && *vpos
<= dpyinfo
->mouse_face_end_row
7065 && (*vpos
> dpyinfo
->mouse_face_beg_row
7066 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7067 && (*vpos
< dpyinfo
->mouse_face_end_row
7068 || *hpos
< dpyinfo
->mouse_face_end_col
7069 || dpyinfo
->mouse_face_past_end
))
7076 /* Handle mouse button event on the tool-bar of frame F, at
7077 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7081 x_handle_tool_bar_click (f
, button_event
)
7083 XButtonEvent
*button_event
;
7085 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7086 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7087 int hpos
, vpos
, prop_idx
;
7088 struct glyph
*glyph
;
7089 Lisp_Object enabled_p
;
7090 int x
= button_event
->x
;
7091 int y
= button_event
->y
;
7093 /* If not on the highlighted tool-bar item, return. */
7094 frame_to_window_pixel_xy (w
, &x
, &y
);
7095 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7098 /* If item is disabled, do nothing. */
7099 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7100 if (NILP (enabled_p
))
7103 if (button_event
->type
== ButtonPress
)
7105 /* Show item in pressed state. */
7106 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7107 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7108 last_tool_bar_item
= prop_idx
;
7112 Lisp_Object key
, frame
;
7113 struct input_event event
;
7115 /* Show item in released state. */
7116 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7117 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7119 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7121 XSETFRAME (frame
, f
);
7122 event
.kind
= TOOL_BAR_EVENT
;
7123 event
.frame_or_window
= frame
;
7125 kbd_buffer_store_event (&event
);
7127 event
.kind
= TOOL_BAR_EVENT
;
7128 event
.frame_or_window
= frame
;
7130 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7131 button_event
->state
);
7132 kbd_buffer_store_event (&event
);
7133 last_tool_bar_item
= -1;
7138 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7139 tool-bar window-relative coordinates X/Y. Called from
7140 note_mouse_highlight. */
7143 note_tool_bar_highlight (f
, x
, y
)
7147 Lisp_Object window
= f
->tool_bar_window
;
7148 struct window
*w
= XWINDOW (window
);
7149 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7151 struct glyph
*glyph
;
7152 struct glyph_row
*row
;
7154 Lisp_Object enabled_p
;
7156 enum draw_glyphs_face draw
;
7157 int mouse_down_p
, rc
;
7159 /* Function note_mouse_highlight is called with negative x(y
7160 values when mouse moves outside of the frame. */
7161 if (x
<= 0 || y
<= 0)
7163 clear_mouse_face (dpyinfo
);
7167 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7170 /* Not on tool-bar item. */
7171 clear_mouse_face (dpyinfo
);
7177 clear_mouse_face (dpyinfo
);
7179 /* Mouse is down, but on different tool-bar item? */
7180 mouse_down_p
= (dpyinfo
->grabbed
7181 && f
== last_mouse_frame
7182 && FRAME_LIVE_P (f
));
7184 && last_tool_bar_item
!= prop_idx
)
7187 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7188 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7190 /* If tool-bar item is not enabled, don't highlight it. */
7191 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7192 if (!NILP (enabled_p
))
7194 /* Compute the x-position of the glyph. In front and past the
7195 image is a space. We include this is the highlighted area. */
7196 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7197 for (i
= x
= 0; i
< hpos
; ++i
)
7198 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7200 /* Record this as the current active region. */
7201 dpyinfo
->mouse_face_beg_col
= hpos
;
7202 dpyinfo
->mouse_face_beg_row
= vpos
;
7203 dpyinfo
->mouse_face_beg_x
= x
;
7204 dpyinfo
->mouse_face_beg_y
= row
->y
;
7205 dpyinfo
->mouse_face_past_end
= 0;
7207 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7208 dpyinfo
->mouse_face_end_row
= vpos
;
7209 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7210 dpyinfo
->mouse_face_end_y
= row
->y
;
7211 dpyinfo
->mouse_face_window
= window
;
7212 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7214 /* Display it as active. */
7215 show_mouse_face (dpyinfo
, draw
);
7216 dpyinfo
->mouse_face_image_state
= draw
;
7221 /* Set help_echo to a help string.to display for this tool-bar item.
7222 XTread_socket does the rest. */
7223 help_echo_object
= help_echo_window
= Qnil
;
7225 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7226 if (NILP (help_echo
))
7227 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7232 /* Find the glyph matrix position of buffer position POS in window W.
7233 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7234 current glyphs must be up to date. If POS is above window start
7235 return (0, 0, 0, 0). If POS is after end of W, return end of
7239 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
7242 int *hpos
, *vpos
, *x
, *y
;
7246 int maybe_next_line_p
= 0;
7247 int line_start_position
;
7248 int yb
= window_text_bottom_y (w
);
7249 struct glyph_row
*row
, *best_row
;
7250 int row_vpos
, best_row_vpos
;
7253 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7254 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7258 if (row
->used
[TEXT_AREA
])
7259 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7261 line_start_position
= 0;
7263 if (line_start_position
> pos
)
7265 /* If the position sought is the end of the buffer,
7266 don't include the blank lines at the bottom of the window. */
7267 else if (line_start_position
== pos
7268 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7270 maybe_next_line_p
= 1;
7273 else if (line_start_position
> 0)
7276 best_row_vpos
= row_vpos
;
7279 if (row
->y
+ row
->height
>= yb
)
7286 /* Find the right column within BEST_ROW. */
7288 current_x
= best_row
->x
;
7289 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7291 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7294 charpos
= glyph
->charpos
;
7298 *vpos
= best_row_vpos
;
7303 else if (charpos
> pos
)
7305 else if (charpos
> 0)
7308 current_x
+= glyph
->pixel_width
;
7311 /* If we're looking for the end of the buffer,
7312 and we didn't find it in the line we scanned,
7313 use the start of the following line. */
7314 if (maybe_next_line_p
)
7319 current_x
= best_row
->x
;
7322 *vpos
= best_row_vpos
;
7323 *hpos
= lastcol
+ 1;
7330 /* Find the position of the the glyph for position POS in OBJECT in
7331 window W's current matrix, and return in *X/*Y the pixel
7332 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7334 RIGHT_P non-zero means return the position of the right edge of the
7335 glyph, RIGHT_P zero means return the left edge position.
7337 If no glyph for POS exists in the matrix, return the position of
7338 the glyph with the next smaller position that is in the matrix, if
7339 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7340 exists in the matrix, return the position of the glyph with the
7341 next larger position in OBJECT.
7343 Value is non-zero if a glyph was found. */
7346 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7350 int *hpos
, *vpos
, *x
, *y
;
7353 int yb
= window_text_bottom_y (w
);
7354 struct glyph_row
*r
;
7355 struct glyph
*best_glyph
= NULL
;
7356 struct glyph_row
*best_row
= NULL
;
7359 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7360 r
->enabled_p
&& r
->y
< yb
;
7363 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7364 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7367 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7368 if (EQ (g
->object
, object
))
7370 if (g
->charpos
== pos
)
7377 else if (best_glyph
== NULL
7378 || ((abs (g
->charpos
- pos
)
7379 < abs (best_glyph
->charpos
- pos
))
7382 : g
->charpos
> pos
)))
7396 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7400 *x
+= best_glyph
->pixel_width
;
7405 *vpos
= best_row
- w
->current_matrix
->rows
;
7408 return best_glyph
!= NULL
;
7412 /* Display the active region described by mouse_face_*
7413 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7416 show_mouse_face (dpyinfo
, draw
)
7417 struct x_display_info
*dpyinfo
;
7418 enum draw_glyphs_face draw
;
7420 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7421 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7423 int cursor_off_p
= 0;
7424 struct cursor_pos saved_cursor
;
7426 saved_cursor
= output_cursor
;
7428 /* If window is in the process of being destroyed, don't bother
7430 if (w
->current_matrix
== NULL
)
7433 /* Recognize when we are called to operate on rows that don't exist
7434 anymore. This can happen when a window is split. */
7435 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7438 set_output_cursor (&w
->phys_cursor
);
7440 /* Note that mouse_face_beg_row etc. are window relative. */
7441 for (i
= dpyinfo
->mouse_face_beg_row
;
7442 i
<= dpyinfo
->mouse_face_end_row
;
7445 int start_hpos
, end_hpos
, start_x
;
7446 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7448 /* Don't do anything if row doesn't have valid contents. */
7449 if (!row
->enabled_p
)
7452 /* For all but the first row, the highlight starts at column 0. */
7453 if (i
== dpyinfo
->mouse_face_beg_row
)
7455 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7456 start_x
= dpyinfo
->mouse_face_beg_x
;
7464 if (i
== dpyinfo
->mouse_face_end_row
)
7465 end_hpos
= dpyinfo
->mouse_face_end_col
;
7467 end_hpos
= row
->used
[TEXT_AREA
];
7469 /* If the cursor's in the text we are about to rewrite, turn the
7471 if (!w
->pseudo_window_p
7472 && i
== output_cursor
.vpos
7473 && output_cursor
.hpos
>= start_hpos
- 1
7474 && output_cursor
.hpos
<= end_hpos
)
7476 x_update_window_cursor (w
, 0);
7480 if (end_hpos
> start_hpos
)
7482 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7483 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7484 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7488 /* If we turned the cursor off, turn it back on. */
7490 x_display_cursor (w
, 1,
7491 output_cursor
.hpos
, output_cursor
.vpos
,
7492 output_cursor
.x
, output_cursor
.y
);
7494 output_cursor
= saved_cursor
;
7498 /* Change the mouse cursor. */
7499 if (draw
== DRAW_NORMAL_TEXT
)
7500 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7501 f
->output_data
.x
->text_cursor
);
7502 else if (draw
== DRAW_MOUSE_FACE
)
7503 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7504 f
->output_data
.x
->cross_cursor
);
7506 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7507 f
->output_data
.x
->nontext_cursor
);
7510 /* Clear out the mouse-highlighted active region.
7511 Redraw it un-highlighted first. */
7514 clear_mouse_face (dpyinfo
)
7515 struct x_display_info
*dpyinfo
;
7517 #if 0 /* This prevents redrawing tool bar items when changing from one
7518 to another while a tooltip is open, so don't do it. */
7519 if (!NILP (tip_frame
))
7523 if (! NILP (dpyinfo
->mouse_face_window
))
7524 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7526 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7527 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7528 dpyinfo
->mouse_face_window
= Qnil
;
7532 /* Clear any mouse-face on window W. This function is part of the
7533 redisplay interface, and is called from try_window_id and similar
7534 functions to ensure the mouse-highlight is off. */
7537 x_clear_mouse_face (w
)
7540 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7544 XSETWINDOW (window
, w
);
7545 if (EQ (window
, dpyinfo
->mouse_face_window
))
7546 clear_mouse_face (dpyinfo
);
7551 /* Just discard the mouse face information for frame F, if any.
7552 This is used when the size of F is changed. */
7555 cancel_mouse_face (f
)
7559 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7561 window
= dpyinfo
->mouse_face_window
;
7562 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7564 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7565 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7566 dpyinfo
->mouse_face_window
= Qnil
;
7571 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
7574 /* Try to determine frame pixel position and size of the glyph under
7575 frame pixel coordinates X/Y on frame F . Return the position and
7576 size in *RECT. Value is non-zero if we could compute these
7580 glyph_rect (f
, x
, y
, rect
)
7586 int part
, found
= 0;
7588 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7591 struct window
*w
= XWINDOW (window
);
7592 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7593 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7596 frame_to_window_pixel_xy (w
, &x
, &y
);
7598 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7601 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7602 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7605 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7608 rect
->width
= g
->pixel_width
;
7609 rect
->height
= r
->height
;
7610 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7611 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7621 /* Return the current position of the mouse.
7622 *FP should be a frame which indicates which display to ask about.
7624 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
7625 and *PART to the frame, window, and scroll bar part that the mouse
7626 is over. Set *X and *Y to the portion and whole of the mouse's
7627 position on the scroll bar.
7629 If the mouse movement started elsewhere, set *FP to the frame the
7630 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
7633 Set *TIME to the server time-stamp for the time at which the mouse
7634 was at this position.
7636 Don't store anything if we don't have a valid set of values to report.
7638 This clears the mouse_moved flag, so we can wait for the next mouse
7642 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7645 Lisp_Object
*bar_window
;
7646 enum scroll_bar_part
*part
;
7648 unsigned long *time
;
7654 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7655 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7661 Window dummy_window
;
7664 Lisp_Object frame
, tail
;
7666 /* Clear the mouse-moved flag for every frame on this display. */
7667 FOR_EACH_FRAME (tail
, frame
)
7668 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7669 XFRAME (frame
)->mouse_moved
= 0;
7671 last_mouse_scroll_bar
= Qnil
;
7673 /* Figure out which root window we're on. */
7674 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7675 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7677 /* The root window which contains the pointer. */
7680 /* Trash which we can't trust if the pointer is on
7681 a different screen. */
7684 /* The position on that root window. */
7687 /* More trash we can't trust. */
7690 /* Modifier keys and pointer buttons, about which
7692 (unsigned int *) &dummy
);
7694 /* Now we have a position on the root; find the innermost window
7695 containing the pointer. */
7699 int parent_x
= 0, parent_y
= 0;
7704 /* XTranslateCoordinates can get errors if the window
7705 structure is changing at the same time this function
7706 is running. So at least we must not crash from them. */
7708 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
7710 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7711 && FRAME_LIVE_P (last_mouse_frame
))
7713 /* If mouse was grabbed on a frame, give coords for that frame
7714 even if the mouse is now outside it. */
7715 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7717 /* From-window, to-window. */
7718 root
, FRAME_X_WINDOW (last_mouse_frame
),
7720 /* From-position, to-position. */
7721 root_x
, root_y
, &win_x
, &win_y
,
7725 f1
= last_mouse_frame
;
7731 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7733 /* From-window, to-window. */
7736 /* From-position, to-position. */
7737 root_x
, root_y
, &win_x
, &win_y
,
7742 if (child
== None
|| child
== win
)
7750 /* Now we know that:
7751 win is the innermost window containing the pointer
7752 (XTC says it has no child containing the pointer),
7753 win_x and win_y are the pointer's position in it
7754 (XTC did this the last time through), and
7755 parent_x and parent_y are the pointer's position in win's parent.
7756 (They are what win_x and win_y were when win was child.
7757 If win is the root window, it has no parent, and
7758 parent_{x,y} are invalid, but that's okay, because we'll
7759 never use them in that case.) */
7761 /* Is win one of our frames? */
7762 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
7764 #ifdef USE_X_TOOLKIT
7765 /* If we end up with the menu bar window, say it's not
7768 && f1
->output_data
.x
->menubar_widget
7769 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
7771 #endif /* USE_X_TOOLKIT */
7774 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
7777 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
7779 /* If not, is it one of our scroll bars? */
7782 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
7786 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7792 if (f1
== 0 && insist
> 0)
7793 f1
= SELECTED_FRAME ();
7797 /* Ok, we found a frame. Store all the values.
7798 last_mouse_glyph is a rectangle used to reduce the
7799 generation of mouse events. To not miss any motion
7800 events, we must divide the frame into rectangles of the
7801 size of the smallest character that could be displayed
7802 on it, i.e. into the same rectangles that matrices on
7803 the frame are divided into. */
7805 int width
, height
, gx
, gy
;
7808 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
7809 last_mouse_glyph
= rect
;
7812 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7813 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7817 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7818 round down even for negative values. */
7823 gx
= (gx
+ width
- 1) / width
* width
;
7824 gy
= (gy
+ height
- 1) / height
* height
;
7826 last_mouse_glyph
.width
= width
;
7827 last_mouse_glyph
.height
= height
;
7828 last_mouse_glyph
.x
= gx
;
7829 last_mouse_glyph
.y
= gy
;
7835 XSETINT (*x
, win_x
);
7836 XSETINT (*y
, win_y
);
7837 *time
= last_mouse_movement_time
;
7846 #ifdef USE_X_TOOLKIT
7848 /* Atimer callback function for TIMER. Called every 0.1s to process
7849 Xt timeouts, if needed. We must avoid calling XtAppPending as
7850 much as possible because that function does an implicit XFlush
7851 that slows us down. */
7854 x_process_timeouts (timer
)
7855 struct atimer
*timer
;
7857 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
7860 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
7861 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
7866 #endif /* USE_X_TOOLKIT */
7869 /* Scroll bar support. */
7871 /* Given an X window ID, find the struct scroll_bar which manages it.
7872 This can be called in GC, so we have to make sure to strip off mark
7875 static struct scroll_bar
*
7876 x_window_to_scroll_bar (window_id
)
7881 for (tail
= Vframe_list
;
7882 XGCTYPE (tail
) == Lisp_Cons
;
7885 Lisp_Object frame
, bar
, condemned
;
7887 frame
= XCAR (tail
);
7888 /* All elements of Vframe_list should be frames. */
7889 if (! GC_FRAMEP (frame
))
7892 /* Scan this frame's scroll bar list for a scroll bar with the
7894 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7895 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7896 /* This trick allows us to search both the ordinary and
7897 condemned scroll bar lists with one loop. */
7898 ! GC_NILP (bar
) || (bar
= condemned
,
7901 bar
= XSCROLL_BAR (bar
)->next
)
7902 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7903 return XSCROLL_BAR (bar
);
7911 /************************************************************************
7913 ************************************************************************/
7915 #ifdef USE_TOOLKIT_SCROLL_BARS
7917 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
7918 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
7919 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
7920 struct scroll_bar
*));
7921 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
7925 /* Id of action hook installed for scroll bars. */
7927 static XtActionHookId action_hook_id
;
7929 /* Lisp window being scrolled. Set when starting to interact with
7930 a toolkit scroll bar, reset to nil when ending the interaction. */
7932 static Lisp_Object window_being_scrolled
;
7934 /* Last scroll bar part sent in xm_scroll_callback. */
7936 static int last_scroll_bar_part
;
7938 /* Whether this is an Xaw with arrow-scrollbars. This should imply
7939 that movements of 1/20 of the screen size are mapped to up/down. */
7941 static Boolean xaw3d_arrow_scroll
;
7943 /* Whether the drag scrolling maintains the mouse at the top of the
7944 thumb. If not, resizing the thumb needs to be done more carefully
7945 to avoid jerkyness. */
7947 static Boolean xaw3d_pick_top
;
7950 /* Action hook installed via XtAppAddActionHook when toolkit scroll
7951 bars are used.. The hook is responsible for detecting when
7952 the user ends an interaction with the scroll bar, and generates
7953 a `end-scroll' scroll_bar_click' event if so. */
7956 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
7959 XtPointer client_data
;
7963 Cardinal
*num_params
;
7969 scroll_bar_p
= XmIsScrollBar (widget
);
7970 end_action
= "Release";
7971 #else /* !USE_MOTIF i.e. use Xaw */
7972 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
7973 end_action
= "EndScroll";
7974 #endif /* USE_MOTIF */
7977 && strcmp (action_name
, end_action
) == 0
7978 && WINDOWP (window_being_scrolled
))
7982 x_send_scroll_bar_event (window_being_scrolled
,
7983 scroll_bar_end_scroll
, 0, 0);
7984 w
= XWINDOW (window_being_scrolled
);
7985 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
7986 window_being_scrolled
= Qnil
;
7987 last_scroll_bar_part
= -1;
7989 /* Xt timeouts no longer needed. */
7990 toolkit_scroll_bar_interaction
= 0;
7994 /* A vector of windows used for communication between
7995 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
7997 static struct window
**scroll_bar_windows
;
7998 static int scroll_bar_windows_size
;
8001 /* Send a client message with message type Xatom_Scrollbar for a
8002 scroll action to the frame of WINDOW. PART is a value identifying
8003 the part of the scroll bar that was clicked on. PORTION is the
8004 amount to scroll of a whole of WHOLE. */
8007 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8009 int part
, portion
, whole
;
8012 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8013 struct window
*w
= XWINDOW (window
);
8014 struct frame
*f
= XFRAME (w
->frame
);
8019 /* Construct a ClientMessage event to send to the frame. */
8020 ev
->type
= ClientMessage
;
8021 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8022 ev
->display
= FRAME_X_DISPLAY (f
);
8023 ev
->window
= FRAME_X_WINDOW (f
);
8026 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8027 not enough to store a pointer or Lisp_Object on a 64 bit system.
8028 So, store the window in scroll_bar_windows and pass the index
8029 into that array in the event. */
8030 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8031 if (scroll_bar_windows
[i
] == NULL
)
8034 if (i
== scroll_bar_windows_size
)
8036 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8037 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8038 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8040 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8042 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8043 scroll_bar_windows_size
= new_size
;
8046 scroll_bar_windows
[i
] = w
;
8047 ev
->data
.l
[0] = (long) i
;
8048 ev
->data
.l
[1] = (long) part
;
8049 ev
->data
.l
[2] = (long) 0;
8050 ev
->data
.l
[3] = (long) portion
;
8051 ev
->data
.l
[4] = (long) whole
;
8053 /* Make Xt timeouts work while the scroll bar is active. */
8054 toolkit_scroll_bar_interaction
= 1;
8056 /* Setting the event mask to zero means that the message will
8057 be sent to the client that created the window, and if that
8058 window no longer exists, no event will be sent. */
8059 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8064 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8068 x_scroll_bar_to_input_event (event
, ievent
)
8070 struct input_event
*ievent
;
8072 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8077 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8078 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8080 XSETWINDOW (window
, w
);
8081 f
= XFRAME (w
->frame
);
8083 ievent
->kind
= scroll_bar_click
;
8084 ievent
->frame_or_window
= window
;
8086 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8087 ievent
->part
= ev
->data
.l
[1];
8088 ievent
->code
= ev
->data
.l
[2];
8089 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8090 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8091 ievent
->modifiers
= 0;
8097 /* Minimum and maximum values used for Motif scroll bars. */
8100 #define XM_SB_MAX 10000000
8101 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8104 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8105 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8106 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
8109 xm_scroll_callback (widget
, client_data
, call_data
)
8111 XtPointer client_data
, call_data
;
8113 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8114 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8116 int part
= -1, whole
= 0, portion
= 0;
8120 case XmCR_DECREMENT
:
8121 bar
->dragging
= Qnil
;
8122 part
= scroll_bar_up_arrow
;
8125 case XmCR_INCREMENT
:
8126 bar
->dragging
= Qnil
;
8127 part
= scroll_bar_down_arrow
;
8130 case XmCR_PAGE_DECREMENT
:
8131 bar
->dragging
= Qnil
;
8132 part
= scroll_bar_above_handle
;
8135 case XmCR_PAGE_INCREMENT
:
8136 bar
->dragging
= Qnil
;
8137 part
= scroll_bar_below_handle
;
8141 bar
->dragging
= Qnil
;
8142 part
= scroll_bar_to_top
;
8145 case XmCR_TO_BOTTOM
:
8146 bar
->dragging
= Qnil
;
8147 part
= scroll_bar_to_bottom
;
8153 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8154 && XINT (bar
->dragging
) <= cs
->value
);
8156 /* Get the slider size. */
8158 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8161 /* At the max position of the scroll bar, do a line-wise
8162 movement. Without doing anything, we would be called with
8163 the same cs->value again and again. If we want to make
8164 sure that we can reach the end of the buffer, we have to do
8167 Implementation note: setting bar->dragging always to
8168 cs->value gives a smoother movement at the max position.
8169 Setting it to nil when doing line-wise movement gives
8170 a better slider behavior. */
8172 if (cs
->value
+ slider_size
== XM_SB_MAX
8174 && last_scroll_bar_part
== scroll_bar_down_arrow
))
8176 part
= scroll_bar_down_arrow
;
8177 bar
->dragging
= Qnil
;
8181 whole
= XM_SB_RANGE
;
8182 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
8183 part
= scroll_bar_handle
;
8184 bar
->dragging
= make_number (cs
->value
);
8189 case XmCR_VALUE_CHANGED
:
8195 window_being_scrolled
= bar
->window
;
8196 last_scroll_bar_part
= part
;
8197 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8202 #else /* !USE_MOTIF, i.e. Xaw. */
8205 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8206 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8207 scroll bar struct. CALL_DATA is a pointer to a float saying where
8211 xaw_jump_callback (widget
, client_data
, call_data
)
8213 XtPointer client_data
, call_data
;
8215 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8216 float top
= *(float *) call_data
;
8218 int whole
, portion
, height
;
8221 /* Get the size of the thumb, a value between 0 and 1. */
8223 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8227 portion
= shown
< 1 ? top
* whole
: 0;
8229 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8230 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8231 the bottom, so we force the scrolling whenever we see that we're
8232 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8233 we try to ensure that we always stay two pixels away from the
8235 part
= scroll_bar_down_arrow
;
8237 part
= scroll_bar_handle
;
8239 window_being_scrolled
= bar
->window
;
8240 bar
->dragging
= make_number (portion
);
8241 last_scroll_bar_part
= part
;
8242 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8246 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8247 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8248 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8249 the scroll bar. CALL_DATA is an integer specifying the action that
8250 has taken place. It's magnitude is in the range 0..height of the
8251 scroll bar. Negative values mean scroll towards buffer start.
8252 Values < height of scroll bar mean line-wise movement. */
8255 xaw_scroll_callback (widget
, client_data
, call_data
)
8257 XtPointer client_data
, call_data
;
8259 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8260 int position
= (int) call_data
;
8264 /* Get the height of the scroll bar. */
8266 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8269 if (abs (position
) >= height
)
8270 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8272 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8273 it maps line-movement to call_data = max(5, height/20). */
8274 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8275 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8277 part
= scroll_bar_move_ratio
;
8279 window_being_scrolled
= bar
->window
;
8280 bar
->dragging
= Qnil
;
8281 last_scroll_bar_part
= part
;
8282 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8286 #endif /* not USE_MOTIF */
8289 /* Create the widget for scroll bar BAR on frame F. Record the widget
8290 and X window of the scroll bar in BAR. */
8293 x_create_toolkit_scroll_bar (f
, bar
)
8295 struct scroll_bar
*bar
;
8301 char *scroll_bar_name
= "verticalScrollBar";
8302 unsigned long pixel
;
8307 /* Set resources. Create the widget. */
8308 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8309 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8310 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8311 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8312 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8313 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8314 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8316 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8319 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8323 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8326 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8330 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8331 scroll_bar_name
, av
, ac
);
8333 /* Add one callback for everything that can happen. */
8334 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8336 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8338 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8340 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8342 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8344 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8346 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8349 /* Realize the widget. Only after that is the X window created. */
8350 XtRealizeWidget (widget
);
8352 /* Set the cursor to an arrow. I didn't find a resource to do that.
8353 And I'm wondering why it hasn't an arrow cursor by default. */
8354 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8355 f
->output_data
.x
->nontext_cursor
);
8357 #else /* !USE_MOTIF i.e. use Xaw */
8359 /* Set resources. Create the widget. The background of the
8360 Xaw3d scroll bar widget is a little bit light for my taste.
8361 We don't alter it here to let users change it according
8362 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8363 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8364 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8365 /* For smoother scrolling with Xaw3d -sm */
8366 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8367 /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
8369 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8372 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8376 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8379 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8383 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8384 f
->output_data
.x
->edit_widget
, av
, ac
);
8388 char *val
= initial
;
8389 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8390 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8392 { /* ARROW_SCROLL */
8393 xaw3d_arrow_scroll
= True
;
8394 /* Isn't that just a personal preference ? -sm */
8395 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8399 /* Define callbacks. */
8400 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8401 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8404 /* Realize the widget. Only after that is the X window created. */
8405 XtRealizeWidget (widget
);
8407 #endif /* !USE_MOTIF */
8409 /* Install an action hook that let's us detect when the user
8410 finishes interacting with a scroll bar. */
8411 if (action_hook_id
== 0)
8412 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8414 /* Remember X window and widget in the scroll bar vector. */
8415 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8416 xwindow
= XtWindow (widget
);
8417 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8423 /* Set the thumb size and position of scroll bar BAR. We are currently
8424 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8427 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8428 struct scroll_bar
*bar
;
8429 int portion
, position
, whole
;
8431 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8432 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8439 top
= (float) position
/ whole
;
8440 shown
= (float) portion
/ whole
;
8448 XmScrollBarWidget sb
;
8450 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8451 is the scroll bar's maximum and MIN is the scroll bar's minimum
8453 size
= shown
* XM_SB_RANGE
;
8454 size
= min (size
, XM_SB_RANGE
);
8455 size
= max (size
, 1);
8457 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8458 value
= top
* XM_SB_RANGE
;
8459 value
= min (value
, XM_SB_MAX
- size
);
8460 value
= max (value
, XM_SB_MIN
);
8462 if (NILP (bar
->dragging
))
8463 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8464 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8465 /* This has the negative side effect that the slider value is
8466 not what it would be if we scrolled here using line-wise or
8467 page-wise movement. */
8468 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8471 /* If currently dragging, only update the slider size.
8472 This reduces flicker effects. */
8473 int old_value
, old_size
, increment
, page_increment
;
8475 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8476 &increment
, &page_increment
);
8477 XmScrollBarSetValues (widget
, old_value
,
8478 min (size
, XM_SB_RANGE
- old_value
),
8482 #else /* !USE_MOTIF i.e. use Xaw */
8484 float old_top
, old_shown
;
8486 XtVaGetValues (widget
,
8487 XtNtopOfThumb
, &old_top
,
8488 XtNshown
, &old_shown
,
8492 /* Massage the top+shown values. */
8493 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8494 top
= max (0, min (1, top
));
8497 /* Keep two pixels available for moving the thumb down. */
8498 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8500 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8501 check that your system's configuration file contains a define
8502 for `NARROWPROTO'. See s/freebsd.h for an example. */
8503 if (top
!= old_top
|| shown
!= old_shown
)
8505 if (NILP (bar
->dragging
))
8506 XawScrollbarSetThumb (widget
, top
, shown
);
8510 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8511 int scroll_mode
= 0;
8513 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8514 if (xaw3d_arrow_scroll
)
8516 /* Xaw3d stupidly ignores resize requests while dragging
8517 so we have to make it believe it's not in dragging mode. */
8518 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8519 if (scroll_mode
== 2)
8520 sb
->scrollbar
.scroll_mode
= 0;
8523 /* Try to make the scrolling a tad smoother. */
8524 if (!xaw3d_pick_top
)
8525 shown
= min (shown
, old_shown
);
8527 XawScrollbarSetThumb (widget
, top
, shown
);
8530 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8531 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8536 #endif /* !USE_MOTIF */
8541 #endif /* USE_TOOLKIT_SCROLL_BARS */
8545 /************************************************************************
8546 Scroll bars, general
8547 ************************************************************************/
8549 /* Create a scroll bar and return the scroll bar vector for it. W is
8550 the Emacs window on which to create the scroll bar. TOP, LEFT,
8551 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8554 static struct scroll_bar
*
8555 x_scroll_bar_create (w
, top
, left
, width
, height
)
8557 int top
, left
, width
, height
;
8559 struct frame
*f
= XFRAME (w
->frame
);
8560 struct scroll_bar
*bar
8561 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8565 #ifdef USE_TOOLKIT_SCROLL_BARS
8566 x_create_toolkit_scroll_bar (f
, bar
);
8567 #else /* not USE_TOOLKIT_SCROLL_BARS */
8569 XSetWindowAttributes a
;
8573 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8574 if (a
.background_pixel
== -1)
8575 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8577 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8578 | ButtonMotionMask
| PointerMotionHintMask
8580 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8582 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8584 /* Clear the area of W that will serve as a scroll bar. This is
8585 for the case that a window has been split horizontally. In
8586 this case, no clear_frame is generated to reduce flickering. */
8587 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8589 window_box_height (w
), False
);
8591 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8592 /* Position and size of scroll bar. */
8593 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8595 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8597 /* Border width, depth, class, and visual. */
8604 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8606 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8608 XSETWINDOW (bar
->window
, w
);
8609 XSETINT (bar
->top
, top
);
8610 XSETINT (bar
->left
, left
);
8611 XSETINT (bar
->width
, width
);
8612 XSETINT (bar
->height
, height
);
8613 XSETINT (bar
->start
, 0);
8614 XSETINT (bar
->end
, 0);
8615 bar
->dragging
= Qnil
;
8617 /* Add bar to its frame's list of scroll bars. */
8618 bar
->next
= FRAME_SCROLL_BARS (f
);
8620 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8621 if (!NILP (bar
->next
))
8622 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8624 /* Map the window/widget. */
8625 #ifdef USE_TOOLKIT_SCROLL_BARS
8627 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8628 XtConfigureWidget (scroll_bar
,
8629 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8631 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8632 max (height
, 1), 0);
8633 XtMapWidget (scroll_bar
);
8635 #else /* not USE_TOOLKIT_SCROLL_BARS */
8636 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8637 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8644 /* Draw BAR's handle in the proper position.
8646 If the handle is already drawn from START to END, don't bother
8647 redrawing it, unless REBUILD is non-zero; in that case, always
8648 redraw it. (REBUILD is handy for drawing the handle after expose
8651 Normally, we want to constrain the start and end of the handle to
8652 fit inside its rectangle, but if the user is dragging the scroll
8653 bar handle, we want to let them drag it down all the way, so that
8654 the bar's top is as far down as it goes; otherwise, there's no way
8655 to move to the very end of the buffer. */
8657 #ifndef USE_TOOLKIT_SCROLL_BARS
8660 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8661 struct scroll_bar
*bar
;
8665 int dragging
= ! NILP (bar
->dragging
);
8666 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8667 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8668 GC gc
= f
->output_data
.x
->normal_gc
;
8670 /* If the display is already accurate, do nothing. */
8672 && start
== XINT (bar
->start
)
8673 && end
== XINT (bar
->end
))
8679 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
8680 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8681 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8683 /* Make sure the values are reasonable, and try to preserve
8684 the distance between start and end. */
8686 int length
= end
- start
;
8690 else if (start
> top_range
)
8692 end
= start
+ length
;
8696 else if (end
> top_range
&& ! dragging
)
8700 /* Store the adjusted setting in the scroll bar. */
8701 XSETINT (bar
->start
, start
);
8702 XSETINT (bar
->end
, end
);
8704 /* Clip the end position, just for display. */
8705 if (end
> top_range
)
8708 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
8709 below top positions, to make sure the handle is always at least
8710 that many pixels tall. */
8711 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8713 /* Draw the empty space above the handle. Note that we can't clear
8714 zero-height areas; that means "clear to end of window." */
8716 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8717 /* x, y, width, height, and exposures. */
8718 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8719 VERTICAL_SCROLL_BAR_TOP_BORDER
,
8720 inside_width
, start
,
8723 /* Change to proper foreground color if one is specified. */
8724 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8725 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8726 f
->output_data
.x
->scroll_bar_foreground_pixel
);
8728 /* Draw the handle itself. */
8729 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8730 /* x, y, width, height */
8731 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8732 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
8733 inside_width
, end
- start
);
8735 /* Restore the foreground color of the GC if we changed it above. */
8736 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8737 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8738 f
->output_data
.x
->foreground_pixel
);
8740 /* Draw the empty space below the handle. Note that we can't
8741 clear zero-height areas; that means "clear to end of window." */
8742 if (end
< inside_height
)
8743 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8744 /* x, y, width, height, and exposures. */
8745 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8746 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
8747 inside_width
, inside_height
- end
,
8755 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8757 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8761 x_scroll_bar_remove (bar
)
8762 struct scroll_bar
*bar
;
8764 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8767 #ifdef USE_TOOLKIT_SCROLL_BARS
8768 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
8770 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8773 /* Disassociate this scroll bar from its window. */
8774 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8780 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8781 that we are displaying PORTION characters out of a total of WHOLE
8782 characters, starting at POSITION. If WINDOW has no scroll bar,
8786 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8788 int portion
, whole
, position
;
8790 struct frame
*f
= XFRAME (w
->frame
);
8791 struct scroll_bar
*bar
;
8792 int top
, height
, left
, sb_left
, width
, sb_width
;
8793 int window_x
, window_y
, window_width
, window_height
;
8795 /* Get window dimensions. */
8796 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8798 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8799 height
= window_height
;
8801 /* Compute the left edge of the scroll bar area. */
8802 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8803 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8805 left
= XFASTINT (w
->left
);
8806 left
*= CANON_X_UNIT (f
);
8807 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8809 /* Compute the width of the scroll bar which might be less than
8810 the width of the area reserved for the scroll bar. */
8811 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8812 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8816 /* Compute the left edge of the scroll bar. */
8817 #ifdef USE_TOOLKIT_SCROLL_BARS
8818 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8819 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8821 sb_left
= left
+ (width
- sb_width
) / 2;
8823 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8824 sb_left
= left
+ width
- sb_width
;
8829 /* Does the scroll bar exist yet? */
8830 if (NILP (w
->vertical_scroll_bar
))
8833 if (width
&& height
)
8834 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8835 left
, top
, width
, height
, False
);
8837 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8841 /* It may just need to be moved and resized. */
8842 unsigned int mask
= 0;
8844 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8848 if (sb_left
!= XINT (bar
->left
))
8850 if (top
!= XINT (bar
->top
))
8852 if (sb_width
!= XINT (bar
->width
))
8854 if (height
!= XINT (bar
->height
))
8857 #ifdef USE_TOOLKIT_SCROLL_BARS
8859 /* Since toolkit scroll bars are smaller than the space reserved
8860 for them on the frame, we have to clear "under" them. */
8861 if (width
&& height
)
8862 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8863 left
, top
, width
, height
, False
);
8865 /* Move/size the scroll bar widget. */
8867 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
8868 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8870 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8871 max (height
, 1), 0);
8873 #else /* not USE_TOOLKIT_SCROLL_BARS */
8875 /* Clear areas not covered by the scroll bar because of
8876 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
8877 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
8879 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8880 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8882 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8883 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8884 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8888 /* Clear areas not covered by the scroll bar because it's not as
8889 wide as the area reserved for it . This makes sure a
8890 previous mode line display is cleared after C-x 2 C-x 1, for
8893 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8894 int rest
= area_width
- sb_width
;
8896 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8897 left
+ area_width
- rest
, 0,
8898 rest
, max (height
, 1), False
);
8901 /* Move/size the scroll bar window. */
8906 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
8908 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
8910 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
8914 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8916 /* Remember new settings. */
8917 XSETINT (bar
->left
, sb_left
);
8918 XSETINT (bar
->top
, top
);
8919 XSETINT (bar
->width
, sb_width
);
8920 XSETINT (bar
->height
, height
);
8925 #ifdef USE_TOOLKIT_SCROLL_BARS
8926 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
8927 #else /* not USE_TOOLKIT_SCROLL_BARS */
8928 /* Set the scroll bar's current state, unless we're currently being
8930 if (NILP (bar
->dragging
))
8932 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8935 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8938 int start
= ((double) position
* top_range
) / whole
;
8939 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8940 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8943 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8945 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8949 /* The following three hooks are used when we're doing a thorough
8950 redisplay of the frame. We don't explicitly know which scroll bars
8951 are going to be deleted, because keeping track of when windows go
8952 away is a real pain - "Can you say set-window-configuration, boys
8953 and girls?" Instead, we just assert at the beginning of redisplay
8954 that *all* scroll bars are to be removed, and then save a scroll bar
8955 from the fiery pit when we actually redisplay its window. */
8957 /* Arrange for all scroll bars on FRAME to be removed at the next call
8958 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8959 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8962 XTcondemn_scroll_bars (frame
)
8965 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8966 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8969 bar
= FRAME_SCROLL_BARS (frame
);
8970 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8971 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8972 XSCROLL_BAR (bar
)->prev
= Qnil
;
8973 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8974 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8975 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8980 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8981 Note that WINDOW isn't necessarily condemned at all. */
8984 XTredeem_scroll_bar (window
)
8985 struct window
*window
;
8987 struct scroll_bar
*bar
;
8990 /* We can't redeem this window's scroll bar if it doesn't have one. */
8991 if (NILP (window
->vertical_scroll_bar
))
8994 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8996 /* Unlink it from the condemned list. */
8997 f
= XFRAME (WINDOW_FRAME (window
));
8998 if (NILP (bar
->prev
))
9000 /* If the prev pointer is nil, it must be the first in one of
9002 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9003 /* It's not condemned. Everything's fine. */
9005 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9006 window
->vertical_scroll_bar
))
9007 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9009 /* If its prev pointer is nil, it must be at the front of
9010 one or the other! */
9014 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9016 if (! NILP (bar
->next
))
9017 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9019 bar
->next
= FRAME_SCROLL_BARS (f
);
9021 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9022 if (! NILP (bar
->next
))
9023 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9026 /* Remove all scroll bars on FRAME that haven't been saved since the
9027 last call to `*condemn_scroll_bars_hook'. */
9030 XTjudge_scroll_bars (f
)
9033 Lisp_Object bar
, next
;
9035 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9037 /* Clear out the condemned list now so we won't try to process any
9038 more events on the hapless scroll bars. */
9039 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9041 for (; ! NILP (bar
); bar
= next
)
9043 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9045 x_scroll_bar_remove (b
);
9048 b
->next
= b
->prev
= Qnil
;
9051 /* Now there should be no references to the condemned scroll bars,
9052 and they should get garbage-collected. */
9056 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9057 is a no-op when using toolkit scroll bars.
9059 This may be called from a signal handler, so we have to ignore GC
9063 x_scroll_bar_expose (bar
, event
)
9064 struct scroll_bar
*bar
;
9067 #ifndef USE_TOOLKIT_SCROLL_BARS
9069 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9070 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9071 GC gc
= f
->output_data
.x
->normal_gc
;
9072 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9076 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9078 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9079 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9081 /* x, y, width, height */
9083 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9084 XINT (bar
->height
) - 1);
9088 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9091 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9092 is set to something other than no_event, it is enqueued.
9094 This may be called from a signal handler, so we have to ignore GC
9097 #ifndef USE_TOOLKIT_SCROLL_BARS
9100 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9101 struct scroll_bar
*bar
;
9103 struct input_event
*emacs_event
;
9105 if (! GC_WINDOWP (bar
->window
))
9108 emacs_event
->kind
= scroll_bar_click
;
9109 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9110 emacs_event
->modifiers
9111 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9112 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9113 event
->xbutton
.state
)
9114 | (event
->type
== ButtonRelease
9117 emacs_event
->frame_or_window
= bar
->window
;
9118 emacs_event
->arg
= Qnil
;
9119 emacs_event
->timestamp
= event
->xbutton
.time
;
9122 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9124 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9127 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9128 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9131 if (y
> top_range
) y
= top_range
;
9133 if (y
< XINT (bar
->start
))
9134 emacs_event
->part
= scroll_bar_above_handle
;
9135 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9136 emacs_event
->part
= scroll_bar_handle
;
9138 emacs_event
->part
= scroll_bar_below_handle
;
9140 /* Just because the user has clicked on the handle doesn't mean
9141 they want to drag it. Lisp code needs to be able to decide
9142 whether or not we're dragging. */
9144 /* If the user has just clicked on the handle, record where they're
9146 if (event
->type
== ButtonPress
9147 && emacs_event
->part
== scroll_bar_handle
)
9148 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9151 /* If the user has released the handle, set it to its final position. */
9152 if (event
->type
== ButtonRelease
9153 && ! NILP (bar
->dragging
))
9155 int new_start
= y
- XINT (bar
->dragging
);
9156 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9158 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9159 bar
->dragging
= Qnil
;
9162 /* Same deal here as the other #if 0. */
9164 /* Clicks on the handle are always reported as occurring at the top of
9166 if (emacs_event
->part
== scroll_bar_handle
)
9167 emacs_event
->x
= bar
->start
;
9169 XSETINT (emacs_event
->x
, y
);
9171 XSETINT (emacs_event
->x
, y
);
9174 XSETINT (emacs_event
->y
, top_range
);
9178 /* Handle some mouse motion while someone is dragging the scroll bar.
9180 This may be called from a signal handler, so we have to ignore GC
9184 x_scroll_bar_note_movement (bar
, event
)
9185 struct scroll_bar
*bar
;
9188 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9190 last_mouse_movement_time
= event
->xmotion
.time
;
9193 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9195 /* If we're dragging the bar, display it. */
9196 if (! GC_NILP (bar
->dragging
))
9198 /* Where should the handle be now? */
9199 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9201 if (new_start
!= XINT (bar
->start
))
9203 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9205 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9210 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9212 /* Return information to the user about the current position of the mouse
9213 on the scroll bar. */
9216 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9218 Lisp_Object
*bar_window
;
9219 enum scroll_bar_part
*part
;
9221 unsigned long *time
;
9223 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9224 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9225 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9227 Window dummy_window
;
9229 unsigned int dummy_mask
;
9233 /* Get the mouse's position relative to the scroll bar window, and
9235 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9237 /* Root, child, root x and root y. */
9238 &dummy_window
, &dummy_window
,
9239 &dummy_coord
, &dummy_coord
,
9241 /* Position relative to scroll bar. */
9244 /* Mouse buttons and modifier keys. */
9251 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9254 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9256 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9258 if (! NILP (bar
->dragging
))
9259 win_y
-= XINT (bar
->dragging
);
9263 if (win_y
> top_range
)
9267 *bar_window
= bar
->window
;
9269 if (! NILP (bar
->dragging
))
9270 *part
= scroll_bar_handle
;
9271 else if (win_y
< XINT (bar
->start
))
9272 *part
= scroll_bar_above_handle
;
9273 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9274 *part
= scroll_bar_handle
;
9276 *part
= scroll_bar_below_handle
;
9278 XSETINT (*x
, win_y
);
9279 XSETINT (*y
, top_range
);
9282 last_mouse_scroll_bar
= Qnil
;
9285 *time
= last_mouse_movement_time
;
9291 /* The screen has been cleared so we may have changed foreground or
9292 background colors, and the scroll bars may need to be redrawn.
9293 Clear out the scroll bars, and ask for expose events, so we can
9297 x_scroll_bar_clear (f
)
9300 #ifndef USE_TOOLKIT_SCROLL_BARS
9303 /* We can have scroll bars even if this is 0,
9304 if we just turned off scroll bar mode.
9305 But in that case we should not clear them. */
9306 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9307 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9308 bar
= XSCROLL_BAR (bar
)->next
)
9309 XClearArea (FRAME_X_DISPLAY (f
),
9310 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9312 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9315 /* This processes Expose events from the menu-bar specific X event
9316 loop in xmenu.c. This allows to redisplay the frame if necessary
9317 when handling menu-bar or pop-up items. */
9320 process_expose_from_menu (event
)
9324 struct x_display_info
*dpyinfo
;
9325 int frame_exposed_p
= 0;
9329 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
9330 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9333 if (f
->async_visible
== 0)
9335 f
->async_visible
= 1;
9336 f
->async_iconified
= 0;
9337 f
->output_data
.x
->has_been_visible
= 1;
9338 SET_FRAME_GARBAGED (f
);
9342 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9343 event
.xexpose
.x
, event
.xexpose
.y
,
9344 event
.xexpose
.width
, event
.xexpose
.height
);
9345 frame_exposed_p
= 1;
9350 struct scroll_bar
*bar
9351 = x_window_to_scroll_bar (event
.xexpose
.window
);
9354 x_scroll_bar_expose (bar
, &event
);
9358 return frame_exposed_p
;
9361 /* Define a queue to save up SelectionRequest events for later handling. */
9363 struct selection_event_queue
9366 struct selection_event_queue
*next
;
9369 static struct selection_event_queue
*queue
;
9371 /* Nonzero means queue up certain events--don't process them yet. */
9373 static int x_queue_selection_requests
;
9375 /* Queue up an X event *EVENT, to be processed later. */
9378 x_queue_event (f
, event
)
9382 struct selection_event_queue
*queue_tmp
9383 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9385 if (queue_tmp
!= NULL
)
9387 queue_tmp
->event
= *event
;
9388 queue_tmp
->next
= queue
;
9393 /* Take all the queued events and put them back
9394 so that they get processed afresh. */
9397 x_unqueue_events (display
)
9400 while (queue
!= NULL
)
9402 struct selection_event_queue
*queue_tmp
= queue
;
9403 XPutBackEvent (display
, &queue_tmp
->event
);
9404 queue
= queue_tmp
->next
;
9405 xfree ((char *)queue_tmp
);
9409 /* Start queuing SelectionRequest events. */
9412 x_start_queuing_selection_requests (display
)
9415 x_queue_selection_requests
++;
9418 /* Stop queuing SelectionRequest events. */
9421 x_stop_queuing_selection_requests (display
)
9424 x_queue_selection_requests
--;
9425 x_unqueue_events (display
);
9428 /* The main X event-reading loop - XTread_socket. */
9430 /* Time stamp of enter window event. This is only used by XTread_socket,
9431 but we have to put it out here, since static variables within functions
9432 sometimes don't work. */
9434 static Time enter_timestamp
;
9436 /* This holds the state XLookupString needs to implement dead keys
9437 and other tricks known as "compose processing". _X Window System_
9438 says that a portable program can't use this, but Stephen Gildea assures
9439 me that letting the compiler initialize it to zeros will work okay.
9441 This must be defined outside of XTread_socket, for the same reasons
9442 given for enter_time stamp, above. */
9444 static XComposeStatus compose_status
;
9446 /* Record the last 100 characters stored
9447 to help debug the loss-of-chars-during-GC problem. */
9449 static int temp_index
;
9450 static short temp_buffer
[100];
9452 /* Set this to nonzero to fake an "X I/O error"
9453 on a particular display. */
9455 struct x_display_info
*XTread_socket_fake_io_error
;
9457 /* When we find no input here, we occasionally do a no-op command
9458 to verify that the X server is still running and we can still talk with it.
9459 We try all the open displays, one by one.
9460 This variable is used for cycling thru the displays. */
9462 static struct x_display_info
*next_noop_dpyinfo
;
9464 #define SET_SAVED_MENU_EVENT(size) \
9467 if (f->output_data.x->saved_menu_event == 0) \
9468 f->output_data.x->saved_menu_event \
9469 = (XEvent *) xmalloc (sizeof (XEvent)); \
9470 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9471 if (numchars >= 1) \
9473 bufp->kind = menu_bar_activate_event; \
9474 XSETFRAME (bufp->frame_or_window, f); \
9483 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9484 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9486 /* Read events coming from the X server.
9487 This routine is called by the SIGIO handler.
9488 We return as soon as there are no more events to be read.
9490 Events representing keys are stored in buffer BUFP,
9491 which can hold up to NUMCHARS characters.
9492 We return the number of characters stored into the buffer,
9493 thus pretending to be `read'.
9495 EXPECTED is nonzero if the caller knows input is available. */
9498 XTread_socket (sd
, bufp
, numchars
, expected
)
9500 /* register */ struct input_event
*bufp
;
9501 /* register */ int numchars
;
9508 int event_found
= 0;
9509 struct x_display_info
*dpyinfo
;
9510 struct coding_system coding
;
9512 if (interrupt_input_blocked
)
9514 interrupt_input_pending
= 1;
9518 interrupt_input_pending
= 0;
9521 /* So people can tell when we have read the available input. */
9522 input_signal_count
++;
9525 abort (); /* Don't think this happens. */
9529 /* The input should be decoded if it is from XIM. Currently the
9530 locale of XIM is the same as that of the system. So, we can use
9531 Vlocale_coding_system which is initialized properly at Emacs
9533 setup_coding_system (Vlocale_coding_system
, &coding
);
9534 coding
.src_multibyte
= 0;
9535 coding
.dst_multibyte
= 1;
9536 /* The input is converted to events, thus we can't handle
9537 composition. Anyway, there's no XIM that gives us composition
9539 coding
.composing
= COMPOSITION_DISABLED
;
9541 /* Find the display we are supposed to read input for.
9542 It's the one communicating on descriptor SD. */
9543 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9545 #if 0 /* This ought to be unnecessary; let's verify it. */
9547 /* If available, Xlib uses FIOSNBIO to make the socket
9548 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9549 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9550 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9551 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9552 #endif /* ! defined (FIOSNBIO) */
9555 #if 0 /* This code can't be made to work, with multiple displays,
9556 and appears not to be used on any system any more.
9557 Also keyboard.c doesn't turn O_NDELAY on and off
9558 for X connections. */
9561 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9563 extern int read_alarm_should_throw
;
9564 read_alarm_should_throw
= 1;
9565 XPeekEvent (dpyinfo
->display
, &event
);
9566 read_alarm_should_throw
= 0;
9568 #endif /* HAVE_SELECT */
9572 /* For debugging, this gives a way to fake an I/O error. */
9573 if (dpyinfo
== XTread_socket_fake_io_error
)
9575 XTread_socket_fake_io_error
= 0;
9576 x_io_error_quitter (dpyinfo
->display
);
9579 while (XPending (dpyinfo
->display
))
9581 XNextEvent (dpyinfo
->display
, &event
);
9585 /* Filter events for the current X input method.
9586 XFilterEvent returns non-zero if the input method has
9587 consumed the event. We pass the frame's X window to
9588 XFilterEvent because that's the one for which the IC
9590 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9591 event
.xclient
.window
);
9592 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9602 if (event
.xclient
.message_type
9603 == dpyinfo
->Xatom_wm_protocols
9604 && event
.xclient
.format
== 32)
9606 if (event
.xclient
.data
.l
[0]
9607 == dpyinfo
->Xatom_wm_take_focus
)
9609 /* Use x_any_window_to_frame because this
9610 could be the shell widget window
9611 if the frame has no title bar. */
9612 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9614 /* Not quite sure this is needed -pd */
9615 if (f
&& FRAME_XIC (f
))
9616 XSetICFocus (FRAME_XIC (f
));
9618 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
9619 instructs the WM to set the input focus automatically for
9620 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
9621 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
9622 it has set the focus. So, XSetInputFocus below is not
9625 The call to XSetInputFocus below has also caused trouble. In
9626 cases where the XSetInputFocus done by the WM and the one
9627 below are temporally close (on a fast machine), the call
9628 below can generate additional FocusIn events which confuse
9631 /* Since we set WM_TAKE_FOCUS, we must call
9632 XSetInputFocus explicitly. But not if f is null,
9633 since that might be an event for a deleted frame. */
9636 Display
*d
= event
.xclient
.display
;
9637 /* Catch and ignore errors, in case window has been
9638 iconified by a window manager such as GWM. */
9639 int count
= x_catch_errors (d
);
9640 XSetInputFocus (d
, event
.xclient
.window
,
9641 /* The ICCCM says this is
9642 the only valid choice. */
9644 event
.xclient
.data
.l
[1]);
9645 /* This is needed to detect the error
9646 if there is an error. */
9648 x_uncatch_errors (d
, count
);
9650 /* Not certain about handling scroll bars here */
9653 else if (event
.xclient
.data
.l
[0]
9654 == dpyinfo
->Xatom_wm_save_yourself
)
9656 /* Save state modify the WM_COMMAND property to
9657 something which can reinstate us. This notifies
9658 the session manager, who's looking for such a
9659 PropertyNotify. Can restart processing when
9660 a keyboard or mouse event arrives. */
9663 f
= x_top_window_to_frame (dpyinfo
,
9664 event
.xclient
.window
);
9666 /* This is just so we only give real data once
9667 for a single Emacs process. */
9668 if (f
== SELECTED_FRAME ())
9669 XSetCommand (FRAME_X_DISPLAY (f
),
9670 event
.xclient
.window
,
9671 initial_argv
, initial_argc
);
9673 XSetCommand (FRAME_X_DISPLAY (f
),
9674 event
.xclient
.window
,
9678 else if (event
.xclient
.data
.l
[0]
9679 == dpyinfo
->Xatom_wm_delete_window
)
9682 = x_any_window_to_frame (dpyinfo
,
9683 event
.xclient
.window
);
9690 bufp
->kind
= delete_window_event
;
9691 XSETFRAME (bufp
->frame_or_window
, f
);
9700 else if (event
.xclient
.message_type
9701 == dpyinfo
->Xatom_wm_configure_denied
)
9704 else if (event
.xclient
.message_type
9705 == dpyinfo
->Xatom_wm_window_moved
)
9709 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9711 new_x
= event
.xclient
.data
.s
[0];
9712 new_y
= event
.xclient
.data
.s
[1];
9716 f
->output_data
.x
->left_pos
= new_x
;
9717 f
->output_data
.x
->top_pos
= new_y
;
9721 else if (event
.xclient
.message_type
9722 == dpyinfo
->Xatom_editres
)
9725 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9726 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
9729 #endif /* HACK_EDITRES */
9730 else if ((event
.xclient
.message_type
9731 == dpyinfo
->Xatom_DONE
)
9732 || (event
.xclient
.message_type
9733 == dpyinfo
->Xatom_PAGE
))
9735 /* Ghostview job completed. Kill it. We could
9736 reply with "Next" if we received "Page", but we
9737 currently never do because we are interested in
9738 images, only, which should have 1 page. */
9739 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
9741 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9742 x_kill_gs_process (pixmap
, f
);
9743 expose_frame (f
, 0, 0, 0, 0);
9745 #ifdef USE_TOOLKIT_SCROLL_BARS
9746 /* Scroll bar callbacks send a ClientMessage from which
9747 we construct an input_event. */
9748 else if (event
.xclient
.message_type
9749 == dpyinfo
->Xatom_Scrollbar
)
9751 x_scroll_bar_to_input_event (&event
, bufp
);
9752 ++bufp
, ++count
, --numchars
;
9755 #endif /* USE_TOOLKIT_SCROLL_BARS */
9761 case SelectionNotify
:
9762 #ifdef USE_X_TOOLKIT
9763 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
9765 #endif /* not USE_X_TOOLKIT */
9766 x_handle_selection_notify (&event
.xselection
);
9769 case SelectionClear
: /* Someone has grabbed ownership. */
9770 #ifdef USE_X_TOOLKIT
9771 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
9773 #endif /* USE_X_TOOLKIT */
9775 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
9780 bufp
->kind
= selection_clear_event
;
9781 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9782 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9783 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9784 bufp
->frame_or_window
= Qnil
;
9793 case SelectionRequest
: /* Someone wants our selection. */
9794 #ifdef USE_X_TOOLKIT
9795 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
9797 #endif /* USE_X_TOOLKIT */
9798 if (x_queue_selection_requests
)
9799 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
9803 XSelectionRequestEvent
*eventp
= (XSelectionRequestEvent
*) &event
;
9808 bufp
->kind
= selection_request_event
;
9809 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9810 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
9811 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9812 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
9813 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
9814 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9815 bufp
->frame_or_window
= Qnil
;
9824 case PropertyNotify
:
9825 #ifdef USE_X_TOOLKIT
9826 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
9828 #endif /* not USE_X_TOOLKIT */
9829 x_handle_property_notify (&event
.xproperty
);
9832 case ReparentNotify
:
9833 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
9837 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
9838 x_real_positions (f
, &x
, &y
);
9839 f
->output_data
.x
->left_pos
= x
;
9840 f
->output_data
.x
->top_pos
= y
;
9845 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9848 if (f
->async_visible
== 0)
9850 f
->async_visible
= 1;
9851 f
->async_iconified
= 0;
9852 f
->output_data
.x
->has_been_visible
= 1;
9853 SET_FRAME_GARBAGED (f
);
9856 expose_frame (x_window_to_frame (dpyinfo
,
9857 event
.xexpose
.window
),
9858 event
.xexpose
.x
, event
.xexpose
.y
,
9859 event
.xexpose
.width
, event
.xexpose
.height
);
9863 #ifdef USE_TOOLKIT_SCROLL_BARS
9864 /* Dispatch event to the widget. */
9866 #else /* not USE_TOOLKIT_SCROLL_BARS */
9867 struct scroll_bar
*bar
9868 = x_window_to_scroll_bar (event
.xexpose
.window
);
9871 x_scroll_bar_expose (bar
, &event
);
9872 #ifdef USE_X_TOOLKIT
9875 #endif /* USE_X_TOOLKIT */
9876 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9880 case GraphicsExpose
: /* This occurs when an XCopyArea's
9881 source area was obscured or not
9883 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
9887 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
9888 event
.xgraphicsexpose
.width
,
9889 event
.xgraphicsexpose
.height
);
9891 #ifdef USE_X_TOOLKIT
9894 #endif /* USE_X_TOOLKIT */
9897 case NoExpose
: /* This occurs when an XCopyArea's
9898 source area was completely
9903 /* Redo the mouse-highlight after the tooltip has gone. */
9904 if (event
.xmap
.window
== tip_window
)
9907 redo_mouse_highlight ();
9910 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
9911 if (f
) /* F may no longer exist if
9912 the frame was deleted. */
9914 /* While a frame is unmapped, display generation is
9915 disabled; you don't want to spend time updating a
9916 display that won't ever be seen. */
9917 f
->async_visible
= 0;
9918 /* We can't distinguish, from the event, whether the window
9919 has become iconified or invisible. So assume, if it
9920 was previously visible, than now it is iconified.
9921 But x_make_frame_invisible clears both
9922 the visible flag and the iconified flag;
9923 and that way, we know the window is not iconified now. */
9924 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
9926 f
->async_iconified
= 1;
9928 bufp
->kind
= iconify_event
;
9929 XSETFRAME (bufp
->frame_or_window
, f
);
9939 if (event
.xmap
.window
== tip_window
)
9940 /* The tooltip has been drawn already. Avoid
9941 the SET_FRAME_GARBAGED below. */
9944 /* We use x_top_window_to_frame because map events can
9945 come for sub-windows and they don't mean that the
9946 frame is visible. */
9947 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
9950 f
->async_visible
= 1;
9951 f
->async_iconified
= 0;
9952 f
->output_data
.x
->has_been_visible
= 1;
9954 /* wait_reading_process_input will notice this and update
9955 the frame's display structures. */
9956 SET_FRAME_GARBAGED (f
);
9960 bufp
->kind
= deiconify_event
;
9961 XSETFRAME (bufp
->frame_or_window
, f
);
9967 else if (! NILP (Vframe_list
)
9968 && ! NILP (XCDR (Vframe_list
)))
9969 /* Force a redisplay sooner or later
9970 to update the frame titles
9971 in case this is the second frame. */
9972 record_asynch_buffer_change ();
9977 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
9979 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
9982 /* Scroll bars consume key events, but we want
9983 the keys to go to the scroll bar's frame. */
9984 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
9986 if (widget
&& XmIsScrollBar (widget
))
9988 widget
= XtParent (widget
);
9989 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
9992 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
9996 KeySym keysym
, orig_keysym
;
9997 /* al%imercury@uunet.uu.net says that making this 81
9998 instead of 80 fixed a bug whereby meta chars made
10001 It seems that some version of XmbLookupString has
10002 a bug of not returning XBufferOverflow in
10003 status_return even if the input is too long to
10004 fit in 81 bytes. So, we must prepare sufficient
10005 bytes for copy_buffer. 513 bytes (256 chars for
10006 two-byte character set) seems to be a faily good
10007 approximation. -- 2000.8.10 handa@etl.go.jp */
10008 unsigned char copy_buffer
[513];
10009 unsigned char *copy_bufptr
= copy_buffer
;
10010 int copy_bufsiz
= sizeof (copy_buffer
);
10014 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10015 extra_keyboard_modifiers
);
10016 modifiers
= event
.xkey
.state
;
10018 /* This will have to go some day... */
10020 /* make_lispy_event turns chars into control chars.
10021 Don't do it here because XLookupString is too eager. */
10022 event
.xkey
.state
&= ~ControlMask
;
10023 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10024 | dpyinfo
->super_mod_mask
10025 | dpyinfo
->hyper_mod_mask
10026 | dpyinfo
->alt_mod_mask
);
10028 /* In case Meta is ComposeCharacter,
10029 clear its status. According to Markus Ehrnsperger
10030 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10031 this enables ComposeCharacter to work whether or
10032 not it is combined with Meta. */
10033 if (modifiers
& dpyinfo
->meta_mod_mask
)
10034 bzero (&compose_status
, sizeof (compose_status
));
10039 Status status_return
;
10041 nbytes
= XmbLookupString (FRAME_XIC (f
),
10042 &event
.xkey
, copy_bufptr
,
10043 copy_bufsiz
, &keysym
,
10045 if (status_return
== XBufferOverflow
)
10047 copy_bufsiz
= nbytes
+ 1;
10048 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10049 nbytes
= XmbLookupString (FRAME_XIC (f
),
10050 &event
.xkey
, copy_bufptr
,
10051 copy_bufsiz
, &keysym
,
10055 if (status_return
== XLookupNone
)
10057 else if (status_return
== XLookupChars
)
10062 else if (status_return
!= XLookupKeySym
10063 && status_return
!= XLookupBoth
)
10067 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10068 copy_bufsiz
, &keysym
,
10071 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10072 copy_bufsiz
, &keysym
,
10076 orig_keysym
= keysym
;
10080 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10081 || keysym
== XK_Delete
10082 #ifdef XK_ISO_Left_Tab
10083 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
10085 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
10086 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10087 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10089 /* This recognizes the "extended function keys".
10090 It seems there's no cleaner way.
10091 Test IsModifierKey to avoid handling mode_switch
10093 || ((unsigned) (keysym
) >= XK_Select
10094 && (unsigned)(keysym
) < XK_KP_Space
)
10096 #ifdef XK_dead_circumflex
10097 || orig_keysym
== XK_dead_circumflex
10099 #ifdef XK_dead_grave
10100 || orig_keysym
== XK_dead_grave
10102 #ifdef XK_dead_tilde
10103 || orig_keysym
== XK_dead_tilde
10105 #ifdef XK_dead_diaeresis
10106 || orig_keysym
== XK_dead_diaeresis
10108 #ifdef XK_dead_macron
10109 || orig_keysym
== XK_dead_macron
10111 #ifdef XK_dead_degree
10112 || orig_keysym
== XK_dead_degree
10114 #ifdef XK_dead_acute
10115 || orig_keysym
== XK_dead_acute
10117 #ifdef XK_dead_cedilla
10118 || orig_keysym
== XK_dead_cedilla
10120 #ifdef XK_dead_breve
10121 || orig_keysym
== XK_dead_breve
10123 #ifdef XK_dead_ogonek
10124 || orig_keysym
== XK_dead_ogonek
10126 #ifdef XK_dead_caron
10127 || orig_keysym
== XK_dead_caron
10129 #ifdef XK_dead_doubleacute
10130 || orig_keysym
== XK_dead_doubleacute
10132 #ifdef XK_dead_abovedot
10133 || orig_keysym
== XK_dead_abovedot
10135 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10136 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10137 /* Any "vendor-specific" key is ok. */
10138 || (orig_keysym
& (1 << 28)))
10139 && ! (IsModifierKey (orig_keysym
)
10141 #ifdef XK_Mode_switch
10142 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10145 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10147 #endif /* not HAVE_X11R5 */
10150 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10152 temp_buffer
[temp_index
++] = keysym
;
10153 bufp
->kind
= non_ascii_keystroke
;
10154 bufp
->code
= keysym
;
10155 XSETFRAME (bufp
->frame_or_window
, f
);
10158 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10160 bufp
->timestamp
= event
.xkey
.time
;
10165 else if (numchars
> nbytes
)
10171 for (i
= 0; i
< nbytes
; i
++)
10173 if (temp_index
== (sizeof temp_buffer
10176 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10179 if (/* If the event is not from XIM, */
10180 event
.xkey
.keycode
!= 0
10181 /* or the current locale doesn't request
10182 decoding of the intup data, ... */
10183 || coding
.type
== coding_type_raw_text
10184 || coding
.type
== coding_type_no_conversion
)
10186 /* ... we can use the input data as is. */
10191 /* We have to decode the input data. */
10195 require
= decoding_buffer_size (&coding
, nbytes
);
10196 p
= (unsigned char *) alloca (require
);
10197 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10198 decode_coding (&coding
, copy_bufptr
, p
,
10200 nbytes
= coding
.produced
;
10201 nchars
= coding
.produced_char
;
10205 /* Convert the input data to a sequence of
10206 character events. */
10207 for (i
= 0; i
< nbytes
; i
+= len
)
10209 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10211 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10213 : multibyte_char_keystroke
);
10215 XSETFRAME (bufp
->frame_or_window
, f
);
10218 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10220 bufp
->timestamp
= event
.xkey
.time
;
10225 numchars
-= nchars
;
10227 if (keysym
== NoSymbol
)
10237 /* Don't dispatch this event since XtDispatchEvent calls
10238 XFilterEvent, and two calls in a row may freeze the
10247 /* Don't dispatch this event since XtDispatchEvent calls
10248 XFilterEvent, and two calls in a row may freeze the
10255 /* Here's a possible interpretation of the whole
10256 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10257 you get a FocusIn event, you have to get a FocusOut
10258 event before you relinquish the focus. If you
10259 haven't received a FocusIn event, then a mere
10260 LeaveNotify is enough to free you. */
10264 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10266 if (event
.xcrossing
.focus
)
10268 /* Avoid nasty pop/raise loops. */
10269 if (f
&& (!(f
->auto_raise
)
10270 || !(f
->auto_lower
)
10271 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10273 x_new_focus_frame (dpyinfo
, f
);
10274 enter_timestamp
= event
.xcrossing
.time
;
10277 else if (f
== dpyinfo
->x_focus_frame
)
10278 x_new_focus_frame (dpyinfo
, 0);
10280 /* EnterNotify counts as mouse movement,
10281 so update things that depend on mouse position. */
10282 if (f
&& !f
->output_data
.x
->hourglass_p
)
10283 note_mouse_movement (f
, &event
.xmotion
);
10288 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10289 if (event
.xfocus
.detail
!= NotifyPointer
)
10290 dpyinfo
->x_focus_event_frame
= f
;
10293 x_new_focus_frame (dpyinfo
, f
);
10295 /* Don't stop displaying the initial startup message
10296 for a switch-frame event we don't need. */
10297 if (GC_NILP (Vterminal_frame
)
10298 && GC_CONSP (Vframe_list
)
10299 && !GC_NILP (XCDR (Vframe_list
)))
10301 bufp
->kind
= FOCUS_IN_EVENT
;
10302 XSETFRAME (bufp
->frame_or_window
, f
);
10304 ++bufp
, ++count
, --numchars
;
10309 if (f
&& FRAME_XIC (f
))
10310 XSetICFocus (FRAME_XIC (f
));
10316 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10319 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10321 /* If we move outside the frame, then we're
10322 certainly no longer on any text in the frame. */
10323 clear_mouse_face (dpyinfo
);
10324 dpyinfo
->mouse_face_mouse_frame
= 0;
10327 /* Generate a nil HELP_EVENT to cancel a help-echo.
10328 Do it only if there's something to cancel.
10329 Otherwise, the startup message is cleared when
10330 the mouse leaves the frame. */
10331 if (any_help_event_p
)
10336 XSETFRAME (frame
, f
);
10338 n
= gen_help_event (bufp
, numchars
,
10339 Qnil
, frame
, Qnil
, Qnil
, 0);
10340 bufp
+= n
, count
+= n
, numchars
-= n
;
10343 if (event
.xcrossing
.focus
)
10344 x_mouse_leave (dpyinfo
);
10347 if (f
== dpyinfo
->x_focus_event_frame
)
10348 dpyinfo
->x_focus_event_frame
= 0;
10349 if (f
== dpyinfo
->x_focus_frame
)
10350 x_new_focus_frame (dpyinfo
, 0);
10356 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10357 if (event
.xfocus
.detail
!= NotifyPointer
10358 && f
== dpyinfo
->x_focus_event_frame
)
10359 dpyinfo
->x_focus_event_frame
= 0;
10360 if (f
&& f
== dpyinfo
->x_focus_frame
)
10361 x_new_focus_frame (dpyinfo
, 0);
10364 if (f
&& FRAME_XIC (f
))
10365 XUnsetICFocus (FRAME_XIC (f
));
10372 previous_help_echo
= help_echo
;
10373 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10374 help_echo_pos
= -1;
10376 if (dpyinfo
->grabbed
&& last_mouse_frame
10377 && FRAME_LIVE_P (last_mouse_frame
))
10378 f
= last_mouse_frame
;
10380 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10383 note_mouse_movement (f
, &event
.xmotion
);
10386 #ifndef USE_TOOLKIT_SCROLL_BARS
10387 struct scroll_bar
*bar
10388 = x_window_to_scroll_bar (event
.xmotion
.window
);
10391 x_scroll_bar_note_movement (bar
, &event
);
10392 #endif /* USE_TOOLKIT_SCROLL_BARS */
10394 /* If we move outside the frame, then we're
10395 certainly no longer on any text in the frame. */
10396 clear_mouse_face (dpyinfo
);
10399 /* If the contents of the global variable help_echo
10400 has changed, generate a HELP_EVENT. */
10401 if (!NILP (help_echo
)
10402 || !NILP (previous_help_echo
))
10408 XSETFRAME (frame
, f
);
10412 any_help_event_p
= 1;
10413 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10414 help_echo_window
, help_echo_object
,
10416 bufp
+= n
, count
+= n
, numchars
-= n
;
10422 case ConfigureNotify
:
10423 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10426 #ifndef USE_X_TOOLKIT
10427 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10428 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10430 /* In the toolkit version, change_frame_size
10431 is called by the code that handles resizing
10432 of the EmacsFrame widget. */
10434 /* Even if the number of character rows and columns has
10435 not changed, the font size may have changed, so we need
10436 to check the pixel dimensions as well. */
10437 if (columns
!= f
->width
10438 || rows
!= f
->height
10439 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10440 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10442 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10443 SET_FRAME_GARBAGED (f
);
10444 cancel_mouse_face (f
);
10448 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10449 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10451 /* What we have now is the position of Emacs's own window.
10452 Convert that to the position of the window manager window. */
10453 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10454 &f
->output_data
.x
->top_pos
);
10457 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10458 xic_set_statusarea (f
);
10461 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10463 /* Since the WM decorations come below top_pos now,
10464 we must put them below top_pos in the future. */
10465 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10466 x_wm_set_size_hint (f
, (long) 0, 0);
10469 /* Some window managers pass (0,0) as the location of
10470 the window, and the Motif event handler stores it
10471 in the emacs widget, which messes up Motif menus. */
10472 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10474 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10475 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10477 #endif /* USE_MOTIF */
10482 case ButtonRelease
:
10484 /* If we decide we want to generate an event to be seen
10485 by the rest of Emacs, we put it here. */
10486 struct input_event emacs_event
;
10487 int tool_bar_p
= 0;
10489 emacs_event
.kind
= no_event
;
10490 bzero (&compose_status
, sizeof (compose_status
));
10492 if (dpyinfo
->grabbed
10493 && last_mouse_frame
10494 && FRAME_LIVE_P (last_mouse_frame
))
10495 f
= last_mouse_frame
;
10497 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10501 /* Is this in the tool-bar? */
10502 if (WINDOWP (f
->tool_bar_window
)
10503 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10505 Lisp_Object window
;
10508 x
= event
.xbutton
.x
;
10509 y
= event
.xbutton
.y
;
10512 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10513 if (EQ (window
, f
->tool_bar_window
))
10515 x_handle_tool_bar_click (f
, &event
.xbutton
);
10521 if (!dpyinfo
->x_focus_frame
10522 || f
== dpyinfo
->x_focus_frame
)
10523 construct_mouse_click (&emacs_event
, &event
, f
);
10527 #ifndef USE_TOOLKIT_SCROLL_BARS
10528 struct scroll_bar
*bar
10529 = x_window_to_scroll_bar (event
.xbutton
.window
);
10532 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10533 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10536 if (event
.type
== ButtonPress
)
10538 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10539 last_mouse_frame
= f
;
10540 /* Ignore any mouse motion that happened
10541 before this event; any subsequent mouse-movement
10542 Emacs events should reflect only motion after
10543 the ButtonPress. */
10545 f
->mouse_moved
= 0;
10548 last_tool_bar_item
= -1;
10552 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10555 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10557 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10563 #ifdef USE_X_TOOLKIT
10564 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10565 /* For a down-event in the menu bar,
10566 don't pass it to Xt right now.
10567 Instead, save it away
10568 and we will pass it to Xt from kbd_buffer_get_event.
10569 That way, we can run some Lisp code first. */
10570 if (f
&& event
.type
== ButtonPress
10571 /* Verify the event is really within the menu bar
10572 and not just sent to it due to grabbing. */
10573 && event
.xbutton
.x
>= 0
10574 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10575 && event
.xbutton
.y
>= 0
10576 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10577 && event
.xbutton
.same_screen
)
10579 SET_SAVED_BUTTON_EVENT
;
10580 XSETFRAME (last_mouse_press_frame
, f
);
10582 else if (event
.type
== ButtonPress
)
10584 last_mouse_press_frame
= Qnil
;
10588 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10589 but I am trying to be cautious. */
10590 else if (event
.type
== ButtonRelease
)
10592 if (!NILP (last_mouse_press_frame
))
10594 f
= XFRAME (last_mouse_press_frame
);
10595 if (f
->output_data
.x
)
10596 SET_SAVED_BUTTON_EVENT
;
10601 #endif /* USE_MOTIF */
10604 #endif /* USE_X_TOOLKIT */
10608 case CirculateNotify
:
10611 case CirculateRequest
:
10614 case VisibilityNotify
:
10617 case MappingNotify
:
10618 /* Someone has changed the keyboard mapping - update the
10620 switch (event
.xmapping
.request
)
10622 case MappingModifier
:
10623 x_find_modifier_meanings (dpyinfo
);
10624 /* This is meant to fall through. */
10625 case MappingKeyboard
:
10626 XRefreshKeyboardMapping (&event
.xmapping
);
10632 #ifdef USE_X_TOOLKIT
10634 XtDispatchEvent (&event
);
10636 #endif /* USE_X_TOOLKIT */
10644 /* On some systems, an X bug causes Emacs to get no more events
10645 when the window is destroyed. Detect that. (1994.) */
10648 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
10649 One XNOOP in 100 loops will make Emacs terminate.
10650 B. Bretthauer, 1994 */
10652 if (x_noop_count
>= 100)
10656 if (next_noop_dpyinfo
== 0)
10657 next_noop_dpyinfo
= x_display_list
;
10659 XNoOp (next_noop_dpyinfo
->display
);
10661 /* Each time we get here, cycle through the displays now open. */
10662 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
10666 /* If the focus was just given to an auto-raising frame,
10668 /* ??? This ought to be able to handle more than one such frame. */
10669 if (pending_autoraise_frame
)
10671 x_raise_frame (pending_autoraise_frame
);
10672 pending_autoraise_frame
= 0;
10683 /***********************************************************************
10685 ***********************************************************************/
10687 /* Note if the text cursor of window W has been overwritten by a
10688 drawing operation that outputs N glyphs starting at HPOS in the
10689 line given by output_cursor.vpos. N < 0 means all the rest of the
10690 line after HPOS has been written. */
10693 note_overwritten_text_cursor (w
, hpos
, n
)
10697 if (updated_area
== TEXT_AREA
10698 && output_cursor
.vpos
== w
->phys_cursor
.vpos
10699 && hpos
<= w
->phys_cursor
.hpos
10701 || hpos
+ n
> w
->phys_cursor
.hpos
))
10702 w
->phys_cursor_on_p
= 0;
10706 /* Set clipping for output in glyph row ROW. W is the window in which
10707 we operate. GC is the graphics context to set clipping in.
10708 WHOLE_LINE_P non-zero means include the areas used for truncation
10709 mark display and alike in the clipping rectangle.
10711 ROW may be a text row or, e.g., a mode line. Text rows must be
10712 clipped to the interior of the window dedicated to text display,
10713 mode lines must be clipped to the whole window. */
10716 x_clip_to_row (w
, row
, gc
, whole_line_p
)
10718 struct glyph_row
*row
;
10722 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10723 XRectangle clip_rect
;
10724 int window_x
, window_y
, window_width
, window_height
;
10726 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
10728 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
10729 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
10730 clip_rect
.y
= max (clip_rect
.y
, window_y
);
10731 clip_rect
.width
= window_width
;
10732 clip_rect
.height
= row
->visible_height
;
10734 /* If clipping to the whole line, including trunc marks, extend
10735 the rectangle to the left and increase its width. */
10738 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
10739 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
10742 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
10746 /* Draw a hollow box cursor on window W in glyph row ROW. */
10749 x_draw_hollow_cursor (w
, row
)
10751 struct glyph_row
*row
;
10753 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10754 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10755 Display
*dpy
= FRAME_X_DISPLAY (f
);
10758 struct glyph
*cursor_glyph
;
10761 /* Compute frame-relative coordinates from window-relative
10763 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10764 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
10765 + row
->ascent
- w
->phys_cursor_ascent
);
10766 h
= row
->height
- 1;
10768 /* Get the glyph the cursor is on. If we can't tell because
10769 the current matrix is invalid or such, give up. */
10770 cursor_glyph
= get_phys_cursor_glyph (w
);
10771 if (cursor_glyph
== NULL
)
10774 /* Compute the width of the rectangle to draw. If on a stretch
10775 glyph, and `x-stretch-block-cursor' is nil, don't draw a
10776 rectangle as wide as the glyph, but use a canonical character
10778 wd
= cursor_glyph
->pixel_width
- 1;
10779 if (cursor_glyph
->type
== STRETCH_GLYPH
10780 && !x_stretch_cursor_p
)
10781 wd
= min (CANON_X_UNIT (f
), wd
);
10783 /* The foreground of cursor_gc is typically the same as the normal
10784 background color, which can cause the cursor box to be invisible. */
10785 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10786 if (dpyinfo
->scratch_cursor_gc
)
10787 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
10789 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
10790 GCForeground
, &xgcv
);
10791 gc
= dpyinfo
->scratch_cursor_gc
;
10793 /* Set clipping, draw the rectangle, and reset clipping again. */
10794 x_clip_to_row (w
, row
, gc
, 0);
10795 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
10796 XSetClipMask (dpy
, gc
, None
);
10800 /* Draw a bar cursor on window W in glyph row ROW.
10802 Implementation note: One would like to draw a bar cursor with an
10803 angle equal to the one given by the font property XA_ITALIC_ANGLE.
10804 Unfortunately, I didn't find a font yet that has this property set.
10808 x_draw_bar_cursor (w
, row
, width
)
10810 struct glyph_row
*row
;
10813 struct frame
*f
= XFRAME (w
->frame
);
10814 struct glyph
*cursor_glyph
;
10817 unsigned long mask
;
10822 /* If cursor is out of bounds, don't draw garbage. This can happen
10823 in mini-buffer windows when switching between echo area glyphs
10824 and mini-buffer. */
10825 cursor_glyph
= get_phys_cursor_glyph (w
);
10826 if (cursor_glyph
== NULL
)
10829 /* If on an image, draw like a normal cursor. That's usually better
10830 visible than drawing a bar, esp. if the image is large so that
10831 the bar might not be in the window. */
10832 if (cursor_glyph
->type
== IMAGE_GLYPH
)
10834 struct glyph_row
*row
;
10835 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
10836 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
10840 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
10841 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10842 xgcv
.graphics_exposures
= 0;
10843 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
10844 dpy
= FRAME_X_DISPLAY (f
);
10845 window
= FRAME_X_WINDOW (f
);
10846 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
10849 XChangeGC (dpy
, gc
, mask
, &xgcv
);
10852 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
10853 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
10857 width
= f
->output_data
.x
->cursor_width
;
10859 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10860 x_clip_to_row (w
, row
, gc
, 0);
10861 XFillRectangle (dpy
, window
, gc
,
10863 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
10864 min (cursor_glyph
->pixel_width
, width
),
10866 XSetClipMask (dpy
, gc
, None
);
10871 /* Clear the cursor of window W to background color, and mark the
10872 cursor as not shown. This is used when the text where the cursor
10873 is is about to be rewritten. */
10879 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
10880 x_update_window_cursor (w
, 0);
10884 /* Draw the cursor glyph of window W in glyph row ROW. See the
10885 comment of x_draw_glyphs for the meaning of HL. */
10888 x_draw_phys_cursor_glyph (w
, row
, hl
)
10890 struct glyph_row
*row
;
10891 enum draw_glyphs_face hl
;
10893 /* If cursor hpos is out of bounds, don't draw garbage. This can
10894 happen in mini-buffer windows when switching between echo area
10895 glyphs and mini-buffer. */
10896 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
10898 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
10899 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
10902 /* When we erase the cursor, and ROW is overlapped by other
10903 rows, make sure that these overlapping parts of other rows
10905 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
10907 if (row
> w
->current_matrix
->rows
10908 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
10909 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
10911 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
10912 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
10913 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
10919 /* Erase the image of a cursor of window W from the screen. */
10922 x_erase_phys_cursor (w
)
10925 struct frame
*f
= XFRAME (w
->frame
);
10926 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10927 int hpos
= w
->phys_cursor
.hpos
;
10928 int vpos
= w
->phys_cursor
.vpos
;
10929 int mouse_face_here_p
= 0;
10930 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
10931 struct glyph_row
*cursor_row
;
10932 struct glyph
*cursor_glyph
;
10933 enum draw_glyphs_face hl
;
10935 /* No cursor displayed or row invalidated => nothing to do on the
10937 if (w
->phys_cursor_type
== NO_CURSOR
)
10938 goto mark_cursor_off
;
10940 /* VPOS >= active_glyphs->nrows means that window has been resized.
10941 Don't bother to erase the cursor. */
10942 if (vpos
>= active_glyphs
->nrows
)
10943 goto mark_cursor_off
;
10945 /* If row containing cursor is marked invalid, there is nothing we
10947 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
10948 if (!cursor_row
->enabled_p
)
10949 goto mark_cursor_off
;
10951 /* This can happen when the new row is shorter than the old one.
10952 In this case, either x_draw_glyphs or clear_end_of_line
10953 should have cleared the cursor. Note that we wouldn't be
10954 able to erase the cursor in this case because we don't have a
10955 cursor glyph at hand. */
10956 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
10957 goto mark_cursor_off
;
10959 /* If the cursor is in the mouse face area, redisplay that when
10960 we clear the cursor. */
10961 if (! NILP (dpyinfo
->mouse_face_window
)
10962 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
10963 && (vpos
> dpyinfo
->mouse_face_beg_row
10964 || (vpos
== dpyinfo
->mouse_face_beg_row
10965 && hpos
>= dpyinfo
->mouse_face_beg_col
))
10966 && (vpos
< dpyinfo
->mouse_face_end_row
10967 || (vpos
== dpyinfo
->mouse_face_end_row
10968 && hpos
< dpyinfo
->mouse_face_end_col
))
10969 /* Don't redraw the cursor's spot in mouse face if it is at the
10970 end of a line (on a newline). The cursor appears there, but
10971 mouse highlighting does not. */
10972 && cursor_row
->used
[TEXT_AREA
] > hpos
)
10973 mouse_face_here_p
= 1;
10975 /* Maybe clear the display under the cursor. */
10976 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
10979 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10981 cursor_glyph
= get_phys_cursor_glyph (w
);
10982 if (cursor_glyph
== NULL
)
10983 goto mark_cursor_off
;
10985 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
10987 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10989 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
10991 cursor_glyph
->pixel_width
,
10992 cursor_row
->visible_height
,
10996 /* Erase the cursor by redrawing the character underneath it. */
10997 if (mouse_face_here_p
)
10998 hl
= DRAW_MOUSE_FACE
;
10999 else if (cursor_row
->inverse_p
)
11000 hl
= DRAW_INVERSE_VIDEO
;
11002 hl
= DRAW_NORMAL_TEXT
;
11003 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11006 w
->phys_cursor_on_p
= 0;
11007 w
->phys_cursor_type
= NO_CURSOR
;
11011 /* Display or clear cursor of window W. If ON is zero, clear the
11012 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11013 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11016 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11018 int on
, hpos
, vpos
, x
, y
;
11020 struct frame
*f
= XFRAME (w
->frame
);
11021 int new_cursor_type
;
11022 int new_cursor_width
;
11023 struct glyph_matrix
*current_glyphs
;
11024 struct glyph_row
*glyph_row
;
11025 struct glyph
*glyph
;
11027 /* This is pointless on invisible frames, and dangerous on garbaged
11028 windows and frames; in the latter case, the frame or window may
11029 be in the midst of changing its size, and x and y may be off the
11031 if (! FRAME_VISIBLE_P (f
)
11032 || FRAME_GARBAGED_P (f
)
11033 || vpos
>= w
->current_matrix
->nrows
11034 || hpos
>= w
->current_matrix
->matrix_w
)
11037 /* If cursor is off and we want it off, return quickly. */
11038 if (!on
&& !w
->phys_cursor_on_p
)
11041 current_glyphs
= w
->current_matrix
;
11042 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11043 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11045 /* If cursor row is not enabled, we don't really know where to
11046 display the cursor. */
11047 if (!glyph_row
->enabled_p
)
11049 w
->phys_cursor_on_p
= 0;
11053 xassert (interrupt_input_blocked
);
11055 /* Set new_cursor_type to the cursor we want to be displayed. In a
11056 mini-buffer window, we want the cursor only to appear if we are
11057 reading input from this window. For the selected window, we want
11058 the cursor type given by the frame parameter. If explicitly
11059 marked off, draw no cursor. In all other cases, we want a hollow
11061 new_cursor_width
= -1;
11062 if (cursor_in_echo_area
11063 && FRAME_HAS_MINIBUF_P (f
)
11064 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11066 if (w
== XWINDOW (echo_area_window
))
11067 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11069 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11073 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11074 || w
!= XWINDOW (f
->selected_window
))
11076 extern int cursor_in_non_selected_windows
;
11078 if (MINI_WINDOW_P (w
)
11079 || !cursor_in_non_selected_windows
11080 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11081 new_cursor_type
= NO_CURSOR
;
11083 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11085 else if (w
->cursor_off_p
)
11086 new_cursor_type
= NO_CURSOR
;
11089 struct buffer
*b
= XBUFFER (w
->buffer
);
11091 if (EQ (b
->cursor_type
, Qt
))
11092 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11094 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11095 &new_cursor_width
);
11099 /* If cursor is currently being shown and we don't want it to be or
11100 it is in the wrong place, or the cursor type is not what we want,
11102 if (w
->phys_cursor_on_p
11104 || w
->phys_cursor
.x
!= x
11105 || w
->phys_cursor
.y
!= y
11106 || new_cursor_type
!= w
->phys_cursor_type
))
11107 x_erase_phys_cursor (w
);
11109 /* If the cursor is now invisible and we want it to be visible,
11111 if (on
&& !w
->phys_cursor_on_p
)
11113 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11114 w
->phys_cursor_height
= glyph_row
->height
;
11116 /* Set phys_cursor_.* before x_draw_.* is called because some
11117 of them may need the information. */
11118 w
->phys_cursor
.x
= x
;
11119 w
->phys_cursor
.y
= glyph_row
->y
;
11120 w
->phys_cursor
.hpos
= hpos
;
11121 w
->phys_cursor
.vpos
= vpos
;
11122 w
->phys_cursor_type
= new_cursor_type
;
11123 w
->phys_cursor_on_p
= 1;
11125 switch (new_cursor_type
)
11127 case HOLLOW_BOX_CURSOR
:
11128 x_draw_hollow_cursor (w
, glyph_row
);
11131 case FILLED_BOX_CURSOR
:
11132 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11136 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11147 if (w
== XWINDOW (f
->selected_window
))
11148 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11149 xic_set_preeditarea (w
, x
, y
);
11154 if (updating_frame
!= f
)
11155 XFlush (FRAME_X_DISPLAY (f
));
11160 /* Display the cursor on window W, or clear it. X and Y are window
11161 relative pixel coordinates. HPOS and VPOS are glyph matrix
11162 positions. If W is not the selected window, display a hollow
11163 cursor. ON non-zero means display the cursor at X, Y which
11164 correspond to HPOS, VPOS, otherwise it is cleared. */
11167 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11169 int on
, hpos
, vpos
, x
, y
;
11172 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11177 /* Display the cursor on window W, or clear it, according to ON_P.
11178 Don't change the cursor's position. */
11181 x_update_cursor (f
, on_p
)
11184 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11188 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11189 in the window tree rooted at W. */
11192 x_update_cursor_in_window_tree (w
, on_p
)
11198 if (!NILP (w
->hchild
))
11199 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11200 else if (!NILP (w
->vchild
))
11201 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11203 x_update_window_cursor (w
, on_p
);
11205 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11210 /* Switch the display of W's cursor on or off, according to the value
11214 x_update_window_cursor (w
, on
)
11218 /* Don't update cursor in windows whose frame is in the process
11219 of being deleted. */
11220 if (w
->current_matrix
)
11223 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11224 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11234 /* Refresh bitmap kitchen sink icon for frame F
11235 when we get an expose event for it. */
11241 /* Normally, the window manager handles this function. */
11244 /* Make the x-window of frame F use the gnu icon bitmap. */
11247 x_bitmap_icon (f
, file
)
11253 if (FRAME_X_WINDOW (f
) == 0)
11256 /* Free up our existing icon bitmap if any. */
11257 if (f
->output_data
.x
->icon_bitmap
> 0)
11258 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11259 f
->output_data
.x
->icon_bitmap
= 0;
11261 if (STRINGP (file
))
11262 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11265 /* Create the GNU bitmap if necessary. */
11266 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11267 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11268 = x_create_bitmap_from_data (f
, gnu_bits
,
11269 gnu_width
, gnu_height
);
11271 /* The first time we create the GNU bitmap,
11272 this increments the ref-count one extra time.
11273 As a result, the GNU bitmap is never freed.
11274 That way, we don't have to worry about allocating it again. */
11275 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11277 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11280 x_wm_set_icon_pixmap (f
, bitmap_id
);
11281 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11287 /* Make the x-window of frame F use a rectangle with text.
11288 Use ICON_NAME as the text. */
11291 x_text_icon (f
, icon_name
)
11295 if (FRAME_X_WINDOW (f
) == 0)
11300 XTextProperty text
;
11301 text
.value
= (unsigned char *) icon_name
;
11302 text
.encoding
= XA_STRING
;
11304 text
.nitems
= strlen (icon_name
);
11305 #ifdef USE_X_TOOLKIT
11306 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11308 #else /* not USE_X_TOOLKIT */
11309 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11310 #endif /* not USE_X_TOOLKIT */
11312 #else /* not HAVE_X11R4 */
11313 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11314 #endif /* not HAVE_X11R4 */
11316 if (f
->output_data
.x
->icon_bitmap
> 0)
11317 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11318 f
->output_data
.x
->icon_bitmap
= 0;
11319 x_wm_set_icon_pixmap (f
, 0);
11324 #define X_ERROR_MESSAGE_SIZE 200
11326 /* If non-nil, this should be a string.
11327 It means catch X errors and store the error message in this string. */
11329 static Lisp_Object x_error_message_string
;
11331 /* An X error handler which stores the error message in
11332 x_error_message_string. This is called from x_error_handler if
11333 x_catch_errors is in effect. */
11336 x_error_catcher (display
, error
)
11338 XErrorEvent
*error
;
11340 XGetErrorText (display
, error
->error_code
,
11341 XSTRING (x_error_message_string
)->data
,
11342 X_ERROR_MESSAGE_SIZE
);
11345 /* Begin trapping X errors for display DPY. Actually we trap X errors
11346 for all displays, but DPY should be the display you are actually
11349 After calling this function, X protocol errors no longer cause
11350 Emacs to exit; instead, they are recorded in the string
11351 stored in x_error_message_string.
11353 Calling x_check_errors signals an Emacs error if an X error has
11354 occurred since the last call to x_catch_errors or x_check_errors.
11356 Calling x_uncatch_errors resumes the normal error handling. */
11358 void x_check_errors ();
11359 static Lisp_Object
x_catch_errors_unwind ();
11362 x_catch_errors (dpy
)
11365 int count
= specpdl_ptr
- specpdl
;
11367 /* Make sure any errors from previous requests have been dealt with. */
11368 XSync (dpy
, False
);
11370 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11372 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11373 XSTRING (x_error_message_string
)->data
[0] = 0;
11378 /* Unbind the binding that we made to check for X errors. */
11381 x_catch_errors_unwind (old_val
)
11382 Lisp_Object old_val
;
11384 x_error_message_string
= old_val
;
11388 /* If any X protocol errors have arrived since the last call to
11389 x_catch_errors or x_check_errors, signal an Emacs error using
11390 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11393 x_check_errors (dpy
, format
)
11397 /* Make sure to catch any errors incurred so far. */
11398 XSync (dpy
, False
);
11400 if (XSTRING (x_error_message_string
)->data
[0])
11401 error (format
, XSTRING (x_error_message_string
)->data
);
11404 /* Nonzero if we had any X protocol errors
11405 since we did x_catch_errors on DPY. */
11408 x_had_errors_p (dpy
)
11411 /* Make sure to catch any errors incurred so far. */
11412 XSync (dpy
, False
);
11414 return XSTRING (x_error_message_string
)->data
[0] != 0;
11417 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11420 x_clear_errors (dpy
)
11423 XSTRING (x_error_message_string
)->data
[0] = 0;
11426 /* Stop catching X protocol errors and let them make Emacs die.
11427 DPY should be the display that was passed to x_catch_errors.
11428 COUNT should be the value that was returned by
11429 the corresponding call to x_catch_errors. */
11432 x_uncatch_errors (dpy
, count
)
11436 unbind_to (count
, Qnil
);
11440 static unsigned int x_wire_count
;
11443 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11448 /* Handle SIGPIPE, which can happen when the connection to a server
11449 simply goes away. SIGPIPE is handled by x_connection_signal.
11450 Don't need to do anything, because the write which caused the
11451 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11452 which will do the appropriate cleanup for us. */
11455 x_connection_signal (signalnum
) /* If we don't have an argument, */
11456 int signalnum
; /* some compilers complain in signal calls. */
11459 /* USG systems forget handlers when they are used;
11460 must reestablish each time */
11461 signal (signalnum
, x_connection_signal
);
11466 /************************************************************************
11468 ************************************************************************/
11470 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11471 the text of an error message that lead to the connection loss. */
11474 x_connection_closed (dpy
, error_message
)
11476 char *error_message
;
11478 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11479 Lisp_Object frame
, tail
;
11483 msg
= (char *) alloca (strlen (error_message
) + 1);
11484 strcpy (msg
, error_message
);
11485 handling_signal
= 0;
11487 /* Prevent being called recursively because of an error condition
11488 below. Otherwise, we might end up with printing ``can't find per
11489 display information'' in the recursive call instead of printing
11490 the original message here. */
11491 count
= x_catch_errors (dpy
);
11493 /* We have to close the display to inform Xt that it doesn't
11494 exist anymore. If we don't, Xt will continue to wait for
11495 events from the display. As a consequence, a sequence of
11497 M-x make-frame-on-display RET :1 RET
11498 ...kill the new frame, so that we get an IO error...
11499 M-x make-frame-on-display RET :1 RET
11501 will indefinitely wait in Xt for events for display `:1', opened
11502 in the first class to make-frame-on-display.
11504 Closing the display is reported to lead to a bus error on
11505 OpenWindows in certain situations. I suspect that is a bug
11506 in OpenWindows. I don't know how to cicumvent it here. */
11508 #ifdef USE_X_TOOLKIT
11509 /* If DPYINFO is null, this means we didn't open the display
11510 in the first place, so don't try to close it. */
11512 XtCloseDisplay (dpy
);
11515 /* Indicate that this display is dead. */
11517 dpyinfo
->display
= 0;
11519 /* First delete frames whose mini-buffers are on frames
11520 that are on the dead display. */
11521 FOR_EACH_FRAME (tail
, frame
)
11523 Lisp_Object minibuf_frame
;
11525 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11526 if (FRAME_X_P (XFRAME (frame
))
11527 && FRAME_X_P (XFRAME (minibuf_frame
))
11528 && ! EQ (frame
, minibuf_frame
)
11529 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11530 Fdelete_frame (frame
, Qt
);
11533 /* Now delete all remaining frames on the dead display.
11534 We are now sure none of these is used as the mini-buffer
11535 for another frame that we need to delete. */
11536 FOR_EACH_FRAME (tail
, frame
)
11537 if (FRAME_X_P (XFRAME (frame
))
11538 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11540 /* Set this to t so that Fdelete_frame won't get confused
11541 trying to find a replacement. */
11542 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
11543 Fdelete_frame (frame
, Qt
);
11547 x_delete_display (dpyinfo
);
11549 x_uncatch_errors (dpy
, count
);
11551 if (x_display_list
== 0)
11553 fprintf (stderr
, "%s\n", msg
);
11554 shut_down_emacs (0, 0, Qnil
);
11558 /* Ordinary stack unwind doesn't deal with these. */
11560 sigunblock (sigmask (SIGIO
));
11562 sigunblock (sigmask (SIGALRM
));
11563 TOTALLY_UNBLOCK_INPUT
;
11565 clear_waiting_for_input ();
11570 /* This is the usual handler for X protocol errors.
11571 It kills all frames on the display that we got the error for.
11572 If that was the only one, it prints an error message and kills Emacs. */
11575 x_error_quitter (display
, error
)
11577 XErrorEvent
*error
;
11579 char buf
[256], buf1
[356];
11581 /* Note that there is no real way portable across R3/R4 to get the
11582 original error handler. */
11584 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
11585 sprintf (buf1
, "X protocol error: %s on protocol request %d",
11586 buf
, error
->request_code
);
11587 x_connection_closed (display
, buf1
);
11591 /* This is the first-level handler for X protocol errors.
11592 It calls x_error_quitter or x_error_catcher. */
11595 x_error_handler (display
, error
)
11597 XErrorEvent
*error
;
11599 if (! NILP (x_error_message_string
))
11600 x_error_catcher (display
, error
);
11602 x_error_quitter (display
, error
);
11606 /* This is the handler for X IO errors, always.
11607 It kills all frames on the display that we lost touch with.
11608 If that was the only one, it prints an error message and kills Emacs. */
11611 x_io_error_quitter (display
)
11616 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
11617 x_connection_closed (display
, buf
);
11621 /* Changing the font of the frame. */
11623 /* Give frame F the font named FONTNAME as its default font, and
11624 return the full name of that font. FONTNAME may be a wildcard
11625 pattern; in that case, we choose some font that fits the pattern.
11626 The return value shows which font we chose. */
11629 x_new_font (f
, fontname
)
11631 register char *fontname
;
11633 struct font_info
*fontp
11634 = FS_LOAD_FONT (f
, 0, fontname
, -1);
11639 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
11640 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
11641 f
->output_data
.x
->fontset
= -1;
11643 /* Compute the scroll bar width in character columns. */
11644 if (f
->scroll_bar_pixel_width
> 0)
11646 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11647 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
11651 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11652 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
11655 /* Now make the frame display the given font. */
11656 if (FRAME_X_WINDOW (f
) != 0)
11658 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
11659 f
->output_data
.x
->font
->fid
);
11660 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
11661 f
->output_data
.x
->font
->fid
);
11662 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
11663 f
->output_data
.x
->font
->fid
);
11665 frame_update_line_height (f
);
11667 /* Don't change the size of a tip frame; there's no point in
11668 doing it because it's done in Fx_show_tip, and it leads to
11669 problems because the tip frame has no widget. */
11670 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
11671 x_set_window_size (f
, 0, f
->width
, f
->height
);
11674 /* If we are setting a new frame's font for the first time,
11675 there are no faces yet, so this font's height is the line height. */
11676 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
11678 return build_string (fontp
->full_name
);
11681 /* Give frame F the fontset named FONTSETNAME as its default font, and
11682 return the full name of that fontset. FONTSETNAME may be a wildcard
11683 pattern; in that case, we choose some fontset that fits the pattern.
11684 The return value shows which fontset we chose. */
11687 x_new_fontset (f
, fontsetname
)
11691 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
11692 Lisp_Object result
;
11697 if (f
->output_data
.x
->fontset
== fontset
)
11698 /* This fontset is already set in frame F. There's nothing more
11700 return fontset_name (fontset
);
11702 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
11704 if (!STRINGP (result
))
11705 /* Can't load ASCII font. */
11708 /* Since x_new_font doesn't update any fontset information, do it now. */
11709 f
->output_data
.x
->fontset
= fontset
;
11713 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
11714 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
11717 return build_string (fontsetname
);
11721 /***********************************************************************
11723 ***********************************************************************/
11729 /* XIM destroy callback function, which is called whenever the
11730 connection to input method XIM dies. CLIENT_DATA contains a
11731 pointer to the x_display_info structure corresponding to XIM. */
11734 xim_destroy_callback (xim
, client_data
, call_data
)
11736 XPointer client_data
;
11737 XPointer call_data
;
11739 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
11740 Lisp_Object frame
, tail
;
11744 /* No need to call XDestroyIC.. */
11745 FOR_EACH_FRAME (tail
, frame
)
11747 struct frame
*f
= XFRAME (frame
);
11748 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
11750 FRAME_XIC (f
) = NULL
;
11751 if (FRAME_XIC_FONTSET (f
))
11753 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
11754 FRAME_XIC_FONTSET (f
) = NULL
;
11759 /* No need to call XCloseIM. */
11760 dpyinfo
->xim
= NULL
;
11761 XFree (dpyinfo
->xim_styles
);
11765 #endif /* HAVE_X11R6 */
11767 /* Open the connection to the XIM server on display DPYINFO.
11768 RESOURCE_NAME is the resource name Emacs uses. */
11771 xim_open_dpy (dpyinfo
, resource_name
)
11772 struct x_display_info
*dpyinfo
;
11773 char *resource_name
;
11778 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
11779 dpyinfo
->xim
= xim
;
11784 XIMCallback destroy
;
11787 /* Get supported styles and XIM values. */
11788 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
11791 destroy
.callback
= xim_destroy_callback
;
11792 destroy
.client_data
= (XPointer
)dpyinfo
;
11793 /* This isn't prptotyped in OSF 5.0. */
11794 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
11798 #else /* not USE_XIM */
11799 dpyinfo
->xim
= NULL
;
11800 #endif /* not USE_XIM */
11804 #ifdef HAVE_X11R6_XIM
11808 struct x_display_info
*dpyinfo
;
11809 char *resource_name
;
11812 /* XIM instantiate callback function, which is called whenever an XIM
11813 server is available. DISPLAY is teh display of the XIM.
11814 CLIENT_DATA contains a pointer to an xim_inst_t structure created
11815 when the callback was registered. */
11818 xim_instantiate_callback (display
, client_data
, call_data
)
11820 XPointer client_data
;
11821 XPointer call_data
;
11823 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
11824 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
11826 /* We don't support multiple XIM connections. */
11830 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
11832 /* Create XIC for the existing frames on the same display, as long
11833 as they have no XIC. */
11834 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
11836 Lisp_Object tail
, frame
;
11839 FOR_EACH_FRAME (tail
, frame
)
11841 struct frame
*f
= XFRAME (frame
);
11843 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
11844 if (FRAME_XIC (f
) == NULL
)
11846 create_frame_xic (f
);
11847 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
11848 xic_set_statusarea (f
);
11849 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
11851 struct window
*w
= XWINDOW (f
->selected_window
);
11852 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
11861 #endif /* HAVE_X11R6_XIM */
11864 /* Open a connection to the XIM server on display DPYINFO.
11865 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
11866 connection only at the first time. On X11R6, open the connection
11867 in the XIM instantiate callback function. */
11870 xim_initialize (dpyinfo
, resource_name
)
11871 struct x_display_info
*dpyinfo
;
11872 char *resource_name
;
11875 #ifdef HAVE_X11R6_XIM
11876 struct xim_inst_t
*xim_inst
;
11879 dpyinfo
->xim
= NULL
;
11880 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
11881 xim_inst
->dpyinfo
= dpyinfo
;
11882 len
= strlen (resource_name
);
11883 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
11884 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
11885 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
11886 resource_name
, EMACS_CLASS
,
11887 xim_instantiate_callback
,
11888 /* Fixme: This is XPointer in
11889 XFree86 but (XPointer *) on
11890 Tru64, at least. */
11891 (XPointer
) xim_inst
);
11892 #else /* not HAVE_X11R6_XIM */
11893 dpyinfo
->xim
= NULL
;
11894 xim_open_dpy (dpyinfo
, resource_name
);
11895 #endif /* not HAVE_X11R6_XIM */
11897 #else /* not USE_XIM */
11898 dpyinfo
->xim
= NULL
;
11899 #endif /* not USE_XIM */
11903 /* Close the connection to the XIM server on display DPYINFO. */
11906 xim_close_dpy (dpyinfo
)
11907 struct x_display_info
*dpyinfo
;
11910 #ifdef HAVE_X11R6_XIM
11911 if (dpyinfo
->display
)
11912 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
11914 xim_instantiate_callback
, NULL
);
11915 #endif /* not HAVE_X11R6_XIM */
11916 if (dpyinfo
->display
)
11917 XCloseIM (dpyinfo
->xim
);
11918 dpyinfo
->xim
= NULL
;
11919 XFree (dpyinfo
->xim_styles
);
11920 #endif /* USE_XIM */
11923 #endif /* not HAVE_X11R6_XIM */
11927 /* Calculate the absolute position in frame F
11928 from its current recorded position values and gravity. */
11931 x_calc_absolute_position (f
)
11935 int win_x
= 0, win_y
= 0;
11936 int flags
= f
->output_data
.x
->size_hint_flags
;
11939 /* We have nothing to do if the current position
11940 is already for the top-left corner. */
11941 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
11944 #ifdef USE_X_TOOLKIT
11945 this_window
= XtWindow (f
->output_data
.x
->widget
);
11947 this_window
= FRAME_X_WINDOW (f
);
11950 /* Find the position of the outside upper-left corner of
11951 the inner window, with respect to the outer window.
11952 But do this only if we will need the results. */
11953 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
11958 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
11961 x_clear_errors (FRAME_X_DISPLAY (f
));
11962 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
11964 /* From-window, to-window. */
11966 f
->output_data
.x
->parent_desc
,
11968 /* From-position, to-position. */
11969 0, 0, &win_x
, &win_y
,
11971 /* Child of win. */
11973 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
11975 Window newroot
, newparent
= 0xdeadbeef;
11976 Window
*newchildren
;
11977 unsigned int nchildren
;
11979 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
11980 &newparent
, &newchildren
, &nchildren
))
11983 XFree ((char *) newchildren
);
11985 f
->output_data
.x
->parent_desc
= newparent
;
11991 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
11995 /* Treat negative positions as relative to the leftmost bottommost
11996 position that fits on the screen. */
11997 if (flags
& XNegative
)
11998 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
11999 - 2 * f
->output_data
.x
->border_width
- win_x
12001 + f
->output_data
.x
->left_pos
);
12004 int height
= PIXEL_HEIGHT (f
);
12006 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12007 /* Something is fishy here. When using Motif, starting Emacs with
12008 `-g -0-0', the frame appears too low by a few pixels.
12010 This seems to be so because initially, while Emacs is starting,
12011 the column widget's height and the frame's pixel height are
12012 different. The column widget's height is the right one. In
12013 later invocations, when Emacs is up, the frame's pixel height
12016 It's not obvious where the initial small difference comes from.
12017 2000-12-01, gerd. */
12019 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12022 if (flags
& YNegative
)
12023 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12024 - 2 * f
->output_data
.x
->border_width
12027 + f
->output_data
.x
->top_pos
);
12030 /* The left_pos and top_pos
12031 are now relative to the top and left screen edges,
12032 so the flags should correspond. */
12033 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12036 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12037 to really change the position, and 0 when calling from
12038 x_make_frame_visible (in that case, XOFF and YOFF are the current
12039 position values). It is -1 when calling from x_set_frame_parameters,
12040 which means, do adjust for borders but don't change the gravity. */
12043 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12045 register int xoff
, yoff
;
12046 int change_gravity
;
12048 int modified_top
, modified_left
;
12050 if (change_gravity
> 0)
12052 f
->output_data
.x
->top_pos
= yoff
;
12053 f
->output_data
.x
->left_pos
= xoff
;
12054 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12056 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12058 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12059 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12061 x_calc_absolute_position (f
);
12064 x_wm_set_size_hint (f
, (long) 0, 0);
12066 modified_left
= f
->output_data
.x
->left_pos
;
12067 modified_top
= f
->output_data
.x
->top_pos
;
12068 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12069 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12070 /* It is a mystery why we need to add the border_width here
12071 when the frame is already visible, but experiment says we do. */
12072 if (change_gravity
!= 0)
12074 modified_left
+= f
->output_data
.x
->border_width
;
12075 modified_top
+= f
->output_data
.x
->border_width
;
12079 #ifdef USE_X_TOOLKIT
12080 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12081 modified_left
, modified_top
);
12082 #else /* not USE_X_TOOLKIT */
12083 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12084 modified_left
, modified_top
);
12085 #endif /* not USE_X_TOOLKIT */
12090 /* Change the size of frame F's X window to COLS/ROWS in the case F
12091 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12092 top-left-corner window gravity for this size change and subsequent
12093 size changes. Otherwise we leave the window gravity unchanged. */
12096 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12098 int change_gravity
;
12101 int pixelwidth
, pixelheight
;
12103 check_frame_size (f
, &rows
, &cols
);
12104 f
->output_data
.x
->vertical_scroll_bar_extra
12105 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12107 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12108 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12109 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12110 f
->output_data
.x
->flags_areas_extra
12111 = FRAME_FLAGS_AREA_WIDTH (f
);
12112 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12113 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12115 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12116 x_wm_set_size_hint (f
, (long) 0, 0);
12118 XSync (FRAME_X_DISPLAY (f
), False
);
12119 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12120 pixelwidth
, pixelheight
);
12122 /* Now, strictly speaking, we can't be sure that this is accurate,
12123 but the window manager will get around to dealing with the size
12124 change request eventually, and we'll hear how it went when the
12125 ConfigureNotify event gets here.
12127 We could just not bother storing any of this information here,
12128 and let the ConfigureNotify event set everything up, but that
12129 might be kind of confusing to the Lisp code, since size changes
12130 wouldn't be reported in the frame parameters until some random
12131 point in the future when the ConfigureNotify event arrives.
12133 We pass 1 for DELAY since we can't run Lisp code inside of
12135 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12136 PIXEL_WIDTH (f
) = pixelwidth
;
12137 PIXEL_HEIGHT (f
) = pixelheight
;
12139 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12140 receive in the ConfigureNotify event; if we get what we asked
12141 for, then the event won't cause the screen to become garbaged, so
12142 we have to make sure to do it here. */
12143 SET_FRAME_GARBAGED (f
);
12145 XFlush (FRAME_X_DISPLAY (f
));
12149 /* Call this to change the size of frame F's x-window.
12150 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12151 for this size change and subsequent size changes.
12152 Otherwise we leave the window gravity unchanged. */
12155 x_set_window_size (f
, change_gravity
, cols
, rows
)
12157 int change_gravity
;
12162 #ifdef USE_X_TOOLKIT
12164 if (f
->output_data
.x
->widget
!= NULL
)
12166 /* The x and y position of the widget is clobbered by the
12167 call to XtSetValues within EmacsFrameSetCharSize.
12168 This is a real kludge, but I don't understand Xt so I can't
12169 figure out a correct fix. Can anyone else tell me? -- rms. */
12170 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12171 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12172 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12173 f
->output_data
.x
->widget
->core
.x
= xpos
;
12174 f
->output_data
.x
->widget
->core
.y
= ypos
;
12177 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12179 #else /* not USE_X_TOOLKIT */
12181 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12183 #endif /* not USE_X_TOOLKIT */
12185 /* If cursor was outside the new size, mark it as off. */
12186 mark_window_cursors_off (XWINDOW (f
->root_window
));
12188 /* Clear out any recollection of where the mouse highlighting was,
12189 since it might be in a place that's outside the new frame size.
12190 Actually checking whether it is outside is a pain in the neck,
12191 so don't try--just let the highlighting be done afresh with new size. */
12192 cancel_mouse_face (f
);
12197 /* Mouse warping. */
12200 x_set_mouse_position (f
, x
, y
)
12206 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12207 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12209 if (pix_x
< 0) pix_x
= 0;
12210 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12212 if (pix_y
< 0) pix_y
= 0;
12213 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12217 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12218 0, 0, 0, 0, pix_x
, pix_y
);
12222 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12225 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12231 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12232 0, 0, 0, 0, pix_x
, pix_y
);
12236 /* focus shifting, raising and lowering. */
12239 x_focus_on_frame (f
)
12242 #if 0 /* This proves to be unpleasant. */
12246 /* I don't think that the ICCCM allows programs to do things like this
12247 without the interaction of the window manager. Whatever you end up
12248 doing with this code, do it to x_unfocus_frame too. */
12249 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12250 RevertToPointerRoot
, CurrentTime
);
12255 x_unfocus_frame (f
)
12259 /* Look at the remarks in x_focus_on_frame. */
12260 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12261 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12262 RevertToPointerRoot
, CurrentTime
);
12266 /* Raise frame F. */
12272 if (f
->async_visible
)
12275 #ifdef USE_X_TOOLKIT
12276 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12277 #else /* not USE_X_TOOLKIT */
12278 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12279 #endif /* not USE_X_TOOLKIT */
12280 XFlush (FRAME_X_DISPLAY (f
));
12285 /* Lower frame F. */
12291 if (f
->async_visible
)
12294 #ifdef USE_X_TOOLKIT
12295 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12296 #else /* not USE_X_TOOLKIT */
12297 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12298 #endif /* not USE_X_TOOLKIT */
12299 XFlush (FRAME_X_DISPLAY (f
));
12305 XTframe_raise_lower (f
, raise_flag
)
12315 /* Change of visibility. */
12317 /* This tries to wait until the frame is really visible.
12318 However, if the window manager asks the user where to position
12319 the frame, this will return before the user finishes doing that.
12320 The frame will not actually be visible at that time,
12321 but it will become visible later when the window manager
12322 finishes with it. */
12325 x_make_frame_visible (f
)
12329 int original_top
, original_left
;
12330 int retry_count
= 2;
12336 type
= x_icon_type (f
);
12338 x_bitmap_icon (f
, type
);
12340 if (! FRAME_VISIBLE_P (f
))
12342 /* We test FRAME_GARBAGED_P here to make sure we don't
12343 call x_set_offset a second time
12344 if we get to x_make_frame_visible a second time
12345 before the window gets really visible. */
12346 if (! FRAME_ICONIFIED_P (f
)
12347 && ! f
->output_data
.x
->asked_for_visible
)
12348 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12350 f
->output_data
.x
->asked_for_visible
= 1;
12352 if (! EQ (Vx_no_window_manager
, Qt
))
12353 x_wm_set_window_state (f
, NormalState
);
12354 #ifdef USE_X_TOOLKIT
12355 /* This was XtPopup, but that did nothing for an iconified frame. */
12356 XtMapWidget (f
->output_data
.x
->widget
);
12357 #else /* not USE_X_TOOLKIT */
12358 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12359 #endif /* not USE_X_TOOLKIT */
12360 #if 0 /* This seems to bring back scroll bars in the wrong places
12361 if the window configuration has changed. They seem
12362 to come back ok without this. */
12363 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12364 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12368 XFlush (FRAME_X_DISPLAY (f
));
12370 /* Synchronize to ensure Emacs knows the frame is visible
12371 before we do anything else. We do this loop with input not blocked
12372 so that incoming events are handled. */
12376 /* This must be before UNBLOCK_INPUT
12377 since events that arrive in response to the actions above
12378 will set it when they are handled. */
12379 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12381 original_left
= f
->output_data
.x
->left_pos
;
12382 original_top
= f
->output_data
.x
->top_pos
;
12384 /* This must come after we set COUNT. */
12387 /* We unblock here so that arriving X events are processed. */
12389 /* Now move the window back to where it was "supposed to be".
12390 But don't do it if the gravity is negative.
12391 When the gravity is negative, this uses a position
12392 that is 3 pixels too low. Perhaps that's really the border width.
12394 Don't do this if the window has never been visible before,
12395 because the window manager may choose the position
12396 and we don't want to override it. */
12398 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12399 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12400 && previously_visible
)
12404 unsigned int width
, height
, border
, depth
;
12408 /* On some window managers (such as FVWM) moving an existing
12409 window, even to the same place, causes the window manager
12410 to introduce an offset. This can cause the window to move
12411 to an unexpected location. Check the geometry (a little
12412 slow here) and then verify that the window is in the right
12413 place. If the window is not in the right place, move it
12414 there, and take the potential window manager hit. */
12415 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12416 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12418 if (original_left
!= x
|| original_top
!= y
)
12419 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12420 original_left
, original_top
);
12425 XSETFRAME (frame
, f
);
12427 /* Wait until the frame is visible. Process X events until a
12428 MapNotify event has been seen, or until we think we won't get a
12429 MapNotify at all.. */
12430 for (count
= input_signal_count
+ 10;
12431 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12433 /* Force processing of queued events. */
12436 /* Machines that do polling rather than SIGIO have been
12437 observed to go into a busy-wait here. So we'll fake an
12438 alarm signal to let the handler know that there's something
12439 to be read. We used to raise a real alarm, but it seems
12440 that the handler isn't always enabled here. This is
12442 if (input_polling_used ())
12444 /* It could be confusing if a real alarm arrives while
12445 processing the fake one. Turn it off and let the
12446 handler reset it. */
12447 extern void poll_for_input_1
P_ ((void));
12448 int old_poll_suppress_count
= poll_suppress_count
;
12449 poll_suppress_count
= 1;
12450 poll_for_input_1 ();
12451 poll_suppress_count
= old_poll_suppress_count
;
12454 /* See if a MapNotify event has been processed. */
12455 FRAME_SAMPLE_VISIBILITY (f
);
12460 (let ((f (selected-frame)))
12464 the frame is not raised with various window managers on
12465 FreeBSD, Linux and Solaris. It turns out that, for some
12466 unknown reason, the call to XtMapWidget is completely ignored.
12467 Mapping the widget a second time works. */
12469 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12474 /* Change from mapped state to withdrawn state. */
12476 /* Make the frame visible (mapped and not iconified). */
12479 x_make_frame_invisible (f
)
12484 #ifdef USE_X_TOOLKIT
12485 /* Use the frame's outermost window, not the one we normally draw on. */
12486 window
= XtWindow (f
->output_data
.x
->widget
);
12487 #else /* not USE_X_TOOLKIT */
12488 window
= FRAME_X_WINDOW (f
);
12489 #endif /* not USE_X_TOOLKIT */
12491 /* Don't keep the highlight on an invisible frame. */
12492 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12493 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12495 #if 0/* This might add unreliability; I don't trust it -- rms. */
12496 if (! f
->async_visible
&& ! f
->async_iconified
)
12502 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12503 that the current position of the window is user-specified, rather than
12504 program-specified, so that when the window is mapped again, it will be
12505 placed at the same location, without forcing the user to position it
12506 by hand again (they have already done that once for this window.) */
12507 x_wm_set_size_hint (f
, (long) 0, 1);
12511 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12512 DefaultScreen (FRAME_X_DISPLAY (f
))))
12514 UNBLOCK_INPUT_RESIGNAL
;
12515 error ("Can't notify window manager of window withdrawal");
12517 #else /* ! defined (HAVE_X11R4) */
12519 /* Tell the window manager what we're going to do. */
12520 if (! EQ (Vx_no_window_manager
, Qt
))
12524 unmap
.xunmap
.type
= UnmapNotify
;
12525 unmap
.xunmap
.window
= window
;
12526 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12527 unmap
.xunmap
.from_configure
= False
;
12528 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12529 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12531 SubstructureRedirectMaskSubstructureNotifyMask
,
12534 UNBLOCK_INPUT_RESIGNAL
;
12535 error ("Can't notify window manager of withdrawal");
12539 /* Unmap the window ourselves. Cheeky! */
12540 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12541 #endif /* ! defined (HAVE_X11R4) */
12543 /* We can't distinguish this from iconification
12544 just by the event that we get from the server.
12545 So we can't win using the usual strategy of letting
12546 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
12547 and synchronize with the server to make sure we agree. */
12549 FRAME_ICONIFIED_P (f
) = 0;
12550 f
->async_visible
= 0;
12551 f
->async_iconified
= 0;
12558 /* Change window state from mapped to iconified. */
12561 x_iconify_frame (f
)
12567 /* Don't keep the highlight on an invisible frame. */
12568 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12569 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12571 if (f
->async_iconified
)
12576 FRAME_SAMPLE_VISIBILITY (f
);
12578 type
= x_icon_type (f
);
12580 x_bitmap_icon (f
, type
);
12582 #ifdef USE_X_TOOLKIT
12584 if (! FRAME_VISIBLE_P (f
))
12586 if (! EQ (Vx_no_window_manager
, Qt
))
12587 x_wm_set_window_state (f
, IconicState
);
12588 /* This was XtPopup, but that did nothing for an iconified frame. */
12589 XtMapWidget (f
->output_data
.x
->widget
);
12590 /* The server won't give us any event to indicate
12591 that an invisible frame was changed to an icon,
12592 so we have to record it here. */
12595 f
->async_iconified
= 1;
12596 f
->async_visible
= 0;
12601 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
12602 XtWindow (f
->output_data
.x
->widget
),
12603 DefaultScreen (FRAME_X_DISPLAY (f
)));
12607 error ("Can't notify window manager of iconification");
12609 f
->async_iconified
= 1;
12610 f
->async_visible
= 0;
12614 XFlush (FRAME_X_DISPLAY (f
));
12616 #else /* not USE_X_TOOLKIT */
12618 /* Make sure the X server knows where the window should be positioned,
12619 in case the user deiconifies with the window manager. */
12620 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
12621 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12623 /* Since we don't know which revision of X we're running, we'll use both
12624 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
12626 /* X11R4: send a ClientMessage to the window manager using the
12627 WM_CHANGE_STATE type. */
12631 message
.xclient
.window
= FRAME_X_WINDOW (f
);
12632 message
.xclient
.type
= ClientMessage
;
12633 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
12634 message
.xclient
.format
= 32;
12635 message
.xclient
.data
.l
[0] = IconicState
;
12637 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12638 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12640 SubstructureRedirectMask
| SubstructureNotifyMask
,
12643 UNBLOCK_INPUT_RESIGNAL
;
12644 error ("Can't notify window manager of iconification");
12648 /* X11R3: set the initial_state field of the window manager hints to
12650 x_wm_set_window_state (f
, IconicState
);
12652 if (!FRAME_VISIBLE_P (f
))
12654 /* If the frame was withdrawn, before, we must map it. */
12655 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12658 f
->async_iconified
= 1;
12659 f
->async_visible
= 0;
12661 XFlush (FRAME_X_DISPLAY (f
));
12663 #endif /* not USE_X_TOOLKIT */
12667 /* Free X resources of frame F. */
12670 x_free_frame_resources (f
)
12673 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12677 /* If a display connection is dead, don't try sending more
12678 commands to the X server. */
12679 if (dpyinfo
->display
)
12681 if (f
->output_data
.x
->icon_desc
)
12682 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
12686 free_frame_xic (f
);
12689 if (FRAME_X_WINDOW (f
))
12690 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12692 #ifdef USE_X_TOOLKIT
12693 if (f
->output_data
.x
->widget
)
12694 XtDestroyWidget (f
->output_data
.x
->widget
);
12695 free_frame_menubar (f
);
12696 #endif /* USE_X_TOOLKIT */
12698 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
12699 unload_color (f
, f
->output_data
.x
->background_pixel
);
12700 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
12701 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
12702 unload_color (f
, f
->output_data
.x
->border_pixel
);
12703 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
12705 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
12706 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
12707 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
12708 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
12709 if (f
->output_data
.x
->white_relief
.allocated_p
)
12710 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
12711 if (f
->output_data
.x
->black_relief
.allocated_p
)
12712 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
12714 if (FRAME_FACE_CACHE (f
))
12715 free_frame_faces (f
);
12718 XFlush (FRAME_X_DISPLAY (f
));
12721 if (f
->output_data
.x
->saved_menu_event
)
12722 xfree (f
->output_data
.x
->saved_menu_event
);
12724 xfree (f
->output_data
.x
);
12725 f
->output_data
.x
= NULL
;
12727 if (f
== dpyinfo
->x_focus_frame
)
12728 dpyinfo
->x_focus_frame
= 0;
12729 if (f
== dpyinfo
->x_focus_event_frame
)
12730 dpyinfo
->x_focus_event_frame
= 0;
12731 if (f
== dpyinfo
->x_highlight_frame
)
12732 dpyinfo
->x_highlight_frame
= 0;
12734 if (f
== dpyinfo
->mouse_face_mouse_frame
)
12736 dpyinfo
->mouse_face_beg_row
12737 = dpyinfo
->mouse_face_beg_col
= -1;
12738 dpyinfo
->mouse_face_end_row
12739 = dpyinfo
->mouse_face_end_col
= -1;
12740 dpyinfo
->mouse_face_window
= Qnil
;
12741 dpyinfo
->mouse_face_deferred_gc
= 0;
12742 dpyinfo
->mouse_face_mouse_frame
= 0;
12749 /* Destroy the X window of frame F. */
12752 x_destroy_window (f
)
12755 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12757 /* If a display connection is dead, don't try sending more
12758 commands to the X server. */
12759 if (dpyinfo
->display
!= 0)
12760 x_free_frame_resources (f
);
12762 dpyinfo
->reference_count
--;
12766 /* Setting window manager hints. */
12768 /* Set the normal size hints for the window manager, for frame F.
12769 FLAGS is the flags word to use--or 0 meaning preserve the flags
12770 that the window now has.
12771 If USER_POSITION is nonzero, we set the USPosition
12772 flag (this is useful when FLAGS is 0). */
12775 x_wm_set_size_hint (f
, flags
, user_position
)
12780 XSizeHints size_hints
;
12782 #ifdef USE_X_TOOLKIT
12785 Dimension widget_width
, widget_height
;
12786 Window window
= XtWindow (f
->output_data
.x
->widget
);
12787 #else /* not USE_X_TOOLKIT */
12788 Window window
= FRAME_X_WINDOW (f
);
12789 #endif /* not USE_X_TOOLKIT */
12791 /* Setting PMaxSize caused various problems. */
12792 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
12794 size_hints
.x
= f
->output_data
.x
->left_pos
;
12795 size_hints
.y
= f
->output_data
.x
->top_pos
;
12797 #ifdef USE_X_TOOLKIT
12798 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
12799 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
12800 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
12801 size_hints
.height
= widget_height
;
12802 size_hints
.width
= widget_width
;
12803 #else /* not USE_X_TOOLKIT */
12804 size_hints
.height
= PIXEL_HEIGHT (f
);
12805 size_hints
.width
= PIXEL_WIDTH (f
);
12806 #endif /* not USE_X_TOOLKIT */
12808 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
12809 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
12810 size_hints
.max_width
12811 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
12812 size_hints
.max_height
12813 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
12815 /* Calculate the base and minimum sizes.
12817 (When we use the X toolkit, we don't do it here.
12818 Instead we copy the values that the widgets are using, below.) */
12819 #ifndef USE_X_TOOLKIT
12821 int base_width
, base_height
;
12822 int min_rows
= 0, min_cols
= 0;
12824 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
12825 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
12827 check_frame_size (f
, &min_rows
, &min_cols
);
12829 /* The window manager uses the base width hints to calculate the
12830 current number of rows and columns in the frame while
12831 resizing; min_width and min_height aren't useful for this
12832 purpose, since they might not give the dimensions for a
12833 zero-row, zero-column frame.
12835 We use the base_width and base_height members if we have
12836 them; otherwise, we set the min_width and min_height members
12837 to the size for a zero x zero frame. */
12840 size_hints
.flags
|= PBaseSize
;
12841 size_hints
.base_width
= base_width
;
12842 size_hints
.base_height
= base_height
;
12843 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
12844 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
12846 size_hints
.min_width
= base_width
;
12847 size_hints
.min_height
= base_height
;
12851 /* If we don't need the old flags, we don't need the old hint at all. */
12854 size_hints
.flags
|= flags
;
12857 #endif /* not USE_X_TOOLKIT */
12860 XSizeHints hints
; /* Sometimes I hate X Windows... */
12861 long supplied_return
;
12865 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
12868 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
12871 #ifdef USE_X_TOOLKIT
12872 size_hints
.base_height
= hints
.base_height
;
12873 size_hints
.base_width
= hints
.base_width
;
12874 size_hints
.min_height
= hints
.min_height
;
12875 size_hints
.min_width
= hints
.min_width
;
12879 size_hints
.flags
|= flags
;
12884 if (hints
.flags
& PSize
)
12885 size_hints
.flags
|= PSize
;
12886 if (hints
.flags
& PPosition
)
12887 size_hints
.flags
|= PPosition
;
12888 if (hints
.flags
& USPosition
)
12889 size_hints
.flags
|= USPosition
;
12890 if (hints
.flags
& USSize
)
12891 size_hints
.flags
|= USSize
;
12895 #ifndef USE_X_TOOLKIT
12900 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
12901 size_hints
.flags
|= PWinGravity
;
12905 size_hints
.flags
&= ~ PPosition
;
12906 size_hints
.flags
|= USPosition
;
12908 #endif /* PWinGravity */
12911 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
12913 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
12917 /* Used for IconicState or NormalState */
12920 x_wm_set_window_state (f
, state
)
12924 #ifdef USE_X_TOOLKIT
12927 XtSetArg (al
[0], XtNinitialState
, state
);
12928 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
12929 #else /* not USE_X_TOOLKIT */
12930 Window window
= FRAME_X_WINDOW (f
);
12932 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
12933 f
->output_data
.x
->wm_hints
.initial_state
= state
;
12935 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
12936 #endif /* not USE_X_TOOLKIT */
12940 x_wm_set_icon_pixmap (f
, pixmap_id
)
12944 Pixmap icon_pixmap
;
12946 #ifndef USE_X_TOOLKIT
12947 Window window
= FRAME_X_WINDOW (f
);
12952 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
12953 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
12957 /* It seems there is no way to turn off use of an icon pixmap.
12958 The following line does it, only if no icon has yet been created,
12959 for some window managers. But with mwm it crashes.
12960 Some people say it should clear the IconPixmapHint bit in this case,
12961 but that doesn't work, and the X consortium said it isn't the
12962 right thing at all. Since there is no way to win,
12963 best to explicitly give up. */
12965 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
12971 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
12975 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
12976 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
12979 #else /* not USE_X_TOOLKIT */
12981 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
12982 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
12984 #endif /* not USE_X_TOOLKIT */
12988 x_wm_set_icon_position (f
, icon_x
, icon_y
)
12990 int icon_x
, icon_y
;
12992 #ifdef USE_X_TOOLKIT
12993 Window window
= XtWindow (f
->output_data
.x
->widget
);
12995 Window window
= FRAME_X_WINDOW (f
);
12998 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
12999 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13000 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13002 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13006 /***********************************************************************
13008 ***********************************************************************/
13010 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13013 x_get_font_info (f
, font_idx
)
13017 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13021 /* Return a list of names of available fonts matching PATTERN on frame F.
13023 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13026 SIZE < 0 means include scalable fonts.
13028 Frame F null means we have not yet created any frame on X, and
13029 consult the first display in x_display_list. MAXNAMES sets a limit
13030 on how many fonts to match. */
13033 x_list_fonts (f
, pattern
, size
, maxnames
)
13035 Lisp_Object pattern
;
13039 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13040 Lisp_Object tem
, second_best
;
13041 struct x_display_info
*dpyinfo
13042 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13043 Display
*dpy
= dpyinfo
->display
;
13044 int try_XLoadQueryFont
= 0;
13046 int allow_scalable_fonts_p
= 0;
13050 allow_scalable_fonts_p
= 1;
13054 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13055 if (NILP (patterns
))
13056 patterns
= Fcons (pattern
, Qnil
);
13058 if (maxnames
== 1 && !size
)
13059 /* We can return any single font matching PATTERN. */
13060 try_XLoadQueryFont
= 1;
13062 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13065 char **names
= NULL
;
13067 pattern
= XCAR (patterns
);
13068 /* See if we cached the result for this particular query.
13069 The cache is an alist of the form:
13070 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13071 tem
= XCDR (dpyinfo
->name_list_element
);
13072 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13073 allow_scalable_fonts_p
? Qt
: Qnil
);
13074 list
= Fassoc (key
, tem
);
13077 list
= Fcdr_safe (list
);
13078 /* We have a cashed list. Don't have to get the list again. */
13082 /* At first, put PATTERN in the cache. */
13085 count
= x_catch_errors (dpy
);
13087 if (try_XLoadQueryFont
)
13090 unsigned long value
;
13092 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13093 if (x_had_errors_p (dpy
))
13095 /* This error is perhaps due to insufficient memory on X
13096 server. Let's just ignore it. */
13098 x_clear_errors (dpy
);
13102 && XGetFontProperty (font
, XA_FONT
, &value
))
13104 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13105 int len
= strlen (name
);
13108 /* If DXPC (a Differential X Protocol Compressor)
13109 Ver.3.7 is running, XGetAtomName will return null
13110 string. We must avoid such a name. */
13112 try_XLoadQueryFont
= 0;
13116 names
= (char **) alloca (sizeof (char *));
13117 /* Some systems only allow alloca assigned to a
13119 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13120 bcopy (name
, names
[0], len
+ 1);
13125 try_XLoadQueryFont
= 0;
13128 XFreeFont (dpy
, font
);
13131 if (!try_XLoadQueryFont
)
13133 /* We try at least 10 fonts because XListFonts will return
13134 auto-scaled fonts at the head. */
13135 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13137 if (x_had_errors_p (dpy
))
13139 /* This error is perhaps due to insufficient memory on X
13140 server. Let's just ignore it. */
13142 x_clear_errors (dpy
);
13146 x_uncatch_errors (dpy
, count
);
13153 /* Make a list of all the fonts we got back.
13154 Store that in the font cache for the display. */
13155 for (i
= 0; i
< num_fonts
; i
++)
13158 char *p
= names
[i
];
13159 int average_width
= -1, dashes
= 0;
13161 /* Count the number of dashes in NAMES[I]. If there are
13162 14 dashes, and the field value following 12th dash
13163 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13164 is usually too ugly to be used for editing. Let's
13170 if (dashes
== 7) /* PIXEL_SIZE field */
13172 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13173 average_width
= atoi (p
);
13176 if (allow_scalable_fonts_p
13177 || dashes
< 14 || average_width
!= 0)
13179 tem
= build_string (names
[i
]);
13180 if (NILP (Fassoc (tem
, list
)))
13182 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13183 && ((fast_c_string_match_ignore_case
13184 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13186 /* We can set the value of PIXEL_SIZE to the
13187 width of this font. */
13188 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13190 /* For the moment, width is not known. */
13191 list
= Fcons (Fcons (tem
, Qnil
), list
);
13195 if (!try_XLoadQueryFont
)
13196 XFreeFontNames (names
);
13199 /* Now store the result in the cache. */
13200 XCDR (dpyinfo
->name_list_element
)
13201 = Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
));
13204 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13206 newlist
= second_best
= Qnil
;
13207 /* Make a list of the fonts that have the right width. */
13208 for (; CONSP (list
); list
= XCDR (list
))
13214 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13218 newlist
= Fcons (XCAR (tem
), newlist
);
13222 if (!INTEGERP (XCDR (tem
)))
13224 /* Since we have not yet known the size of this font, we
13225 must try slow function call XLoadQueryFont. */
13226 XFontStruct
*thisinfo
;
13229 count
= x_catch_errors (dpy
);
13230 thisinfo
= XLoadQueryFont (dpy
,
13231 XSTRING (XCAR (tem
))->data
);
13232 if (x_had_errors_p (dpy
))
13234 /* This error is perhaps due to insufficient memory on X
13235 server. Let's just ignore it. */
13237 x_clear_errors (dpy
);
13239 x_uncatch_errors (dpy
, count
);
13245 = (thisinfo
->min_bounds
.width
== 0
13247 : make_number (thisinfo
->max_bounds
.width
));
13248 XFreeFont (dpy
, thisinfo
);
13251 /* For unknown reason, the previous call of XListFont had
13252 returned a font which can't be opened. Record the size
13253 as 0 not to try to open it again. */
13254 XCDR (tem
) = make_number (0);
13257 found_size
= XINT (XCDR (tem
));
13258 if (found_size
== size
)
13259 newlist
= Fcons (XCAR (tem
), newlist
);
13260 else if (found_size
> 0)
13262 if (NILP (second_best
))
13264 else if (found_size
< size
)
13266 if (XINT (XCDR (second_best
)) > size
13267 || XINT (XCDR (second_best
)) < found_size
)
13272 if (XINT (XCDR (second_best
)) > size
13273 && XINT (XCDR (second_best
)) > found_size
)
13278 if (!NILP (newlist
))
13280 else if (!NILP (second_best
))
13282 newlist
= Fcons (XCAR (second_best
), Qnil
);
13293 /* Check that FONT is valid on frame F. It is if it can be found in F's
13297 x_check_font (f
, font
)
13302 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13304 xassert (font
!= NULL
);
13306 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13307 if (dpyinfo
->font_table
[i
].name
13308 && font
== dpyinfo
->font_table
[i
].font
)
13311 xassert (i
< dpyinfo
->n_fonts
);
13314 #endif /* GLYPH_DEBUG != 0 */
13316 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13317 Note: There are (broken) X fonts out there with invalid XFontStruct
13318 min_bounds contents. For example, handa@etl.go.jp reports that
13319 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13320 have font->min_bounds.width == 0. */
13323 x_font_min_bounds (font
, w
, h
)
13327 *h
= FONT_HEIGHT (font
);
13328 *w
= font
->min_bounds
.width
;
13330 /* Try to handle the case where FONT->min_bounds has invalid
13331 contents. Since the only font known to have invalid min_bounds
13332 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13334 *w
= font
->max_bounds
.width
;
13338 /* Compute the smallest character width and smallest font height over
13339 all fonts available on frame F. Set the members smallest_char_width
13340 and smallest_font_height in F's x_display_info structure to
13341 the values computed. Value is non-zero if smallest_font_height or
13342 smallest_char_width become smaller than they were before. */
13345 x_compute_min_glyph_bounds (f
)
13349 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13351 int old_width
= dpyinfo
->smallest_char_width
;
13352 int old_height
= dpyinfo
->smallest_font_height
;
13354 dpyinfo
->smallest_font_height
= 100000;
13355 dpyinfo
->smallest_char_width
= 100000;
13357 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13358 if (dpyinfo
->font_table
[i
].name
)
13360 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13363 font
= (XFontStruct
*) fontp
->font
;
13364 xassert (font
!= (XFontStruct
*) ~0);
13365 x_font_min_bounds (font
, &w
, &h
);
13367 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13368 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13371 xassert (dpyinfo
->smallest_char_width
> 0
13372 && dpyinfo
->smallest_font_height
> 0);
13374 return (dpyinfo
->n_fonts
== 1
13375 || dpyinfo
->smallest_char_width
< old_width
13376 || dpyinfo
->smallest_font_height
< old_height
);
13380 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13381 pointer to the structure font_info while allocating it dynamically.
13382 If SIZE is 0, load any size of font.
13383 If loading is failed, return NULL. */
13386 x_load_font (f
, fontname
, size
)
13388 register char *fontname
;
13391 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13392 Lisp_Object font_names
;
13395 /* Get a list of all the fonts that match this name. Once we
13396 have a list of matching fonts, we compare them against the fonts
13397 we already have by comparing names. */
13398 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13400 if (!NILP (font_names
))
13405 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13406 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13407 if (dpyinfo
->font_table
[i
].name
13408 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13409 XSTRING (XCAR (tail
))->data
)
13410 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13411 XSTRING (XCAR (tail
))->data
)))
13412 return (dpyinfo
->font_table
+ i
);
13415 /* Load the font and add it to the table. */
13419 struct font_info
*fontp
;
13420 unsigned long value
;
13423 /* If we have found fonts by x_list_font, load one of them. If
13424 not, we still try to load a font by the name given as FONTNAME
13425 because XListFonts (called in x_list_font) of some X server has
13426 a bug of not finding a font even if the font surely exists and
13427 is loadable by XLoadQueryFont. */
13428 if (size
> 0 && !NILP (font_names
))
13429 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13432 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13433 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13434 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13436 /* This error is perhaps due to insufficient memory on X
13437 server. Let's just ignore it. */
13439 x_clear_errors (FRAME_X_DISPLAY (f
));
13441 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13446 /* Find a free slot in the font table. */
13447 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13448 if (dpyinfo
->font_table
[i
].name
== NULL
)
13451 /* If no free slot found, maybe enlarge the font table. */
13452 if (i
== dpyinfo
->n_fonts
13453 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13456 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13457 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13458 dpyinfo
->font_table
13459 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13462 fontp
= dpyinfo
->font_table
+ i
;
13463 if (i
== dpyinfo
->n_fonts
)
13464 ++dpyinfo
->n_fonts
;
13466 /* Now fill in the slots of *FONTP. */
13468 fontp
->font
= font
;
13469 fontp
->font_idx
= i
;
13470 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13471 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13473 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13475 if (XGetFontProperty (font
, XA_FONT
, &value
))
13477 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13481 /* Count the number of dashes in the "full name".
13482 If it is too few, this isn't really the font's full name,
13484 In X11R4, the fonts did not come with their canonical names
13495 full_name
= (char *) xmalloc (p
- name
+ 1);
13496 bcopy (name
, full_name
, p
- name
+ 1);
13502 if (full_name
!= 0)
13503 fontp
->full_name
= full_name
;
13505 fontp
->full_name
= fontp
->name
;
13507 fontp
->size
= font
->max_bounds
.width
;
13508 fontp
->height
= FONT_HEIGHT (font
);
13510 if (NILP (font_names
))
13512 /* We come here because of a bug of XListFonts mentioned at
13513 the head of this block. Let's store this information in
13514 the cache for x_list_fonts. */
13515 Lisp_Object lispy_name
= build_string (fontname
);
13516 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13517 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
13520 XCDR (dpyinfo
->name_list_element
)
13521 = Fcons (Fcons (key
,
13522 Fcons (Fcons (lispy_full_name
,
13523 make_number (fontp
->size
)),
13525 XCDR (dpyinfo
->name_list_element
));
13528 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
13530 XCDR (dpyinfo
->name_list_element
)
13531 = Fcons (Fcons (key
,
13532 Fcons (Fcons (lispy_full_name
,
13533 make_number (fontp
->size
)),
13535 XCDR (dpyinfo
->name_list_element
));
13539 /* The slot `encoding' specifies how to map a character
13540 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
13541 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
13542 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
13543 2:0xA020..0xFF7F). For the moment, we don't know which charset
13544 uses this font. So, we set information in fontp->encoding[1]
13545 which is never used by any charset. If mapping can't be
13546 decided, set FONT_ENCODING_NOT_DECIDED. */
13548 = (font
->max_byte1
== 0
13550 ? (font
->min_char_or_byte2
< 0x80
13551 ? (font
->max_char_or_byte2
< 0x80
13552 ? 0 /* 0x20..0x7F */
13553 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
13554 : 1) /* 0xA0..0xFF */
13556 : (font
->min_byte1
< 0x80
13557 ? (font
->max_byte1
< 0x80
13558 ? (font
->min_char_or_byte2
< 0x80
13559 ? (font
->max_char_or_byte2
< 0x80
13560 ? 0 /* 0x2020..0x7F7F */
13561 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
13562 : 3) /* 0x20A0..0x7FFF */
13563 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
13564 : (font
->min_char_or_byte2
< 0x80
13565 ? (font
->max_char_or_byte2
< 0x80
13566 ? 2 /* 0xA020..0xFF7F */
13567 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
13568 : 1))); /* 0xA0A0..0xFFFF */
13570 fontp
->baseline_offset
13571 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
13572 ? (long) value
: 0);
13573 fontp
->relative_compose
13574 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
13575 ? (long) value
: 0);
13576 fontp
->default_ascent
13577 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
13578 ? (long) value
: 0);
13580 /* Set global flag fonts_changed_p to non-zero if the font loaded
13581 has a character with a smaller width than any other character
13582 before, or if the font loaded has a smalle>r height than any
13583 other font loaded before. If this happens, it will make a
13584 glyph matrix reallocation necessary. */
13585 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
13592 /* Return a pointer to struct font_info of a font named FONTNAME for
13593 frame F. If no such font is loaded, return NULL. */
13596 x_query_font (f
, fontname
)
13598 register char *fontname
;
13600 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13603 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13604 if (dpyinfo
->font_table
[i
].name
13605 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
13606 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
13607 return (dpyinfo
->font_table
+ i
);
13612 /* Find a CCL program for a font specified by FONTP, and set the member
13613 `encoder' of the structure. */
13616 x_find_ccl_program (fontp
)
13617 struct font_info
*fontp
;
13619 Lisp_Object list
, elt
;
13622 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
13626 && STRINGP (XCAR (elt
))
13627 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
13629 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
13636 struct ccl_program
*ccl
13637 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
13639 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
13642 fontp
->font_encoder
= ccl
;
13648 /***********************************************************************
13650 ***********************************************************************/
13652 #ifdef USE_X_TOOLKIT
13653 static XrmOptionDescRec emacs_options
[] = {
13654 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13655 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13657 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13658 XrmoptionSepArg
, NULL
},
13659 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13661 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13662 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13663 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13664 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13665 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13666 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13667 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13669 #endif /* USE_X_TOOLKIT */
13671 static int x_initialized
;
13673 #ifdef MULTI_KBOARD
13674 /* Test whether two display-name strings agree up to the dot that separates
13675 the screen number from the server number. */
13677 same_x_server (name1
, name2
)
13678 char *name1
, *name2
;
13680 int seen_colon
= 0;
13681 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
13682 int system_name_length
= strlen (system_name
);
13683 int length_until_period
= 0;
13685 while (system_name
[length_until_period
] != 0
13686 && system_name
[length_until_period
] != '.')
13687 length_until_period
++;
13689 /* Treat `unix' like an empty host name. */
13690 if (! strncmp (name1
, "unix:", 5))
13692 if (! strncmp (name2
, "unix:", 5))
13694 /* Treat this host's name like an empty host name. */
13695 if (! strncmp (name1
, system_name
, system_name_length
)
13696 && name1
[system_name_length
] == ':')
13697 name1
+= system_name_length
;
13698 if (! strncmp (name2
, system_name
, system_name_length
)
13699 && name2
[system_name_length
] == ':')
13700 name2
+= system_name_length
;
13701 /* Treat this host's domainless name like an empty host name. */
13702 if (! strncmp (name1
, system_name
, length_until_period
)
13703 && name1
[length_until_period
] == ':')
13704 name1
+= length_until_period
;
13705 if (! strncmp (name2
, system_name
, length_until_period
)
13706 && name2
[length_until_period
] == ':')
13707 name2
+= length_until_period
;
13709 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13713 if (seen_colon
&& *name1
== '.')
13717 && (*name1
== '.' || *name1
== '\0')
13718 && (*name2
== '.' || *name2
== '\0'));
13722 struct x_display_info
*
13723 x_term_init (display_name
, xrm_option
, resource_name
)
13724 Lisp_Object display_name
;
13726 char *resource_name
;
13730 struct x_display_info
*dpyinfo
;
13735 if (!x_initialized
)
13741 #ifdef USE_X_TOOLKIT
13742 /* weiner@footloose.sps.mot.com reports that this causes
13744 X protocol error: BadAtom (invalid Atom parameter)
13745 on protocol request 18skiloaf.
13746 So let's not use it until R6. */
13747 #ifdef HAVE_X11XTR6
13748 XtSetLanguageProc (NULL
, NULL
, NULL
);
13759 argv
[argc
++] = "-xrm";
13760 argv
[argc
++] = xrm_option
;
13762 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
13763 resource_name
, EMACS_CLASS
,
13764 emacs_options
, XtNumber (emacs_options
),
13767 #ifdef HAVE_X11XTR6
13768 /* I think this is to compensate for XtSetLanguageProc. */
13773 #else /* not USE_X_TOOLKIT */
13775 XSetLocaleModifiers ("");
13777 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
13778 #endif /* not USE_X_TOOLKIT */
13780 /* Detect failure. */
13787 /* We have definitely succeeded. Record the new connection. */
13789 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
13790 bzero (dpyinfo
, sizeof *dpyinfo
);
13792 #ifdef MULTI_KBOARD
13794 struct x_display_info
*share
;
13797 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
13798 share
= share
->next
, tail
= XCDR (tail
))
13799 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
13800 XSTRING (display_name
)->data
))
13803 dpyinfo
->kboard
= share
->kboard
;
13806 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
13807 init_kboard (dpyinfo
->kboard
);
13808 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
13810 char *vendor
= ServerVendor (dpy
);
13812 dpyinfo
->kboard
->Vsystem_key_alist
13813 = call1 (Qvendor_specific_keysyms
,
13814 build_string (vendor
? vendor
: ""));
13818 dpyinfo
->kboard
->next_kboard
= all_kboards
;
13819 all_kboards
= dpyinfo
->kboard
;
13820 /* Don't let the initial kboard remain current longer than necessary.
13821 That would cause problems if a file loaded on startup tries to
13822 prompt in the mini-buffer. */
13823 if (current_kboard
== initial_kboard
)
13824 current_kboard
= dpyinfo
->kboard
;
13826 dpyinfo
->kboard
->reference_count
++;
13830 /* Put this display on the chain. */
13831 dpyinfo
->next
= x_display_list
;
13832 x_display_list
= dpyinfo
;
13834 /* Put it on x_display_name_list as well, to keep them parallel. */
13835 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
13836 x_display_name_list
);
13837 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13839 dpyinfo
->display
= dpy
;
13842 XSetAfterFunction (x_current_display
, x_trace_wire
);
13846 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
13847 + STRING_BYTES (XSTRING (Vsystem_name
))
13849 sprintf (dpyinfo
->x_id_name
, "%s@%s",
13850 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
13852 /* Figure out which modifier bits mean what. */
13853 x_find_modifier_meanings (dpyinfo
);
13855 /* Get the scroll bar cursor. */
13856 dpyinfo
->vertical_scroll_bar_cursor
13857 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
13859 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
13860 resource_name
, EMACS_CLASS
);
13861 #ifdef HAVE_XRMSETDATABASE
13862 XrmSetDatabase (dpyinfo
->display
, xrdb
);
13864 dpyinfo
->display
->db
= xrdb
;
13866 /* Put the rdb where we can find it in a way that works on
13868 dpyinfo
->xrdb
= xrdb
;
13870 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
13871 DefaultScreen (dpyinfo
->display
));
13872 select_visual (dpyinfo
);
13873 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
13874 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
13875 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
13876 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
13877 dpyinfo
->grabbed
= 0;
13878 dpyinfo
->reference_count
= 0;
13879 dpyinfo
->icon_bitmap_id
= -1;
13880 dpyinfo
->font_table
= NULL
;
13881 dpyinfo
->n_fonts
= 0;
13882 dpyinfo
->font_table_size
= 0;
13883 dpyinfo
->bitmaps
= 0;
13884 dpyinfo
->bitmaps_size
= 0;
13885 dpyinfo
->bitmaps_last
= 0;
13886 dpyinfo
->scratch_cursor_gc
= 0;
13887 dpyinfo
->mouse_face_mouse_frame
= 0;
13888 dpyinfo
->mouse_face_deferred_gc
= 0;
13889 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13890 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13891 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13892 dpyinfo
->mouse_face_window
= Qnil
;
13893 dpyinfo
->mouse_face_overlay
= Qnil
;
13894 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
13895 dpyinfo
->mouse_face_defer
= 0;
13896 dpyinfo
->x_focus_frame
= 0;
13897 dpyinfo
->x_focus_event_frame
= 0;
13898 dpyinfo
->x_highlight_frame
= 0;
13899 dpyinfo
->image_cache
= make_image_cache ();
13901 /* See if a private colormap is requested. */
13902 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
13904 if (dpyinfo
->visual
->class == PseudoColor
)
13907 value
= display_x_get_resource (dpyinfo
,
13908 build_string ("privateColormap"),
13909 build_string ("PrivateColormap"),
13911 if (STRINGP (value
)
13912 && (!strcmp (XSTRING (value
)->data
, "true")
13913 || !strcmp (XSTRING (value
)->data
, "on")))
13914 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
13918 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
13919 dpyinfo
->visual
, AllocNone
);
13922 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
13923 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
13924 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
13925 dpyinfo
->resy
= pixels
* 25.4 / mm
;
13926 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
13927 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
13928 dpyinfo
->resx
= pixels
* 25.4 / mm
;
13931 dpyinfo
->Xatom_wm_protocols
13932 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
13933 dpyinfo
->Xatom_wm_take_focus
13934 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
13935 dpyinfo
->Xatom_wm_save_yourself
13936 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
13937 dpyinfo
->Xatom_wm_delete_window
13938 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
13939 dpyinfo
->Xatom_wm_change_state
13940 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
13941 dpyinfo
->Xatom_wm_configure_denied
13942 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
13943 dpyinfo
->Xatom_wm_window_moved
13944 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
13945 dpyinfo
->Xatom_editres
13946 = XInternAtom (dpyinfo
->display
, "Editres", False
);
13947 dpyinfo
->Xatom_CLIPBOARD
13948 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
13949 dpyinfo
->Xatom_TIMESTAMP
13950 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
13951 dpyinfo
->Xatom_TEXT
13952 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
13953 dpyinfo
->Xatom_COMPOUND_TEXT
13954 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
13955 dpyinfo
->Xatom_DELETE
13956 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
13957 dpyinfo
->Xatom_MULTIPLE
13958 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
13959 dpyinfo
->Xatom_INCR
13960 = XInternAtom (dpyinfo
->display
, "INCR", False
);
13961 dpyinfo
->Xatom_EMACS_TMP
13962 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
13963 dpyinfo
->Xatom_TARGETS
13964 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
13965 dpyinfo
->Xatom_NULL
13966 = XInternAtom (dpyinfo
->display
, "NULL", False
);
13967 dpyinfo
->Xatom_ATOM_PAIR
13968 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
13969 /* For properties of font. */
13970 dpyinfo
->Xatom_PIXEL_SIZE
13971 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
13972 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
13973 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
13974 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
13975 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
13976 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
13977 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
13979 /* Ghostscript support. */
13980 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
13981 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
13983 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
13986 dpyinfo
->cut_buffers_initialized
= 0;
13988 connection
= ConnectionNumber (dpyinfo
->display
);
13989 dpyinfo
->connection
= connection
;
13994 null_bits
[0] = 0x00;
13996 dpyinfo
->null_pixel
13997 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
13998 null_bits
, 1, 1, (long) 0, (long) 0,
14003 extern int gray_bitmap_width
, gray_bitmap_height
;
14004 extern char *gray_bitmap_bits
;
14006 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14008 gray_bitmap_width
, gray_bitmap_height
,
14009 (unsigned long) 1, (unsigned long) 0, 1);
14013 xim_initialize (dpyinfo
, resource_name
);
14016 #ifdef subprocesses
14017 /* This is only needed for distinguishing keyboard and process input. */
14018 if (connection
!= 0)
14019 add_keyboard_wait_descriptor (connection
);
14022 #ifndef F_SETOWN_BUG
14024 #ifdef F_SETOWN_SOCK_NEG
14025 /* stdin is a socket here */
14026 fcntl (connection
, F_SETOWN
, -getpid ());
14027 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14028 fcntl (connection
, F_SETOWN
, getpid ());
14029 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14030 #endif /* ! defined (F_SETOWN) */
14031 #endif /* F_SETOWN_BUG */
14034 if (interrupt_input
)
14035 init_sigio (connection
);
14036 #endif /* ! defined (SIGIO) */
14039 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14040 /* Make sure that we have a valid font for dialog boxes
14041 so that Xt does not crash. */
14043 Display
*dpy
= dpyinfo
->display
;
14044 XrmValue d
, fr
, to
;
14048 d
.addr
= (XPointer
)&dpy
;
14049 d
.size
= sizeof (Display
*);
14050 fr
.addr
= XtDefaultFont
;
14051 fr
.size
= sizeof (XtDefaultFont
);
14052 to
.size
= sizeof (Font
*);
14053 to
.addr
= (XPointer
)&font
;
14054 count
= x_catch_errors (dpy
);
14055 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14057 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14058 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14059 x_uncatch_errors (dpy
, count
);
14064 /* See if we should run in synchronous mode. This is useful
14065 for debugging X code. */
14068 value
= display_x_get_resource (dpyinfo
,
14069 build_string ("synchronous"),
14070 build_string ("Synchronous"),
14072 if (STRINGP (value
)
14073 && (!strcmp (XSTRING (value
)->data
, "true")
14074 || !strcmp (XSTRING (value
)->data
, "on")))
14075 XSynchronize (dpyinfo
->display
, True
);
14083 /* Get rid of display DPYINFO, assuming all frames are already gone,
14084 and without sending any more commands to the X server. */
14087 x_delete_display (dpyinfo
)
14088 struct x_display_info
*dpyinfo
;
14090 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14092 /* Discard this display from x_display_name_list and x_display_list.
14093 We can't use Fdelq because that can quit. */
14094 if (! NILP (x_display_name_list
)
14095 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14096 x_display_name_list
= XCDR (x_display_name_list
);
14101 tail
= x_display_name_list
;
14102 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14104 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14106 XCDR (tail
) = XCDR (XCDR (tail
));
14109 tail
= XCDR (tail
);
14113 if (next_noop_dpyinfo
== dpyinfo
)
14114 next_noop_dpyinfo
= dpyinfo
->next
;
14116 if (x_display_list
== dpyinfo
)
14117 x_display_list
= dpyinfo
->next
;
14120 struct x_display_info
*tail
;
14122 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14123 if (tail
->next
== dpyinfo
)
14124 tail
->next
= tail
->next
->next
;
14127 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14128 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14129 XrmDestroyDatabase (dpyinfo
->xrdb
);
14132 #ifdef MULTI_KBOARD
14133 if (--dpyinfo
->kboard
->reference_count
== 0)
14134 delete_kboard (dpyinfo
->kboard
);
14138 xim_close_dpy (dpyinfo
);
14141 xfree (dpyinfo
->font_table
);
14142 xfree (dpyinfo
->x_id_name
);
14143 xfree (dpyinfo
->color_cells
);
14148 /* Set up use of X before we make the first connection. */
14150 static struct redisplay_interface x_redisplay_interface
=
14155 x_clear_end_of_line
,
14157 x_after_update_window_line
,
14158 x_update_window_begin
,
14159 x_update_window_end
,
14162 x_clear_mouse_face
,
14163 x_get_glyph_overhangs
,
14164 x_fix_overlapping_area
14170 rif
= &x_redisplay_interface
;
14172 clear_frame_hook
= x_clear_frame
;
14173 ins_del_lines_hook
= x_ins_del_lines
;
14174 change_line_highlight_hook
= x_change_line_highlight
;
14175 delete_glyphs_hook
= x_delete_glyphs
;
14176 ring_bell_hook
= XTring_bell
;
14177 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14178 set_terminal_modes_hook
= XTset_terminal_modes
;
14179 update_begin_hook
= x_update_begin
;
14180 update_end_hook
= x_update_end
;
14181 set_terminal_window_hook
= XTset_terminal_window
;
14182 read_socket_hook
= XTread_socket
;
14183 frame_up_to_date_hook
= XTframe_up_to_date
;
14184 reassert_line_highlight_hook
= XTreassert_line_highlight
;
14185 mouse_position_hook
= XTmouse_position
;
14186 frame_rehighlight_hook
= XTframe_rehighlight
;
14187 frame_raise_lower_hook
= XTframe_raise_lower
;
14188 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14189 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14190 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14191 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14192 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14194 scroll_region_ok
= 1; /* we'll scroll partial frames */
14195 char_ins_del_ok
= 1;
14196 line_ins_del_ok
= 1; /* we'll just blt 'em */
14197 fast_clear_end_of_line
= 1; /* X does this well */
14198 memory_below_frame
= 0; /* we don't remember what scrolls
14203 last_tool_bar_item
= -1;
14204 any_help_event_p
= 0;
14206 /* Try to use interrupt input; if we can't, then start polling. */
14207 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14209 #ifdef USE_X_TOOLKIT
14210 XtToolkitInitialize ();
14211 Xt_app_con
= XtCreateApplicationContext ();
14212 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14214 /* Install an asynchronous timer that processes Xt timeout events
14215 every 0.1s. This is necessary because some widget sets use
14216 timeouts internally, for example the LessTif menu bar, or the
14217 Xaw3d scroll bar. When Xt timouts aren't processed, these
14218 widgets don't behave normally. */
14220 EMACS_TIME interval
;
14221 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14222 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14226 #ifdef USE_TOOLKIT_SCROLL_BARS
14227 xaw3d_arrow_scroll
= False
;
14228 xaw3d_pick_top
= True
;
14231 /* Note that there is no real way portable across R3/R4 to get the
14232 original error handler. */
14233 XSetErrorHandler (x_error_handler
);
14234 XSetIOErrorHandler (x_io_error_quitter
);
14236 /* Disable Window Change signals; they are handled by X events. */
14238 signal (SIGWINCH
, SIG_DFL
);
14239 #endif /* ! defined (SIGWINCH) */
14241 signal (SIGPIPE
, x_connection_signal
);
14248 staticpro (&x_error_message_string
);
14249 x_error_message_string
= Qnil
;
14251 staticpro (&x_display_name_list
);
14252 x_display_name_list
= Qnil
;
14254 staticpro (&last_mouse_scroll_bar
);
14255 last_mouse_scroll_bar
= Qnil
;
14257 staticpro (&Qvendor_specific_keysyms
);
14258 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14260 staticpro (&last_mouse_press_frame
);
14261 last_mouse_press_frame
= Qnil
;
14264 staticpro (&help_echo
);
14265 help_echo_object
= Qnil
;
14266 staticpro (&help_echo_object
);
14267 help_echo_window
= Qnil
;
14268 staticpro (&help_echo_window
);
14269 previous_help_echo
= Qnil
;
14270 staticpro (&previous_help_echo
);
14271 help_echo_pos
= -1;
14273 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14274 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
14275 For example, if a block cursor is over a tab, it will be drawn as\n\
14276 wide as that tab on the display.");
14277 x_stretch_cursor_p
= 0;
14279 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14280 "What X toolkit scroll bars Emacs uses.\n\
14281 A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
14282 Otherwise, value is a symbol describing the X toolkit.");
14283 #ifdef USE_TOOLKIT_SCROLL_BARS
14285 Vx_toolkit_scroll_bars
= intern ("motif");
14286 #elif defined HAVE_XAW3D
14287 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14289 Vx_toolkit_scroll_bars
= intern ("xaw");
14292 Vx_toolkit_scroll_bars
= Qnil
;
14295 staticpro (&last_mouse_motion_frame
);
14296 last_mouse_motion_frame
= Qnil
;
14299 #endif /* not HAVE_X_WINDOWS */