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 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
261 int x_use_underline_position_properties
;
263 /* This is a chain of structures for all the X displays currently in
266 struct x_display_info
*x_display_list
;
268 /* This is a list of cons cells, each of the form (NAME
269 . FONT-LIST-CACHE), one for each element of x_display_list and in
270 the same order. NAME is the name of the frame. FONT-LIST-CACHE
271 records previous values returned by x-list-fonts. */
273 Lisp_Object x_display_name_list
;
275 /* Frame being updated by update_frame. This is declared in term.c.
276 This is set by update_begin and looked at by all the XT functions.
277 It is zero while not inside an update. In that case, the XT
278 functions assume that `selected_frame' is the frame to apply to. */
280 extern struct frame
*updating_frame
;
282 extern int waiting_for_input
;
284 /* This is a frame waiting to be auto-raised, within XTread_socket. */
286 struct frame
*pending_autoraise_frame
;
289 /* The application context for Xt use. */
290 XtAppContext Xt_app_con
;
291 static String Xt_default_resources
[] = {0};
292 #endif /* USE_X_TOOLKIT */
294 /* Nominal cursor position -- where to draw output.
295 HPOS and VPOS are window relative glyph matrix coordinates.
296 X and Y are window relative pixel coordinates. */
298 struct cursor_pos output_cursor
;
300 /* Non-zero means user is interacting with a toolkit scroll bar. */
302 static int toolkit_scroll_bar_interaction
;
306 Formerly, we used PointerMotionHintMask (in standard_event_mask)
307 so that we would have to call XQueryPointer after each MotionNotify
308 event to ask for another such event. However, this made mouse tracking
309 slow, and there was a bug that made it eventually stop.
311 Simply asking for MotionNotify all the time seems to work better.
313 In order to avoid asking for motion events and then throwing most
314 of them away or busy-polling the server for mouse positions, we ask
315 the server for pointer motion hints. This means that we get only
316 one event per group of mouse movements. "Groups" are delimited by
317 other kinds of events (focus changes and button clicks, for
318 example), or by XQueryPointer calls; when one of these happens, we
319 get another MotionNotify event the next time the mouse moves. This
320 is at least as efficient as getting motion events when mouse
321 tracking is on, and I suspect only negligibly worse when tracking
324 /* Where the mouse was last time we reported a mouse event. */
326 FRAME_PTR last_mouse_frame
;
327 static XRectangle last_mouse_glyph
;
328 static Lisp_Object last_mouse_press_frame
;
330 /* The scroll bar in which the last X motion event occurred.
332 If the last X motion event occurred in a scroll bar, we set this so
333 XTmouse_position can know whether to report a scroll bar motion or
336 If the last X motion event didn't occur in a scroll bar, we set
337 this to Qnil, to tell XTmouse_position to return an ordinary motion
340 static Lisp_Object last_mouse_scroll_bar
;
342 /* This is a hack. We would really prefer that XTmouse_position would
343 return the time associated with the position it returns, but there
344 doesn't seem to be any way to wrest the time-stamp from the server
345 along with the position query. So, we just keep track of the time
346 of the last movement we received, and return that in hopes that
347 it's somewhat accurate. */
349 static Time last_mouse_movement_time
;
351 /* Incremented by XTread_socket whenever it really tries to read
355 static int volatile input_signal_count
;
357 static int input_signal_count
;
360 /* Used locally within XTread_socket. */
362 static int x_noop_count
;
364 /* Initial values of argv and argc. */
366 extern char **initial_argv
;
367 extern int initial_argc
;
369 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
371 /* Tells if a window manager is present or not. */
373 extern Lisp_Object Vx_no_window_manager
;
375 extern Lisp_Object Qface
, Qmouse_face
;
379 /* A mask of extra modifier bits to put into every keyboard char. */
381 extern int extra_keyboard_modifiers
;
383 static Lisp_Object Qvendor_specific_keysyms
;
385 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
386 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
389 /* Enumeration for overriding/changing the face to use for drawing
390 glyphs in x_draw_glyphs. */
392 enum draw_glyphs_face
402 static int x_alloc_nearest_color_1
P_ ((Display
*, Colormap
, XColor
*));
403 static void x_set_window_size_1
P_ ((struct frame
*, int, int, int));
404 static const XColor
*x_color_cells
P_ ((Display
*, int *));
405 static void x_update_window_end
P_ ((struct window
*, int, int));
406 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
407 void x_delete_display
P_ ((struct x_display_info
*));
408 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
410 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
412 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
413 int *, int *, int *, int *, int));
414 static void set_output_cursor
P_ ((struct cursor_pos
*));
415 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
416 int *, int *, int *, int));
417 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
418 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
419 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
420 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
421 static void show_mouse_face
P_ ((struct x_display_info
*,
422 enum draw_glyphs_face
));
423 static int x_io_error_quitter
P_ ((Display
*));
424 int x_catch_errors
P_ ((Display
*));
425 void x_uncatch_errors
P_ ((Display
*, int));
426 void x_lower_frame
P_ ((struct frame
*));
427 void x_scroll_bar_clear
P_ ((struct frame
*));
428 int x_had_errors_p
P_ ((Display
*));
429 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
430 void x_raise_frame
P_ ((struct frame
*));
431 void x_set_window_size
P_ ((struct frame
*, int, int, int));
432 void x_wm_set_window_state
P_ ((struct frame
*, int));
433 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
434 void x_initialize
P_ ((void));
435 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
436 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
437 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
439 enum draw_glyphs_face
));
440 static void x_update_end
P_ ((struct frame
*));
441 static void XTframe_up_to_date
P_ ((struct frame
*));
442 static void XTreassert_line_highlight
P_ ((int, int));
443 static void x_change_line_highlight
P_ ((int, int, int, int));
444 static void XTset_terminal_modes
P_ ((void));
445 static void XTreset_terminal_modes
P_ ((void));
446 static void XTcursor_to
P_ ((int, int, int, int));
447 static void x_write_glyphs
P_ ((struct glyph
*, int));
448 static void x_clear_end_of_line
P_ ((int));
449 static void x_clear_frame
P_ ((void));
450 static void x_clear_cursor
P_ ((struct window
*));
451 static void frame_highlight
P_ ((struct frame
*));
452 static void frame_unhighlight
P_ ((struct frame
*));
453 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
454 static void XTframe_rehighlight
P_ ((struct frame
*));
455 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
456 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
457 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
458 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
460 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
461 static void expose_window_tree
P_ ((struct window
*, XRectangle
*));
462 static void expose_window
P_ ((struct window
*, XRectangle
*));
463 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
464 XRectangle
*, enum glyph_row_area
));
465 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
467 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
468 static void x_update_window_cursor
P_ ((struct window
*, int));
469 static void x_erase_phys_cursor
P_ ((struct window
*));
470 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
471 static void x_draw_bitmap
P_ ((struct window
*, struct glyph_row
*,
474 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
476 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
477 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
478 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
479 static void x_flush
P_ ((struct frame
*f
));
480 static void x_update_begin
P_ ((struct frame
*));
481 static void x_update_window_begin
P_ ((struct window
*));
482 static void x_draw_vertical_border
P_ ((struct window
*));
483 static void x_after_update_window_line
P_ ((struct glyph_row
*));
484 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
485 static void x_produce_stretch_glyph
P_ ((struct it
*));
486 static struct scroll_bar
*x_window_to_scroll_bar
P_ ((Window
));
487 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
488 enum scroll_bar_part
*,
489 Lisp_Object
*, Lisp_Object
*,
492 /* Flush display of frame F, or of all frames if F is null. */
501 Lisp_Object rest
, frame
;
502 FOR_EACH_FRAME (rest
, frame
)
503 x_flush (XFRAME (frame
));
505 else if (FRAME_X_P (f
))
506 XFlush (FRAME_X_DISPLAY (f
));
511 /* Remove calls to XFlush by defining XFlush to an empty replacement.
512 Calls to XFlush should be unnecessary because the X output buffer
513 is flushed automatically as needed by calls to XPending,
514 XNextEvent, or XWindowEvent according to the XFlush man page.
515 XTread_socket calls XPending. Removing XFlush improves
518 #define XFlush(DISPLAY) (void) 0
521 /***********************************************************************
523 ***********************************************************************/
527 /* This is a function useful for recording debugging information about
528 the sequence of occurrences in this file. */
536 struct record event_record
[100];
538 int event_record_index
;
540 record_event (locus
, type
)
544 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
545 event_record_index
= 0;
547 event_record
[event_record_index
].locus
= locus
;
548 event_record
[event_record_index
].type
= type
;
549 event_record_index
++;
556 /* Return the struct x_display_info corresponding to DPY. */
558 struct x_display_info
*
559 x_display_info_for_display (dpy
)
562 struct x_display_info
*dpyinfo
;
564 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
565 if (dpyinfo
->display
== dpy
)
573 /***********************************************************************
574 Starting and ending an update
575 ***********************************************************************/
577 /* Start an update of frame F. This function is installed as a hook
578 for update_begin, i.e. it is called when update_begin is called.
579 This function is called prior to calls to x_update_window_begin for
580 each window being updated. Currently, there is nothing to do here
581 because all interesting stuff is done on a window basis. */
591 /* Start update of window W. Set the global variable updated_window
592 to the window being updated and set output_cursor to the cursor
596 x_update_window_begin (w
)
599 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
600 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
603 set_output_cursor (&w
->cursor
);
607 if (f
== display_info
->mouse_face_mouse_frame
)
609 /* Don't do highlighting for mouse motion during the update. */
610 display_info
->mouse_face_defer
= 1;
612 /* If F needs to be redrawn, simply forget about any prior mouse
614 if (FRAME_GARBAGED_P (f
))
615 display_info
->mouse_face_window
= Qnil
;
617 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
618 their mouse_face_p flag set, which means that they are always
619 unequal to rows in a desired matrix which never have that
620 flag set. So, rows containing mouse-face glyphs are never
621 scrolled, and we don't have to switch the mouse highlight off
622 here to prevent it from being scrolled. */
624 /* Can we tell that this update does not affect the window
625 where the mouse highlight is? If so, no need to turn off.
626 Likewise, don't do anything if the frame is garbaged;
627 in that case, the frame's current matrix that we would use
628 is all wrong, and we will redisplay that line anyway. */
629 if (!NILP (display_info
->mouse_face_window
)
630 && w
== XWINDOW (display_info
->mouse_face_window
))
634 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
635 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
638 if (i
< w
->desired_matrix
->nrows
)
639 clear_mouse_face (display_info
);
648 /* Draw a vertical window border to the right of window W if W doesn't
649 have vertical scroll bars. */
652 x_draw_vertical_border (w
)
655 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
657 /* Redraw borders between horizontally adjacent windows. Don't
658 do it for frames with vertical scroll bars because either the
659 right scroll bar of a window, or the left scroll bar of its
660 neighbor will suffice as a border. */
661 if (!WINDOW_RIGHTMOST_P (w
)
662 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
666 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
667 x1
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
670 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
671 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
676 /* End update of window W (which is equal to updated_window).
678 Draw vertical borders between horizontally adjacent windows, and
679 display W's cursor if CURSOR_ON_P is non-zero.
681 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
682 glyphs in mouse-face were overwritten. In that case we have to
683 make sure that the mouse-highlight is properly redrawn.
685 W may be a menu bar pseudo-window in case we don't have X toolkit
686 support. Such windows don't have a cursor, so don't display it
690 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
692 int cursor_on_p
, mouse_face_overwritten_p
;
694 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
696 if (!w
->pseudo_window_p
)
701 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
703 output_cursor
.x
, output_cursor
.y
);
705 x_draw_vertical_border (w
);
709 /* If a row with mouse-face was overwritten, arrange for
710 XTframe_up_to_date to redisplay the mouse highlight. */
711 if (mouse_face_overwritten_p
)
713 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
714 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
715 dpyinfo
->mouse_face_window
= Qnil
;
718 updated_window
= NULL
;
722 /* End update of frame F. This function is installed as a hook in
729 /* Mouse highlight may be displayed again. */
730 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
733 XFlush (FRAME_X_DISPLAY (f
));
738 /* This function is called from various places in xdisp.c whenever a
739 complete update has been performed. The global variable
740 updated_window is not available here. */
743 XTframe_up_to_date (f
)
748 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
750 if (dpyinfo
->mouse_face_deferred_gc
751 || f
== dpyinfo
->mouse_face_mouse_frame
)
754 if (dpyinfo
->mouse_face_mouse_frame
)
755 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
756 dpyinfo
->mouse_face_mouse_x
,
757 dpyinfo
->mouse_face_mouse_y
);
758 dpyinfo
->mouse_face_deferred_gc
= 0;
765 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
766 arrow bitmaps, or clear the areas where they would be displayed
767 before DESIRED_ROW is made current. The window being updated is
768 found in updated_window. This function It is called from
769 update_window_line only if it is known that there are differences
770 between bitmaps to be drawn between current row and DESIRED_ROW. */
773 x_after_update_window_line (desired_row
)
774 struct glyph_row
*desired_row
;
776 struct window
*w
= updated_window
;
780 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
786 x_draw_row_bitmaps (w
, desired_row
);
788 /* When a window has disappeared, make sure that no rest of
789 full-width rows stays visible in the internal border. */
790 if (windows_or_buffers_changed
791 && (f
= XFRAME (w
->frame
),
792 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
795 int height
= desired_row
->visible_height
;
796 int x
= (window_box_right (w
, -1)
797 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
798 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
800 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
801 x
, y
, width
, height
, False
);
809 /* Draw the bitmap WHICH in one of the areas to the left or right of
810 window W. ROW is the glyph row for which to display the bitmap; it
811 determines the vertical position at which the bitmap has to be
815 x_draw_bitmap (w
, row
, which
)
817 struct glyph_row
*row
;
818 enum bitmap_type which
;
820 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
821 Display
*display
= FRAME_X_DISPLAY (f
);
822 Window window
= FRAME_X_WINDOW (f
);
826 GC gc
= f
->output_data
.x
->normal_gc
;
828 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
830 /* Must clip because of partially visible lines. */
831 x_clip_to_row (w
, row
, gc
, 1);
835 case LEFT_TRUNCATION_BITMAP
:
839 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
841 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
844 case OVERLAY_ARROW_BITMAP
:
848 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
850 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
853 case RIGHT_TRUNCATION_BITMAP
:
857 x
= window_box_right (w
, -1);
858 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
861 case CONTINUED_LINE_BITMAP
:
864 bits
= continued_bits
;
865 x
= window_box_right (w
, -1);
866 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
869 case CONTINUATION_LINE_BITMAP
:
870 wd
= continuation_width
;
871 h
= continuation_height
;
872 bits
= continuation_bits
;
873 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
875 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
882 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
884 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
891 /* Convert to frame coordinates. Set dy to the offset in the row to
892 start drawing the bitmap. */
893 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
894 dy
= (row
->height
- h
) / 2;
896 /* Draw the bitmap. I believe these small pixmaps can be cached
898 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
899 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
901 face
->background
, depth
);
902 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
903 XFreePixmap (display
, pixmap
);
904 XSetClipMask (display
, gc
, None
);
908 /* Draw flags bitmaps for glyph row ROW on window W. Call this
909 function with input blocked. */
912 x_draw_row_bitmaps (w
, row
)
914 struct glyph_row
*row
;
916 struct frame
*f
= XFRAME (w
->frame
);
917 enum bitmap_type bitmap
;
919 int header_line_height
= -1;
921 xassert (interrupt_input_blocked
);
923 /* If row is completely invisible, because of vscrolling, we
924 don't have to draw anything. */
925 if (row
->visible_height
<= 0)
928 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
929 PREPARE_FACE_FOR_DISPLAY (f
, face
);
931 /* Decide which bitmap to draw at the left side. */
932 if (row
->overlay_arrow_p
)
933 bitmap
= OVERLAY_ARROW_BITMAP
;
934 else if (row
->truncated_on_left_p
)
935 bitmap
= LEFT_TRUNCATION_BITMAP
;
936 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
937 bitmap
= CONTINUATION_LINE_BITMAP
;
938 else if (row
->indicate_empty_line_p
)
939 bitmap
= ZV_LINE_BITMAP
;
943 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
945 if (bitmap
== NO_BITMAP
946 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
947 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
949 /* If W has a vertical border to its left, don't draw over it. */
950 int border
= ((XFASTINT (w
->left
) > 0
951 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
953 int left
= window_box_left (w
, -1);
955 if (header_line_height
< 0)
956 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
958 /* In case the same realized face is used for bitmap areas and
959 for something displayed in the text (e.g. face `region' on
960 mono-displays, the fill style may have been changed to
961 FillSolid in x_draw_glyph_string_background. */
963 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
965 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
967 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
970 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
972 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
974 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
975 row
->visible_height
);
977 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
980 /* Draw the left bitmap. */
981 if (bitmap
!= NO_BITMAP
)
982 x_draw_bitmap (w
, row
, bitmap
);
984 /* Decide which bitmap to draw at the right side. */
985 if (row
->truncated_on_right_p
)
986 bitmap
= RIGHT_TRUNCATION_BITMAP
;
987 else if (row
->continued_p
)
988 bitmap
= CONTINUED_LINE_BITMAP
;
992 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
994 if (bitmap
== NO_BITMAP
995 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
996 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
998 int right
= window_box_right (w
, -1);
1000 if (header_line_height
< 0)
1001 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1003 /* In case the same realized face is used for bitmap areas and
1004 for something displayed in the text (e.g. face `region' on
1005 mono-displays, the fill style may have been changed to
1006 FillSolid in x_draw_glyph_string_background. */
1008 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1010 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1011 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1014 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1016 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
1017 row
->visible_height
);
1019 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1022 /* Draw the right bitmap. */
1023 if (bitmap
!= NO_BITMAP
)
1024 x_draw_bitmap (w
, row
, bitmap
);
1028 /***********************************************************************
1030 ***********************************************************************/
1032 /* External interface to control of standout mode. Not used for X
1033 frames. Aborts when called. */
1036 XTreassert_line_highlight (new, vpos
)
1043 /* Call this when about to modify line at position VPOS and change
1044 whether it is highlighted. Not used for X frames. Aborts when
1048 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1049 int new_highlight
, vpos
, y
, first_unused_hpos
;
1055 /* This is called when starting Emacs and when restarting after
1056 suspend. When starting Emacs, no X window is mapped. And nothing
1057 must be done to Emacs's own window if it is suspended (though that
1061 XTset_terminal_modes ()
1065 /* This is called when exiting or suspending Emacs. Exiting will make
1066 the X-windows go away, and suspending requires no action. */
1069 XTreset_terminal_modes ()
1075 /***********************************************************************
1077 ***********************************************************************/
1079 /* Set the global variable output_cursor to CURSOR. All cursor
1080 positions are relative to updated_window. */
1083 set_output_cursor (cursor
)
1084 struct cursor_pos
*cursor
;
1086 output_cursor
.hpos
= cursor
->hpos
;
1087 output_cursor
.vpos
= cursor
->vpos
;
1088 output_cursor
.x
= cursor
->x
;
1089 output_cursor
.y
= cursor
->y
;
1093 /* Set a nominal cursor position.
1095 HPOS and VPOS are column/row positions in a window glyph matrix. X
1096 and Y are window text area relative pixel positions.
1098 If this is done during an update, updated_window will contain the
1099 window that is being updated and the position is the future output
1100 cursor position for that window. If updated_window is null, use
1101 selected_window and display the cursor at the given position. */
1104 XTcursor_to (vpos
, hpos
, y
, x
)
1105 int vpos
, hpos
, y
, x
;
1109 /* If updated_window is not set, work on selected_window. */
1113 w
= XWINDOW (selected_window
);
1115 /* Set the output cursor. */
1116 output_cursor
.hpos
= hpos
;
1117 output_cursor
.vpos
= vpos
;
1118 output_cursor
.x
= x
;
1119 output_cursor
.y
= y
;
1121 /* If not called as part of an update, really display the cursor.
1122 This will also set the cursor position of W. */
1123 if (updated_window
== NULL
)
1126 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1127 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1134 /***********************************************************************
1136 ***********************************************************************/
1138 /* Function prototypes of this page. */
1140 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1144 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1145 int, XChar2b
*, int));
1146 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1147 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1148 static void x_append_glyph
P_ ((struct it
*));
1149 static void x_append_composite_glyph
P_ ((struct it
*));
1150 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1152 static void x_produce_glyphs
P_ ((struct it
*));
1153 static void x_produce_image_glyph
P_ ((struct it
*it
));
1156 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1157 is not contained in the font. */
1159 static INLINE XCharStruct
*
1160 x_per_char_metric (font
, char2b
)
1164 /* The result metric information. */
1165 XCharStruct
*pcm
= NULL
;
1167 xassert (font
&& char2b
);
1169 if (font
->per_char
!= NULL
)
1171 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1173 /* min_char_or_byte2 specifies the linear character index
1174 corresponding to the first element of the per_char array,
1175 max_char_or_byte2 is the index of the last character. A
1176 character with non-zero CHAR2B->byte1 is not in the font.
1177 A character with byte2 less than min_char_or_byte2 or
1178 greater max_char_or_byte2 is not in the font. */
1179 if (char2b
->byte1
== 0
1180 && char2b
->byte2
>= font
->min_char_or_byte2
1181 && char2b
->byte2
<= font
->max_char_or_byte2
)
1182 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1186 /* If either min_byte1 or max_byte1 are nonzero, both
1187 min_char_or_byte2 and max_char_or_byte2 are less than
1188 256, and the 2-byte character index values corresponding
1189 to the per_char array element N (counting from 0) are:
1191 byte1 = N/D + min_byte1
1192 byte2 = N\D + min_char_or_byte2
1196 D = max_char_or_byte2 - min_char_or_byte2 + 1
1197 / = integer division
1198 \ = integer modulus */
1199 if (char2b
->byte1
>= font
->min_byte1
1200 && char2b
->byte1
<= font
->max_byte1
1201 && char2b
->byte2
>= font
->min_char_or_byte2
1202 && char2b
->byte2
<= font
->max_char_or_byte2
)
1204 pcm
= (font
->per_char
1205 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1206 * (char2b
->byte1
- font
->min_byte1
))
1207 + (char2b
->byte2
- font
->min_char_or_byte2
));
1213 /* If the per_char pointer is null, all glyphs between the first
1214 and last character indexes inclusive have the same
1215 information, as given by both min_bounds and max_bounds. */
1216 if (char2b
->byte2
>= font
->min_char_or_byte2
1217 && char2b
->byte2
<= font
->max_char_or_byte2
)
1218 pcm
= &font
->max_bounds
;
1221 return ((pcm
== NULL
1222 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1227 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1228 the two-byte form of C. Encoding is returned in *CHAR2B. */
1231 x_encode_char (c
, char2b
, font_info
)
1234 struct font_info
*font_info
;
1236 int charset
= CHAR_CHARSET (c
);
1237 XFontStruct
*font
= font_info
->font
;
1239 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1240 This may be either a program in a special encoder language or a
1242 if (font_info
->font_encoder
)
1244 /* It's a program. */
1245 struct ccl_program
*ccl
= font_info
->font_encoder
;
1247 if (CHARSET_DIMENSION (charset
) == 1)
1249 ccl
->reg
[0] = charset
;
1250 ccl
->reg
[1] = char2b
->byte2
;
1254 ccl
->reg
[0] = charset
;
1255 ccl
->reg
[1] = char2b
->byte1
;
1256 ccl
->reg
[2] = char2b
->byte2
;
1259 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1261 /* We assume that MSBs are appropriately set/reset by CCL
1263 if (font
->max_byte1
== 0) /* 1-byte font */
1264 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1266 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1268 else if (font_info
->encoding
[charset
])
1270 /* Fixed encoding scheme. See fontset.h for the meaning of the
1271 encoding numbers. */
1272 int enc
= font_info
->encoding
[charset
];
1274 if ((enc
== 1 || enc
== 2)
1275 && CHARSET_DIMENSION (charset
) == 2)
1276 char2b
->byte1
|= 0x80;
1278 if (enc
== 1 || enc
== 3)
1279 char2b
->byte2
|= 0x80;
1284 /* Get face and two-byte form of character C in face FACE_ID on frame
1285 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1286 means we want to display multibyte text. Value is a pointer to a
1287 realized face that is ready for display. */
1289 static INLINE
struct face
*
1290 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1296 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1300 /* Unibyte case. We don't have to encode, but we have to make
1301 sure to use a face suitable for unibyte. */
1304 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1305 face
= FACE_FROM_ID (f
, face_id
);
1307 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1309 /* Case of ASCII in a face known to fit ASCII. */
1315 int c1
, c2
, charset
;
1317 /* Split characters into bytes. If c2 is -1 afterwards, C is
1318 really a one-byte character so that byte1 is zero. */
1319 SPLIT_CHAR (c
, charset
, c1
, c2
);
1321 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1323 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1325 /* Maybe encode the character in *CHAR2B. */
1326 if (face
->font
!= NULL
)
1328 struct font_info
*font_info
1329 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1331 x_encode_char (c
, char2b
, font_info
);
1335 /* Make sure X resources of the face are allocated. */
1336 xassert (face
!= NULL
);
1337 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1343 /* Get face and two-byte form of character glyph GLYPH on frame F.
1344 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1345 a pointer to a realized face that is ready for display. */
1347 static INLINE
struct face
*
1348 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1350 struct glyph
*glyph
;
1356 xassert (glyph
->type
== CHAR_GLYPH
);
1357 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1362 if (!glyph
->multibyte_p
)
1364 /* Unibyte case. We don't have to encode, but we have to make
1365 sure to use a face suitable for unibyte. */
1367 char2b
->byte2
= glyph
->u
.ch
;
1369 else if (glyph
->u
.ch
< 128
1370 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1372 /* Case of ASCII in a face known to fit ASCII. */
1374 char2b
->byte2
= glyph
->u
.ch
;
1378 int c1
, c2
, charset
;
1380 /* Split characters into bytes. If c2 is -1 afterwards, C is
1381 really a one-byte character so that byte1 is zero. */
1382 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1384 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1386 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1388 /* Maybe encode the character in *CHAR2B. */
1389 if (charset
!= CHARSET_ASCII
)
1391 struct font_info
*font_info
1392 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1395 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1398 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1403 /* Make sure X resources of the face are allocated. */
1404 xassert (face
!= NULL
);
1405 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1410 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1411 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1417 struct glyph
*glyph
;
1418 enum glyph_row_area area
= it
->area
;
1420 xassert (it
->glyph_row
);
1421 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1423 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1424 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1426 glyph
->charpos
= CHARPOS (it
->position
);
1427 glyph
->object
= it
->object
;
1428 glyph
->pixel_width
= it
->pixel_width
;
1429 glyph
->voffset
= it
->voffset
;
1430 glyph
->type
= CHAR_GLYPH
;
1431 glyph
->multibyte_p
= it
->multibyte_p
;
1432 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1433 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1434 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1435 || it
->phys_descent
> it
->descent
);
1436 glyph
->padding_p
= 0;
1437 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1438 glyph
->face_id
= it
->face_id
;
1439 glyph
->u
.ch
= it
->char_to_display
;
1440 ++it
->glyph_row
->used
[area
];
1444 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1445 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1448 x_append_composite_glyph (it
)
1451 struct glyph
*glyph
;
1452 enum glyph_row_area area
= it
->area
;
1454 xassert (it
->glyph_row
);
1456 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1457 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1459 glyph
->charpos
= CHARPOS (it
->position
);
1460 glyph
->object
= it
->object
;
1461 glyph
->pixel_width
= it
->pixel_width
;
1462 glyph
->voffset
= it
->voffset
;
1463 glyph
->type
= COMPOSITE_GLYPH
;
1464 glyph
->multibyte_p
= it
->multibyte_p
;
1465 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1466 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1467 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1468 || it
->phys_descent
> it
->descent
);
1469 glyph
->padding_p
= 0;
1470 glyph
->glyph_not_available_p
= 0;
1471 glyph
->face_id
= it
->face_id
;
1472 glyph
->u
.cmp_id
= it
->cmp_id
;
1473 ++it
->glyph_row
->used
[area
];
1478 /* Change IT->ascent and IT->height according to the setting of
1482 take_vertical_position_into_account (it
)
1487 if (it
->voffset
< 0)
1488 /* Increase the ascent so that we can display the text higher
1490 it
->ascent
+= abs (it
->voffset
);
1492 /* Increase the descent so that we can display the text lower
1494 it
->descent
+= it
->voffset
;
1499 /* Produce glyphs/get display metrics for the image IT is loaded with.
1500 See the description of struct display_iterator in dispextern.h for
1501 an overview of struct display_iterator. */
1504 x_produce_image_glyph (it
)
1510 xassert (it
->what
== IT_IMAGE
);
1512 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1513 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1516 /* Make sure X resources of the face and image are loaded. */
1517 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1518 prepare_image_for_display (it
->f
, img
);
1520 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1521 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1522 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1526 if (face
->box
!= FACE_NO_BOX
)
1528 if (face
->box_line_width
> 0)
1530 it
->ascent
+= face
->box_line_width
;
1531 it
->descent
+= face
->box_line_width
;
1534 if (it
->start_of_box_run_p
)
1535 it
->pixel_width
+= abs (face
->box_line_width
);
1536 if (it
->end_of_box_run_p
)
1537 it
->pixel_width
+= abs (face
->box_line_width
);
1540 take_vertical_position_into_account (it
);
1544 struct glyph
*glyph
;
1545 enum glyph_row_area area
= it
->area
;
1547 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1548 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1550 glyph
->charpos
= CHARPOS (it
->position
);
1551 glyph
->object
= it
->object
;
1552 glyph
->pixel_width
= it
->pixel_width
;
1553 glyph
->voffset
= it
->voffset
;
1554 glyph
->type
= IMAGE_GLYPH
;
1555 glyph
->multibyte_p
= it
->multibyte_p
;
1556 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1557 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1558 glyph
->overlaps_vertically_p
= 0;
1559 glyph
->padding_p
= 0;
1560 glyph
->glyph_not_available_p
= 0;
1561 glyph
->face_id
= it
->face_id
;
1562 glyph
->u
.img_id
= img
->id
;
1563 ++it
->glyph_row
->used
[area
];
1569 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1570 of the glyph, WIDTH and HEIGHT are the width and height of the
1571 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1572 ascent of the glyph (0 <= ASCENT <= 1). */
1575 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1581 struct glyph
*glyph
;
1582 enum glyph_row_area area
= it
->area
;
1584 xassert (ascent
>= 0 && ascent
<= 1);
1586 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1587 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1589 glyph
->charpos
= CHARPOS (it
->position
);
1590 glyph
->object
= object
;
1591 glyph
->pixel_width
= width
;
1592 glyph
->voffset
= it
->voffset
;
1593 glyph
->type
= STRETCH_GLYPH
;
1594 glyph
->multibyte_p
= it
->multibyte_p
;
1595 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1596 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1597 glyph
->overlaps_vertically_p
= 0;
1598 glyph
->padding_p
= 0;
1599 glyph
->glyph_not_available_p
= 0;
1600 glyph
->face_id
= it
->face_id
;
1601 glyph
->u
.stretch
.ascent
= height
* ascent
;
1602 glyph
->u
.stretch
.height
= height
;
1603 ++it
->glyph_row
->used
[area
];
1608 /* Produce a stretch glyph for iterator IT. IT->object is the value
1609 of the glyph property displayed. The value must be a list
1610 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1613 1. `:width WIDTH' specifies that the space should be WIDTH *
1614 canonical char width wide. WIDTH may be an integer or floating
1617 2. `:relative-width FACTOR' specifies that the width of the stretch
1618 should be computed from the width of the first character having the
1619 `glyph' property, and should be FACTOR times that width.
1621 3. `:align-to HPOS' specifies that the space should be wide enough
1622 to reach HPOS, a value in canonical character units.
1624 Exactly one of the above pairs must be present.
1626 4. `:height HEIGHT' specifies that the height of the stretch produced
1627 should be HEIGHT, measured in canonical character units.
1629 5. `:relative-height FACTOR' specifies that the height of the the
1630 stretch should be FACTOR times the height of the characters having
1633 Either none or exactly one of 4 or 5 must be present.
1635 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1636 of the stretch should be used for the ascent of the stretch.
1637 ASCENT must be in the range 0 <= ASCENT <= 100. */
1640 ((INTEGERP (X) || FLOATP (X)) \
1646 x_produce_stretch_glyph (it
)
1649 /* (space :width WIDTH :height HEIGHT. */
1651 extern Lisp_Object Qspace
;
1653 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1654 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1655 extern Lisp_Object QCalign_to
;
1656 Lisp_Object prop
, plist
;
1657 double width
= 0, height
= 0, ascent
= 0;
1658 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1659 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1661 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1663 /* List should start with `space'. */
1664 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1665 plist
= XCDR (it
->object
);
1667 /* Compute the width of the stretch. */
1668 if (prop
= Fplist_get (plist
, QCwidth
),
1670 /* Absolute width `:width WIDTH' specified and valid. */
1671 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1672 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1675 /* Relative width `:relative-width FACTOR' specified and valid.
1676 Compute the width of the characters having the `glyph'
1679 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1682 if (it
->multibyte_p
)
1684 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1685 - IT_BYTEPOS (*it
));
1686 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1689 it2
.c
= *p
, it2
.len
= 1;
1691 it2
.glyph_row
= NULL
;
1692 it2
.what
= IT_CHARACTER
;
1693 x_produce_glyphs (&it2
);
1694 width
= NUMVAL (prop
) * it2
.pixel_width
;
1696 else if (prop
= Fplist_get (plist
, QCalign_to
),
1698 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1700 /* Nothing specified -> width defaults to canonical char width. */
1701 width
= CANON_X_UNIT (it
->f
);
1703 /* Compute height. */
1704 if (prop
= Fplist_get (plist
, QCheight
),
1706 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1707 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1709 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1711 height
= FONT_HEIGHT (font
);
1713 /* Compute percentage of height used for ascent. If
1714 `:ascent ASCENT' is present and valid, use that. Otherwise,
1715 derive the ascent from the font in use. */
1716 if (prop
= Fplist_get (plist
, QCascent
),
1717 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1718 ascent
= NUMVAL (prop
) / 100.0;
1720 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1729 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1730 if (!STRINGP (object
))
1731 object
= it
->w
->buffer
;
1732 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1735 it
->pixel_width
= width
;
1736 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1737 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1740 if (face
->box
!= FACE_NO_BOX
)
1742 if (face
->box_line_width
> 0)
1744 it
->ascent
+= face
->box_line_width
;
1745 it
->descent
+= face
->box_line_width
;
1748 if (it
->start_of_box_run_p
)
1749 it
->pixel_width
+= abs (face
->box_line_width
);
1750 if (it
->end_of_box_run_p
)
1751 it
->pixel_width
+= abs (face
->box_line_width
);
1754 take_vertical_position_into_account (it
);
1757 /* Return proper value to be used as baseline offset of font that has
1758 ASCENT and DESCENT to draw characters by the font at the vertical
1759 center of the line of frame F.
1761 Here, out task is to find the value of BOFF in the following figure;
1763 -------------------------+-----------+-
1764 -+-+---------+-+ | |
1766 | | | | F_ASCENT F_HEIGHT
1769 | | |-|-+------+-----------|------- baseline
1771 | |---------|-+-+ | |
1773 -+-+---------+-+ F_DESCENT |
1774 -------------------------+-----------+-
1776 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1777 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1778 DESCENT = FONT->descent
1779 HEIGHT = FONT_HEIGHT (FONT)
1780 F_DESCENT = (F->output_data.x->font->descent
1781 - F->output_data.x->baseline_offset)
1782 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1785 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1787 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1788 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1789 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1791 /* Produce glyphs/get display metrics for the display element IT is
1792 loaded with. See the description of struct display_iterator in
1793 dispextern.h for an overview of struct display_iterator. */
1796 x_produce_glyphs (it
)
1799 it
->glyph_not_available_p
= 0;
1801 if (it
->what
== IT_CHARACTER
)
1805 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1807 int font_not_found_p
;
1808 struct font_info
*font_info
;
1809 int boff
; /* baseline offset */
1810 /* We may change it->multibyte_p upon unibyte<->multibyte
1811 conversion. So, save the current value now and restore it
1814 Note: It seems that we don't have to record multibyte_p in
1815 struct glyph because the character code itself tells if or
1816 not the character is multibyte. Thus, in the future, we must
1817 consider eliminating the field `multibyte_p' in the struct
1820 int saved_multibyte_p
= it
->multibyte_p
;
1822 /* Maybe translate single-byte characters to multibyte, or the
1824 it
->char_to_display
= it
->c
;
1825 if (!ASCII_BYTE_P (it
->c
))
1827 if (unibyte_display_via_language_environment
1828 && SINGLE_BYTE_CHAR_P (it
->c
)
1830 || !NILP (Vnonascii_translation_table
)))
1832 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1833 it
->multibyte_p
= 1;
1834 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1835 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1837 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1838 && !it
->multibyte_p
)
1840 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1841 it
->multibyte_p
= 0;
1842 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1843 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1847 /* Get font to use. Encode IT->char_to_display. */
1848 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1849 it
->face_id
, &char2b
,
1853 /* When no suitable font found, use the default font. */
1854 font_not_found_p
= font
== NULL
;
1855 if (font_not_found_p
)
1857 font
= FRAME_FONT (it
->f
);
1858 boff
= it
->f
->output_data
.x
->baseline_offset
;
1863 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1864 boff
= font_info
->baseline_offset
;
1865 if (font_info
->vertical_centering
)
1866 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1869 if (it
->char_to_display
>= ' '
1870 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1872 /* Either unibyte or ASCII. */
1877 pcm
= x_per_char_metric (font
, &char2b
);
1878 it
->ascent
= font
->ascent
+ boff
;
1879 it
->descent
= font
->descent
- boff
;
1883 it
->phys_ascent
= pcm
->ascent
+ boff
;
1884 it
->phys_descent
= pcm
->descent
- boff
;
1885 it
->pixel_width
= pcm
->width
;
1889 it
->glyph_not_available_p
= 1;
1890 it
->phys_ascent
= font
->ascent
+ boff
;
1891 it
->phys_descent
= font
->descent
- boff
;
1892 it
->pixel_width
= FONT_WIDTH (font
);
1895 /* If this is a space inside a region of text with
1896 `space-width' property, change its width. */
1897 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1899 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1901 /* If face has a box, add the box thickness to the character
1902 height. If character has a box line to the left and/or
1903 right, add the box line width to the character's width. */
1904 if (face
->box
!= FACE_NO_BOX
)
1906 int thick
= face
->box_line_width
;
1910 it
->ascent
+= thick
;
1911 it
->descent
+= thick
;
1916 if (it
->start_of_box_run_p
)
1917 it
->pixel_width
+= thick
;
1918 if (it
->end_of_box_run_p
)
1919 it
->pixel_width
+= thick
;
1922 /* If face has an overline, add the height of the overline
1923 (1 pixel) and a 1 pixel margin to the character height. */
1924 if (face
->overline_p
)
1927 take_vertical_position_into_account (it
);
1929 /* If we have to actually produce glyphs, do it. */
1934 /* Translate a space with a `space-width' property
1935 into a stretch glyph. */
1936 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1937 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1938 it
->ascent
+ it
->descent
, ascent
);
1941 x_append_glyph (it
);
1943 /* If characters with lbearing or rbearing are displayed
1944 in this line, record that fact in a flag of the
1945 glyph row. This is used to optimize X output code. */
1946 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1947 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1950 else if (it
->char_to_display
== '\n')
1952 /* A newline has no width but we need the height of the line. */
1953 it
->pixel_width
= 0;
1955 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1956 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1958 if (face
->box
!= FACE_NO_BOX
1959 && face
->box_line_width
> 0)
1961 it
->ascent
+= face
->box_line_width
;
1962 it
->descent
+= face
->box_line_width
;
1965 else if (it
->char_to_display
== '\t')
1967 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1968 int x
= it
->current_x
+ it
->continuation_lines_width
;
1969 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1971 /* If the distance from the current position to the next tab
1972 stop is less than a canonical character width, use the
1973 tab stop after that. */
1974 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1975 next_tab_x
+= tab_width
;
1977 it
->pixel_width
= next_tab_x
- x
;
1979 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1980 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1984 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1985 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1986 it
->ascent
+ it
->descent
, ascent
);
1991 /* A multi-byte character. Assume that the display width of the
1992 character is the width of the character multiplied by the
1993 width of the font. */
1995 /* If we found a font, this font should give us the right
1996 metrics. If we didn't find a font, use the frame's
1997 default font and calculate the width of the character
1998 from the charset width; this is what old redisplay code
2000 pcm
= x_per_char_metric (font
, &char2b
);
2001 if (font_not_found_p
|| !pcm
)
2003 int charset
= CHAR_CHARSET (it
->char_to_display
);
2005 it
->glyph_not_available_p
= 1;
2006 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2007 * CHARSET_WIDTH (charset
));
2008 it
->phys_ascent
= font
->ascent
+ boff
;
2009 it
->phys_descent
= font
->descent
- boff
;
2013 it
->pixel_width
= pcm
->width
;
2014 it
->phys_ascent
= pcm
->ascent
+ boff
;
2015 it
->phys_descent
= pcm
->descent
- boff
;
2017 && (pcm
->lbearing
< 0
2018 || pcm
->rbearing
> pcm
->width
))
2019 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2022 it
->ascent
= font
->ascent
+ boff
;
2023 it
->descent
= font
->descent
- boff
;
2024 if (face
->box
!= FACE_NO_BOX
)
2026 int thick
= face
->box_line_width
;
2030 it
->ascent
+= thick
;
2031 it
->descent
+= thick
;
2036 if (it
->start_of_box_run_p
)
2037 it
->pixel_width
+= thick
;
2038 if (it
->end_of_box_run_p
)
2039 it
->pixel_width
+= thick
;
2042 /* If face has an overline, add the height of the overline
2043 (1 pixel) and a 1 pixel margin to the character height. */
2044 if (face
->overline_p
)
2047 take_vertical_position_into_account (it
);
2050 x_append_glyph (it
);
2052 it
->multibyte_p
= saved_multibyte_p
;
2054 else if (it
->what
== IT_COMPOSITION
)
2056 /* Note: A composition is represented as one glyph in the
2057 glyph matrix. There are no padding glyphs. */
2060 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2062 int font_not_found_p
;
2063 struct font_info
*font_info
;
2064 int boff
; /* baseline offset */
2065 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2067 /* Maybe translate single-byte characters to multibyte. */
2068 it
->char_to_display
= it
->c
;
2069 if (unibyte_display_via_language_environment
2070 && SINGLE_BYTE_CHAR_P (it
->c
)
2073 && !NILP (Vnonascii_translation_table
))))
2075 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2078 /* Get face and font to use. Encode IT->char_to_display. */
2079 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2080 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2081 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2082 it
->face_id
, &char2b
, it
->multibyte_p
);
2085 /* When no suitable font found, use the default font. */
2086 font_not_found_p
= font
== NULL
;
2087 if (font_not_found_p
)
2089 font
= FRAME_FONT (it
->f
);
2090 boff
= it
->f
->output_data
.x
->baseline_offset
;
2095 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2096 boff
= font_info
->baseline_offset
;
2097 if (font_info
->vertical_centering
)
2098 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2101 /* There are no padding glyphs, so there is only one glyph to
2102 produce for the composition. Important is that pixel_width,
2103 ascent and descent are the values of what is drawn by
2104 draw_glyphs (i.e. the values of the overall glyphs composed). */
2107 /* If we have not yet calculated pixel size data of glyphs of
2108 the composition for the current face font, calculate them
2109 now. Theoretically, we have to check all fonts for the
2110 glyphs, but that requires much time and memory space. So,
2111 here we check only the font of the first glyph. This leads
2112 to incorrect display very rarely, and C-l (recenter) can
2113 correct the display anyway. */
2114 if (cmp
->font
!= (void *) font
)
2116 /* Ascent and descent of the font of the first character of
2117 this composition (adjusted by baseline offset). Ascent
2118 and descent of overall glyphs should not be less than
2119 them respectively. */
2120 int font_ascent
= font
->ascent
+ boff
;
2121 int font_descent
= font
->descent
- boff
;
2122 /* Bounding box of the overall glyphs. */
2123 int leftmost
, rightmost
, lowest
, highest
;
2124 int i
, width
, ascent
, descent
;
2126 cmp
->font
= (void *) font
;
2128 /* Initialize the bounding box. */
2130 && (pcm
= x_per_char_metric (font
, &char2b
)))
2133 ascent
= pcm
->ascent
;
2134 descent
= pcm
->descent
;
2138 width
= FONT_WIDTH (font
);
2139 ascent
= font
->ascent
;
2140 descent
= font
->descent
;
2144 lowest
= - descent
+ boff
;
2145 highest
= ascent
+ boff
;
2149 && font_info
->default_ascent
2150 && CHAR_TABLE_P (Vuse_default_ascent
)
2151 && !NILP (Faref (Vuse_default_ascent
,
2152 make_number (it
->char_to_display
))))
2153 highest
= font_info
->default_ascent
+ boff
;
2155 /* Draw the first glyph at the normal position. It may be
2156 shifted to right later if some other glyphs are drawn at
2158 cmp
->offsets
[0] = 0;
2159 cmp
->offsets
[1] = boff
;
2161 /* Set cmp->offsets for the remaining glyphs. */
2162 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2164 int left
, right
, btm
, top
;
2165 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2166 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2168 face
= FACE_FROM_ID (it
->f
, face_id
);
2169 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2174 font
= FRAME_FONT (it
->f
);
2175 boff
= it
->f
->output_data
.x
->baseline_offset
;
2181 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2182 boff
= font_info
->baseline_offset
;
2183 if (font_info
->vertical_centering
)
2184 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2188 && (pcm
= x_per_char_metric (font
, &char2b
)))
2191 ascent
= pcm
->ascent
;
2192 descent
= pcm
->descent
;
2196 width
= FONT_WIDTH (font
);
2201 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2203 /* Relative composition with or without
2205 left
= (leftmost
+ rightmost
- width
) / 2;
2206 btm
= - descent
+ boff
;
2207 if (font_info
&& font_info
->relative_compose
2208 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2209 || NILP (Faref (Vignore_relative_composition
,
2210 make_number (ch
)))))
2213 if (- descent
>= font_info
->relative_compose
)
2214 /* One extra pixel between two glyphs. */
2216 else if (ascent
<= 0)
2217 /* One extra pixel between two glyphs. */
2218 btm
= lowest
- 1 - ascent
- descent
;
2223 /* A composition rule is specified by an integer
2224 value that encodes global and new reference
2225 points (GREF and NREF). GREF and NREF are
2226 specified by numbers as below:
2234 ---3---4---5--- baseline
2236 6---7---8 -- descent
2238 int rule
= COMPOSITION_RULE (cmp
, i
);
2239 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2241 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2242 grefx
= gref
% 3, nrefx
= nref
% 3;
2243 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2246 + grefx
* (rightmost
- leftmost
) / 2
2247 - nrefx
* width
/ 2);
2248 btm
= ((grefy
== 0 ? highest
2250 : grefy
== 2 ? lowest
2251 : (highest
+ lowest
) / 2)
2252 - (nrefy
== 0 ? ascent
+ descent
2253 : nrefy
== 1 ? descent
- boff
2255 : (ascent
+ descent
) / 2));
2258 cmp
->offsets
[i
* 2] = left
;
2259 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2261 /* Update the bounding box of the overall glyphs. */
2262 right
= left
+ width
;
2263 top
= btm
+ descent
+ ascent
;
2264 if (left
< leftmost
)
2266 if (right
> rightmost
)
2274 /* If there are glyphs whose x-offsets are negative,
2275 shift all glyphs to the right and make all x-offsets
2279 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2280 cmp
->offsets
[i
* 2] -= leftmost
;
2281 rightmost
-= leftmost
;
2284 cmp
->pixel_width
= rightmost
;
2285 cmp
->ascent
= highest
;
2286 cmp
->descent
= - lowest
;
2287 if (cmp
->ascent
< font_ascent
)
2288 cmp
->ascent
= font_ascent
;
2289 if (cmp
->descent
< font_descent
)
2290 cmp
->descent
= font_descent
;
2293 it
->pixel_width
= cmp
->pixel_width
;
2294 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2295 it
->descent
= it
->phys_descent
= cmp
->descent
;
2297 if (face
->box
!= FACE_NO_BOX
)
2299 int thick
= face
->box_line_width
;
2303 it
->ascent
+= thick
;
2304 it
->descent
+= thick
;
2309 if (it
->start_of_box_run_p
)
2310 it
->pixel_width
+= thick
;
2311 if (it
->end_of_box_run_p
)
2312 it
->pixel_width
+= thick
;
2315 /* If face has an overline, add the height of the overline
2316 (1 pixel) and a 1 pixel margin to the character height. */
2317 if (face
->overline_p
)
2320 take_vertical_position_into_account (it
);
2323 x_append_composite_glyph (it
);
2325 else if (it
->what
== IT_IMAGE
)
2326 x_produce_image_glyph (it
);
2327 else if (it
->what
== IT_STRETCH
)
2328 x_produce_stretch_glyph (it
);
2330 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2331 because this isn't true for images with `:ascent 100'. */
2332 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2333 if (it
->area
== TEXT_AREA
)
2334 it
->current_x
+= it
->pixel_width
;
2336 it
->descent
+= it
->extra_line_spacing
;
2338 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2339 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2340 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2341 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2345 /* Estimate the pixel height of the mode or top line on frame F.
2346 FACE_ID specifies what line's height to estimate. */
2349 x_estimate_mode_line_height (f
, face_id
)
2351 enum face_id face_id
;
2353 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2355 /* This function is called so early when Emacs starts that the face
2356 cache and mode line face are not yet initialized. */
2357 if (FRAME_FACE_CACHE (f
))
2359 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2363 height
= FONT_HEIGHT (face
->font
);
2364 if (face
->box_line_width
> 0)
2365 height
+= 2 * face
->box_line_width
;
2373 /***********************************************************************
2375 ***********************************************************************/
2377 /* A sequence of glyphs to be drawn in the same face.
2379 This data structure is not really completely X specific, so it
2380 could possibly, at least partially, be useful for other systems. It
2381 is currently not part of the external redisplay interface because
2382 it's not clear what other systems will need. */
2386 /* X-origin of the string. */
2389 /* Y-origin and y-position of the base line of this string. */
2392 /* The width of the string, not including a face extension. */
2395 /* The width of the string, including a face extension. */
2396 int background_width
;
2398 /* The height of this string. This is the height of the line this
2399 string is drawn in, and can be different from the height of the
2400 font the string is drawn in. */
2403 /* Number of pixels this string overwrites in front of its x-origin.
2404 This number is zero if the string has an lbearing >= 0; it is
2405 -lbearing, if the string has an lbearing < 0. */
2408 /* Number of pixels this string overwrites past its right-most
2409 nominal x-position, i.e. x + width. Zero if the string's
2410 rbearing is <= its nominal width, rbearing - width otherwise. */
2413 /* The frame on which the glyph string is drawn. */
2416 /* The window on which the glyph string is drawn. */
2419 /* X display and window for convenience. */
2423 /* The glyph row for which this string was built. It determines the
2424 y-origin and height of the string. */
2425 struct glyph_row
*row
;
2427 /* The area within row. */
2428 enum glyph_row_area area
;
2430 /* Characters to be drawn, and number of characters. */
2434 /* A face-override for drawing cursors, mouse face and similar. */
2435 enum draw_glyphs_face hl
;
2437 /* Face in which this string is to be drawn. */
2440 /* Font in which this string is to be drawn. */
2443 /* Font info for this string. */
2444 struct font_info
*font_info
;
2446 /* Non-null means this string describes (part of) a composition.
2447 All characters from char2b are drawn composed. */
2448 struct composition
*cmp
;
2450 /* Index of this glyph string's first character in the glyph
2451 definition of CMP. If this is zero, this glyph string describes
2452 the first character of a composition. */
2455 /* 1 means this glyph strings face has to be drawn to the right end
2456 of the window's drawing area. */
2457 unsigned extends_to_end_of_line_p
: 1;
2459 /* 1 means the background of this string has been drawn. */
2460 unsigned background_filled_p
: 1;
2462 /* 1 means glyph string must be drawn with 16-bit functions. */
2463 unsigned two_byte_p
: 1;
2465 /* 1 means that the original font determined for drawing this glyph
2466 string could not be loaded. The member `font' has been set to
2467 the frame's default font in this case. */
2468 unsigned font_not_found_p
: 1;
2470 /* 1 means that the face in which this glyph string is drawn has a
2472 unsigned stippled_p
: 1;
2474 /* 1 means only the foreground of this glyph string must be drawn,
2475 and we should use the physical height of the line this glyph
2476 string appears in as clip rect. */
2477 unsigned for_overlaps_p
: 1;
2479 /* The GC to use for drawing this glyph string. */
2482 /* A pointer to the first glyph in the string. This glyph
2483 corresponds to char2b[0]. Needed to draw rectangles if
2484 font_not_found_p is 1. */
2485 struct glyph
*first_glyph
;
2487 /* Image, if any. */
2490 struct glyph_string
*next
, *prev
;
2497 x_dump_glyph_string (s
)
2498 struct glyph_string
*s
;
2500 fprintf (stderr
, "glyph string\n");
2501 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2502 s
->x
, s
->y
, s
->width
, s
->height
);
2503 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2504 fprintf (stderr
, " hl = %d\n", s
->hl
);
2505 fprintf (stderr
, " left overhang = %d, right = %d\n",
2506 s
->left_overhang
, s
->right_overhang
);
2507 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2508 fprintf (stderr
, " extends to end of line = %d\n",
2509 s
->extends_to_end_of_line_p
);
2510 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2511 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2514 #endif /* GLYPH_DEBUG */
2518 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2519 struct glyph_string
**,
2520 struct glyph_string
*,
2521 struct glyph_string
*));
2522 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2523 struct glyph_string
**,
2524 struct glyph_string
*,
2525 struct glyph_string
*));
2526 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2527 struct glyph_string
**,
2528 struct glyph_string
*));
2529 static int x_left_overwritten
P_ ((struct glyph_string
*));
2530 static int x_left_overwriting
P_ ((struct glyph_string
*));
2531 static int x_right_overwritten
P_ ((struct glyph_string
*));
2532 static int x_right_overwriting
P_ ((struct glyph_string
*));
2533 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2535 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2536 XChar2b
*, struct window
*,
2538 enum glyph_row_area
, int,
2539 enum draw_glyphs_face
));
2540 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2541 enum glyph_row_area
, int, int,
2542 enum draw_glyphs_face
, int *, int *, int));
2543 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2544 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2545 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2547 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2548 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2549 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2550 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2551 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2552 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2553 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2554 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2555 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2557 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2558 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2559 unsigned long *, double, int));
2560 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2561 double, int, unsigned long));
2562 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2563 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2564 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2565 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2566 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2567 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2568 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2570 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2571 int, int, int, int, XRectangle
*));
2572 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2573 int, int, int, XRectangle
*));
2574 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2575 enum glyph_row_area
));
2576 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2578 enum glyph_row_area
, int, int));
2581 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2585 /* Append the list of glyph strings with head H and tail T to the list
2586 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2589 x_append_glyph_string_lists (head
, tail
, h
, t
)
2590 struct glyph_string
**head
, **tail
;
2591 struct glyph_string
*h
, *t
;
2605 /* Prepend the list of glyph strings with head H and tail T to the
2606 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2610 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2611 struct glyph_string
**head
, **tail
;
2612 struct glyph_string
*h
, *t
;
2626 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2627 Set *HEAD and *TAIL to the resulting list. */
2630 x_append_glyph_string (head
, tail
, s
)
2631 struct glyph_string
**head
, **tail
;
2632 struct glyph_string
*s
;
2634 s
->next
= s
->prev
= NULL
;
2635 x_append_glyph_string_lists (head
, tail
, s
, s
);
2639 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2644 struct glyph_string
*s
;
2646 if (s
->font
== FRAME_FONT (s
->f
)
2647 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2648 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2650 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2653 /* Cursor on non-default face: must merge. */
2657 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2658 xgcv
.foreground
= s
->face
->background
;
2660 /* If the glyph would be invisible, try a different foreground. */
2661 if (xgcv
.foreground
== xgcv
.background
)
2662 xgcv
.foreground
= s
->face
->foreground
;
2663 if (xgcv
.foreground
== xgcv
.background
)
2664 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2665 if (xgcv
.foreground
== xgcv
.background
)
2666 xgcv
.foreground
= s
->face
->foreground
;
2668 /* Make sure the cursor is distinct from text in this face. */
2669 if (xgcv
.background
== s
->face
->background
2670 && xgcv
.foreground
== s
->face
->foreground
)
2672 xgcv
.background
= s
->face
->foreground
;
2673 xgcv
.foreground
= s
->face
->background
;
2676 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2677 xgcv
.font
= s
->font
->fid
;
2678 xgcv
.graphics_exposures
= False
;
2679 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2681 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2682 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2685 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2686 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2688 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2693 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2696 x_set_mouse_face_gc (s
)
2697 struct glyph_string
*s
;
2702 /* What face has to be used last for the mouse face? */
2703 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2704 face
= FACE_FROM_ID (s
->f
, face_id
);
2706 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2708 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2709 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2711 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2712 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2713 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2715 /* If font in this face is same as S->font, use it. */
2716 if (s
->font
== s
->face
->font
)
2717 s
->gc
= s
->face
->gc
;
2720 /* Otherwise construct scratch_cursor_gc with values from FACE
2725 xgcv
.background
= s
->face
->background
;
2726 xgcv
.foreground
= s
->face
->foreground
;
2727 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2728 xgcv
.font
= s
->font
->fid
;
2729 xgcv
.graphics_exposures
= False
;
2730 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2732 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2733 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2736 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2737 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2739 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2742 xassert (s
->gc
!= 0);
2746 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2747 Faces to use in the mode line have already been computed when the
2748 matrix was built, so there isn't much to do, here. */
2751 x_set_mode_line_face_gc (s
)
2752 struct glyph_string
*s
;
2754 s
->gc
= s
->face
->gc
;
2758 /* Set S->gc of glyph string S for drawing that glyph string. Set
2759 S->stippled_p to a non-zero value if the face of S has a stipple
2763 x_set_glyph_string_gc (s
)
2764 struct glyph_string
*s
;
2766 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2768 if (s
->hl
== DRAW_NORMAL_TEXT
)
2770 s
->gc
= s
->face
->gc
;
2771 s
->stippled_p
= s
->face
->stipple
!= 0;
2773 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2775 x_set_mode_line_face_gc (s
);
2776 s
->stippled_p
= s
->face
->stipple
!= 0;
2778 else if (s
->hl
== DRAW_CURSOR
)
2780 x_set_cursor_gc (s
);
2783 else if (s
->hl
== DRAW_MOUSE_FACE
)
2785 x_set_mouse_face_gc (s
);
2786 s
->stippled_p
= s
->face
->stipple
!= 0;
2788 else if (s
->hl
== DRAW_IMAGE_RAISED
2789 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2791 s
->gc
= s
->face
->gc
;
2792 s
->stippled_p
= s
->face
->stipple
!= 0;
2796 s
->gc
= s
->face
->gc
;
2797 s
->stippled_p
= s
->face
->stipple
!= 0;
2800 /* GC must have been set. */
2801 xassert (s
->gc
!= 0);
2805 /* Return in *R the clipping rectangle for glyph string S. */
2808 x_get_glyph_string_clip_rect (s
, r
)
2809 struct glyph_string
*s
;
2812 if (s
->row
->full_width_p
)
2814 /* Draw full-width. X coordinates are relative to S->w->left. */
2815 int canon_x
= CANON_X_UNIT (s
->f
);
2817 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2818 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2820 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2822 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2823 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2827 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2829 /* Unless displaying a mode or menu bar line, which are always
2830 fully visible, clip to the visible part of the row. */
2831 if (s
->w
->pseudo_window_p
)
2832 r
->height
= s
->row
->visible_height
;
2834 r
->height
= s
->height
;
2838 /* This is a text line that may be partially visible. */
2839 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2840 r
->width
= window_box_width (s
->w
, s
->area
);
2841 r
->height
= s
->row
->visible_height
;
2844 /* Don't use S->y for clipping because it doesn't take partially
2845 visible lines into account. For example, it can be negative for
2846 partially visible lines at the top of a window. */
2847 if (!s
->row
->full_width_p
2848 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2849 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2851 r
->y
= max (0, s
->row
->y
);
2853 /* If drawing a tool-bar window, draw it over the internal border
2854 at the top of the window. */
2855 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2856 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2858 /* If S draws overlapping rows, it's sufficient to use the top and
2859 bottom of the window for clipping because this glyph string
2860 intentionally draws over other lines. */
2861 if (s
->for_overlaps_p
)
2863 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2864 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2867 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2871 /* Set clipping for output of glyph string S. S may be part of a mode
2872 line or menu if we don't have X toolkit support. */
2875 x_set_glyph_string_clipping (s
)
2876 struct glyph_string
*s
;
2879 x_get_glyph_string_clip_rect (s
, &r
);
2880 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2884 /* Compute left and right overhang of glyph string S. If S is a glyph
2885 string for a composition, assume overhangs don't exist. */
2888 x_compute_glyph_string_overhangs (s
)
2889 struct glyph_string
*s
;
2892 && s
->first_glyph
->type
== CHAR_GLYPH
)
2895 int direction
, font_ascent
, font_descent
;
2896 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2897 &font_ascent
, &font_descent
, &cs
);
2898 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2899 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2904 /* Compute overhangs and x-positions for glyph string S and its
2905 predecessors, or successors. X is the starting x-position for S.
2906 BACKWARD_P non-zero means process predecessors. */
2909 x_compute_overhangs_and_x (s
, x
, backward_p
)
2910 struct glyph_string
*s
;
2918 x_compute_glyph_string_overhangs (s
);
2928 x_compute_glyph_string_overhangs (s
);
2937 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2938 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2939 assumed to be zero. */
2942 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2943 struct glyph
*glyph
;
2949 if (glyph
->type
== CHAR_GLYPH
)
2953 struct font_info
*font_info
;
2957 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2959 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2961 && (pcm
= x_per_char_metric (font
, &char2b
)))
2963 if (pcm
->rbearing
> pcm
->width
)
2964 *right
= pcm
->rbearing
- pcm
->width
;
2965 if (pcm
->lbearing
< 0)
2966 *left
= -pcm
->lbearing
;
2972 /* Return the index of the first glyph preceding glyph string S that
2973 is overwritten by S because of S's left overhang. Value is -1
2974 if no glyphs are overwritten. */
2977 x_left_overwritten (s
)
2978 struct glyph_string
*s
;
2982 if (s
->left_overhang
)
2985 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2986 int first
= s
->first_glyph
- glyphs
;
2988 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2989 x
-= glyphs
[i
].pixel_width
;
3000 /* Return the index of the first glyph preceding glyph string S that
3001 is overwriting S because of its right overhang. Value is -1 if no
3002 glyph in front of S overwrites S. */
3005 x_left_overwriting (s
)
3006 struct glyph_string
*s
;
3009 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3010 int first
= s
->first_glyph
- glyphs
;
3014 for (i
= first
- 1; i
>= 0; --i
)
3017 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3020 x
-= glyphs
[i
].pixel_width
;
3027 /* Return the index of the last glyph following glyph string S that is
3028 not overwritten by S because of S's right overhang. Value is -1 if
3029 no such glyph is found. */
3032 x_right_overwritten (s
)
3033 struct glyph_string
*s
;
3037 if (s
->right_overhang
)
3040 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3041 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3042 int end
= s
->row
->used
[s
->area
];
3044 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3045 x
+= glyphs
[i
].pixel_width
;
3054 /* Return the index of the last glyph following glyph string S that
3055 overwrites S because of its left overhang. Value is negative
3056 if no such glyph is found. */
3059 x_right_overwriting (s
)
3060 struct glyph_string
*s
;
3063 int end
= s
->row
->used
[s
->area
];
3064 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3065 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3069 for (i
= first
; i
< end
; ++i
)
3072 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3075 x
+= glyphs
[i
].pixel_width
;
3082 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3085 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3086 struct glyph_string
*s
;
3090 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3091 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3092 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3093 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3097 /* Draw the background of glyph_string S. If S->background_filled_p
3098 is non-zero don't draw it. FORCE_P non-zero means draw the
3099 background even if it wouldn't be drawn normally. This is used
3100 when a string preceding S draws into the background of S, or S
3101 contains the first component of a composition. */
3104 x_draw_glyph_string_background (s
, force_p
)
3105 struct glyph_string
*s
;
3108 /* Nothing to do if background has already been drawn or if it
3109 shouldn't be drawn in the first place. */
3110 if (!s
->background_filled_p
)
3112 int box_line_width
= max (s
->face
->box_line_width
, 0);
3116 /* Fill background with a stipple pattern. */
3117 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3118 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3119 s
->y
+ box_line_width
,
3120 s
->background_width
,
3121 s
->height
- 2 * box_line_width
);
3122 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3123 s
->background_filled_p
= 1;
3125 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3126 || s
->font_not_found_p
3127 || s
->extends_to_end_of_line_p
3130 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3131 s
->background_width
,
3132 s
->height
- 2 * box_line_width
);
3133 s
->background_filled_p
= 1;
3139 /* Draw the foreground of glyph string S. */
3142 x_draw_glyph_string_foreground (s
)
3143 struct glyph_string
*s
;
3147 /* If first glyph of S has a left box line, start drawing the text
3148 of S to the right of that box line. */
3149 if (s
->face
->box
!= FACE_NO_BOX
3150 && s
->first_glyph
->left_box_line_p
)
3151 x
= s
->x
+ abs (s
->face
->box_line_width
);
3155 /* Draw characters of S as rectangles if S's font could not be
3157 if (s
->font_not_found_p
)
3159 for (i
= 0; i
< s
->nchars
; ++i
)
3161 struct glyph
*g
= s
->first_glyph
+ i
;
3162 XDrawRectangle (s
->display
, s
->window
,
3163 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3165 x
+= g
->pixel_width
;
3170 char *char1b
= (char *) s
->char2b
;
3171 int boff
= s
->font_info
->baseline_offset
;
3173 if (s
->font_info
->vertical_centering
)
3174 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3176 /* If we can use 8-bit functions, condense S->char2b. */
3178 for (i
= 0; i
< s
->nchars
; ++i
)
3179 char1b
[i
] = s
->char2b
[i
].byte2
;
3181 /* Draw text with XDrawString if background has already been
3182 filled. Otherwise, use XDrawImageString. (Note that
3183 XDrawImageString is usually faster than XDrawString.) Always
3184 use XDrawImageString when drawing the cursor so that there is
3185 no chance that characters under a box cursor are invisible. */
3186 if (s
->for_overlaps_p
3187 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3189 /* Draw characters with 16-bit or 8-bit functions. */
3191 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3192 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3194 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3195 s
->ybase
- boff
, char1b
, s
->nchars
);
3200 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3201 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3203 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3204 s
->ybase
- boff
, char1b
, s
->nchars
);
3209 /* Draw the foreground of composite glyph string S. */
3212 x_draw_composite_glyph_string_foreground (s
)
3213 struct glyph_string
*s
;
3217 /* If first glyph of S has a left box line, start drawing the text
3218 of S to the right of that box line. */
3219 if (s
->face
->box
!= FACE_NO_BOX
3220 && s
->first_glyph
->left_box_line_p
)
3221 x
= s
->x
+ abs (s
->face
->box_line_width
);
3225 /* S is a glyph string for a composition. S->gidx is the index of
3226 the first character drawn for glyphs of this composition.
3227 S->gidx == 0 means we are drawing the very first character of
3228 this composition. */
3230 /* Draw a rectangle for the composition if the font for the very
3231 first character of the composition could not be loaded. */
3232 if (s
->font_not_found_p
)
3235 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3236 s
->width
- 1, s
->height
- 1);
3240 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3241 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3242 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3243 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3249 #ifdef USE_X_TOOLKIT
3251 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3252 static Boolean cvt_string_to_pixel
P_ ((Display
*, XrmValue
*, Cardinal
*,
3253 XrmValue
*, XrmValue
*, XtPointer
*));
3254 static void cvt_pixel_dtor
P_ ((XtAppContext
, XrmValue
*, XtPointer
,
3255 XrmValue
*, Cardinal
*));
3258 /* Return the frame on which widget WIDGET is used.. Abort if frame
3259 cannot be determined. */
3261 static struct frame
*
3262 x_frame_of_widget (widget
)
3265 struct x_display_info
*dpyinfo
;
3269 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3271 /* Find the top-level shell of the widget. Note that this function
3272 can be called when the widget is not yet realized, so XtWindow
3273 (widget) == 0. That's the reason we can't simply use
3274 x_any_window_to_frame. */
3275 while (!XtIsTopLevelShell (widget
))
3276 widget
= XtParent (widget
);
3278 /* Look for a frame with that top-level widget. Allocate the color
3279 on that frame to get the right gamma correction value. */
3280 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3281 if (GC_FRAMEP (XCAR (tail
))
3282 && (f
= XFRAME (XCAR (tail
)),
3283 (f
->output_data
.nothing
!= 1
3284 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3285 && f
->output_data
.x
->widget
== widget
)
3292 /* Allocate the color COLOR->pixel on the screen and display of
3293 widget WIDGET in colormap CMAP. If an exact match cannot be
3294 allocated, try the nearest color available. Value is non-zero
3295 if successful. This is called from lwlib. */
3298 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3303 struct frame
*f
= x_frame_of_widget (widget
);
3304 return x_alloc_nearest_color (f
, cmap
, color
);
3308 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3309 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3310 If this produces the same color as PIXEL, try a color where all RGB
3311 values have DELTA added. Return the allocated color in *PIXEL.
3312 DISPLAY is the X display, CMAP is the colormap to operate on.
3313 Value is non-zero if successful. */
3316 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3320 unsigned long *pixel
;
3324 struct frame
*f
= x_frame_of_widget (widget
);
3325 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3329 /* Structure specifying which arguments should be passed by Xt to
3330 cvt_string_to_pixel. We want the widget's screen and colormap. */
3332 static XtConvertArgRec cvt_string_to_pixel_args
[] =
3334 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.screen
),
3336 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.colormap
),
3341 /* The address of this variable is returned by
3342 cvt_string_to_pixel. */
3344 static Pixel cvt_string_to_pixel_value
;
3347 /* Convert a color name to a pixel color.
3349 DPY is the display we are working on.
3351 ARGS is an array of *NARGS XrmValue structures holding additional
3352 information about the widget for which the conversion takes place.
3353 The contents of this array are determined by the specification
3354 in cvt_string_to_pixel_args.
3356 FROM is a pointer to an XrmValue which points to the color name to
3357 convert. TO is an XrmValue in which to return the pixel color.
3359 CLOSURE_RET is a pointer to user-data, in which we record if
3360 we allocated the color or not.
3362 Value is True if successful, False otherwise. */
3365 cvt_string_to_pixel (dpy
, args
, nargs
, from
, to
, closure_ret
)
3369 XrmValue
*from
, *to
;
3370 XtPointer
*closure_ret
;
3380 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3381 "wrongParameters", "cvt_string_to_pixel",
3383 "Screen and colormap args required", NULL
, NULL
);
3387 screen
= *(Screen
**) args
[0].addr
;
3388 cmap
= *(Colormap
*) args
[1].addr
;
3389 color_name
= (String
) from
->addr
;
3391 if (strcmp (color_name
, XtDefaultBackground
) == 0)
3393 *closure_ret
= (XtPointer
) False
;
3394 pixel
= WhitePixelOfScreen (screen
);
3396 else if (strcmp (color_name
, XtDefaultForeground
) == 0)
3398 *closure_ret
= (XtPointer
) False
;
3399 pixel
= BlackPixelOfScreen (screen
);
3401 else if (XParseColor (dpy
, cmap
, color_name
, &color
)
3402 && x_alloc_nearest_color_1 (dpy
, cmap
, &color
))
3404 pixel
= color
.pixel
;
3405 *closure_ret
= (XtPointer
) True
;
3410 Cardinal nparams
= 1;
3412 params
[0] = color_name
;
3413 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3414 "badValue", "cvt_string_to_pixel",
3415 "XtToolkitError", "Invalid color `%s'",
3420 if (to
->addr
!= NULL
)
3422 if (to
->size
< sizeof (Pixel
))
3424 to
->size
= sizeof (Pixel
);
3428 *(Pixel
*) to
->addr
= pixel
;
3432 cvt_string_to_pixel_value
= pixel
;
3433 to
->addr
= (XtPointer
) &cvt_string_to_pixel_value
;
3436 to
->size
= sizeof (Pixel
);
3441 /* Free a pixel color which was previously allocated via
3442 cvt_string_to_pixel. This is registered as the destructor
3443 for this type of resource via XtSetTypeConverter.
3445 APP is the application context in which we work.
3447 TO is a pointer to an XrmValue holding the color to free.
3448 CLOSURE is the value we stored in CLOSURE_RET for this color
3449 in cvt_string_to_pixel.
3451 ARGS and NARGS are like for cvt_string_to_pixel. */
3454 cvt_pixel_dtor (app
, to
, closure
, args
, nargs
)
3463 XtAppWarningMsg (app
, "wrongParameters", "cvt_pixel_dtor",
3465 "Screen and colormap arguments required",
3468 else if (closure
!= NULL
)
3470 /* We did allocate the pixel, so free it. */
3471 Screen
*screen
= *(Screen
**) args
[0].addr
;
3472 Colormap cmap
= *(Colormap
*) args
[1].addr
;
3473 x_free_dpy_colors (DisplayOfScreen (screen
), screen
, cmap
,
3474 (Pixel
*) to
->addr
, 1, 0);
3479 #endif /* USE_X_TOOLKIT */
3482 /* Value is an array of XColor structures for the contents of the
3483 color map of display DPY. Set *NCELLS to the size of the array.
3484 Note that this probably shouldn't be called for large color maps,
3485 say a 24-bit TrueColor map. */
3487 static const XColor
*
3488 x_color_cells (dpy
, ncells
)
3492 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3494 if (dpyinfo
->color_cells
== NULL
)
3496 Screen
*screen
= dpyinfo
->screen
;
3499 dpyinfo
->ncolor_cells
3500 = XDisplayCells (dpy
, XScreenNumberOfScreen (screen
));
3501 dpyinfo
->color_cells
3502 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3503 * sizeof *dpyinfo
->color_cells
);
3505 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3506 dpyinfo
->color_cells
[i
].pixel
= i
;
3508 XQueryColors (dpy
, dpyinfo
->cmap
,
3509 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3512 *ncells
= dpyinfo
->ncolor_cells
;
3513 return dpyinfo
->color_cells
;
3517 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3518 colors in COLORS. Use cached information, if available. */
3521 x_query_colors (f
, colors
, ncolors
)
3526 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3528 if (dpyinfo
->color_cells
)
3531 for (i
= 0; i
< ncolors
; ++i
)
3533 unsigned long pixel
= colors
[i
].pixel
;
3534 xassert (pixel
< dpyinfo
->ncolor_cells
);
3535 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3536 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3540 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3544 /* On frame F, translate pixel color to RGB values for the color in
3545 COLOR. Use cached information, if available. */
3548 x_query_color (f
, color
)
3552 x_query_colors (f
, color
, 1);
3556 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
3557 exact match can't be allocated, try the nearest color available.
3558 Value is non-zero if successful. Set *COLOR to the color
3562 x_alloc_nearest_color_1 (dpy
, cmap
, color
)
3569 rc
= XAllocColor (dpy
, cmap
, color
);
3572 /* If we got to this point, the colormap is full, so we're going
3573 to try to get the next closest color. The algorithm used is
3574 a least-squares matching, which is what X uses for closest
3575 color matching with StaticColor visuals. */
3577 unsigned long nearest_delta
= ~0;
3579 const XColor
*cells
= x_color_cells (dpy
, &ncells
);
3581 for (nearest
= i
= 0; i
< ncells
; ++i
)
3583 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3584 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3585 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3586 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3588 if (delta
< nearest_delta
)
3591 nearest_delta
= delta
;
3595 color
->red
= cells
[nearest
].red
;
3596 color
->green
= cells
[nearest
].green
;
3597 color
->blue
= cells
[nearest
].blue
;
3598 rc
= XAllocColor (dpy
, cmap
, color
);
3602 /* If allocation succeeded, and the allocated pixel color is not
3603 equal to a cached pixel color recorded earlier, there was a
3604 change in the colormap, so clear the color cache. */
3605 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3606 XColor
*cached_color
;
3608 if (dpyinfo
->color_cells
3609 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3610 (cached_color
->red
!= color
->red
3611 || cached_color
->blue
!= color
->blue
3612 || cached_color
->green
!= color
->green
)))
3614 xfree (dpyinfo
->color_cells
);
3615 dpyinfo
->color_cells
= NULL
;
3616 dpyinfo
->ncolor_cells
= 0;
3620 #ifdef DEBUG_X_COLORS
3622 register_color (color
->pixel
);
3623 #endif /* DEBUG_X_COLORS */
3629 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
3630 exact match can't be allocated, try the nearest color available.
3631 Value is non-zero if successful. Set *COLOR to the color
3635 x_alloc_nearest_color (f
, cmap
, color
)
3640 gamma_correct (f
, color
);
3641 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f
), cmap
, color
);
3645 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3646 It's necessary to do this instead of just using PIXEL directly to
3647 get color reference counts right. */
3650 x_copy_color (f
, pixel
)
3652 unsigned long pixel
;
3656 color
.pixel
= pixel
;
3658 x_query_color (f
, &color
);
3659 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3661 #ifdef DEBUG_X_COLORS
3662 register_color (pixel
);
3668 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3669 It's necessary to do this instead of just using PIXEL directly to
3670 get color reference counts right. */
3673 x_copy_dpy_color (dpy
, cmap
, pixel
)
3676 unsigned long pixel
;
3680 color
.pixel
= pixel
;
3682 XQueryColor (dpy
, cmap
, &color
);
3683 XAllocColor (dpy
, cmap
, &color
);
3685 #ifdef DEBUG_X_COLORS
3686 register_color (pixel
);
3692 /* Brightness beyond which a color won't have its highlight brightness
3695 Nominally, highlight colors for `3d' faces are calculated by
3696 brightening an object's color by a constant scale factor, but this
3697 doesn't yield good results for dark colors, so for colors who's
3698 brightness is less than this value (on a scale of 0-65535) have an
3699 use an additional additive factor.
3701 The value here is set so that the default menu-bar/mode-line color
3702 (grey75) will not have its highlights changed at all. */
3703 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
3706 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3707 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3708 If this produces the same color as PIXEL, try a color where all RGB
3709 values have DELTA added. Return the allocated color in *PIXEL.
3710 DISPLAY is the X display, CMAP is the colormap to operate on.
3711 Value is non-zero if successful. */
3714 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3718 unsigned long *pixel
;
3726 /* Get RGB color values. */
3727 color
.pixel
= *pixel
;
3728 x_query_color (f
, &color
);
3730 /* Change RGB values by specified FACTOR. Avoid overflow! */
3731 xassert (factor
>= 0);
3732 new.red
= min (0xffff, factor
* color
.red
);
3733 new.green
= min (0xffff, factor
* color
.green
);
3734 new.blue
= min (0xffff, factor
* color
.blue
);
3736 /* Calculate brightness of COLOR. */
3737 bright
= (2 * color
.red
+ 3 * color
.green
+ color
.blue
) / 6;
3739 /* We only boost colors that are darker than
3740 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3741 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3742 /* Make an additive adjustment to NEW, because it's dark enough so
3743 that scaling by FACTOR alone isn't enough. */
3745 /* How far below the limit this color is (0 - 1, 1 being darker). */
3746 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3747 /* The additive adjustment. */
3748 int min_delta
= delta
* dimness
* factor
/ 2;
3752 new.red
= max (0, new.red
- min_delta
);
3753 new.green
= max (0, new.green
- min_delta
);
3754 new.blue
= max (0, new.blue
- min_delta
);
3758 new.red
= min (0xffff, min_delta
+ new.red
);
3759 new.green
= min (0xffff, min_delta
+ new.green
);
3760 new.blue
= min (0xffff, min_delta
+ new.blue
);
3764 /* Try to allocate the color. */
3765 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3768 if (new.pixel
== *pixel
)
3770 /* If we end up with the same color as before, try adding
3771 delta to the RGB values. */
3772 x_free_colors (f
, &new.pixel
, 1);
3774 new.red
= min (0xffff, delta
+ color
.red
);
3775 new.green
= min (0xffff, delta
+ color
.green
);
3776 new.blue
= min (0xffff, delta
+ color
.blue
);
3777 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3788 /* Set up the foreground color for drawing relief lines of glyph
3789 string S. RELIEF is a pointer to a struct relief containing the GC
3790 with which lines will be drawn. Use a color that is FACTOR or
3791 DELTA lighter or darker than the relief's background which is found
3792 in S->f->output_data.x->relief_background. If such a color cannot
3793 be allocated, use DEFAULT_PIXEL, instead. */
3796 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3798 struct relief
*relief
;
3801 unsigned long default_pixel
;
3804 struct x_output
*di
= f
->output_data
.x
;
3805 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3806 unsigned long pixel
;
3807 unsigned long background
= di
->relief_background
;
3808 Colormap cmap
= FRAME_X_COLORMAP (f
);
3809 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3810 Display
*dpy
= FRAME_X_DISPLAY (f
);
3812 xgcv
.graphics_exposures
= False
;
3813 xgcv
.line_width
= 1;
3815 /* Free previously allocated color. The color cell will be reused
3816 when it has been freed as many times as it was allocated, so this
3817 doesn't affect faces using the same colors. */
3819 && relief
->allocated_p
)
3821 x_free_colors (f
, &relief
->pixel
, 1);
3822 relief
->allocated_p
= 0;
3825 /* Allocate new color. */
3826 xgcv
.foreground
= default_pixel
;
3828 if (dpyinfo
->n_planes
!= 1
3829 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3831 relief
->allocated_p
= 1;
3832 xgcv
.foreground
= relief
->pixel
= pixel
;
3835 if (relief
->gc
== 0)
3837 xgcv
.stipple
= dpyinfo
->gray
;
3839 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3842 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3846 /* Set up colors for the relief lines around glyph string S. */
3849 x_setup_relief_colors (s
)
3850 struct glyph_string
*s
;
3852 struct x_output
*di
= s
->f
->output_data
.x
;
3853 unsigned long color
;
3855 if (s
->face
->use_box_color_for_shadows_p
)
3856 color
= s
->face
->box_color
;
3861 /* Get the background color of the face. */
3862 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3863 color
= xgcv
.background
;
3866 if (di
->white_relief
.gc
== 0
3867 || color
!= di
->relief_background
)
3869 di
->relief_background
= color
;
3870 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3871 WHITE_PIX_DEFAULT (s
->f
));
3872 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3873 BLACK_PIX_DEFAULT (s
->f
));
3878 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3879 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3880 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3881 relief. LEFT_P non-zero means draw a relief on the left side of
3882 the rectangle. RIGHT_P non-zero means draw a relief on the right
3883 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3887 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3888 raised_p
, left_p
, right_p
, clip_rect
)
3890 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3891 XRectangle
*clip_rect
;
3897 gc
= f
->output_data
.x
->white_relief
.gc
;
3899 gc
= f
->output_data
.x
->black_relief
.gc
;
3900 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3903 for (i
= 0; i
< width
; ++i
)
3904 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3905 left_x
+ i
* left_p
, top_y
+ i
,
3906 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3910 for (i
= 0; i
< width
; ++i
)
3911 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3912 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3914 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3916 gc
= f
->output_data
.x
->black_relief
.gc
;
3918 gc
= f
->output_data
.x
->white_relief
.gc
;
3919 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3922 for (i
= 0; i
< width
; ++i
)
3923 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3924 left_x
+ i
* left_p
+ 1, bottom_y
- i
,
3925 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3929 for (i
= 0; i
< width
; ++i
)
3930 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3931 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3933 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3937 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3938 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3939 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3940 left side of the rectangle. RIGHT_P non-zero means draw a line
3941 on the right side of the rectangle. CLIP_RECT is the clipping
3942 rectangle to use when drawing. */
3945 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3946 left_p
, right_p
, clip_rect
)
3947 struct glyph_string
*s
;
3948 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3949 XRectangle
*clip_rect
;
3953 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3954 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3955 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3958 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3959 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3963 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3964 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3967 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3968 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3972 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3973 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3975 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3976 XSetClipMask (s
->display
, s
->gc
, None
);
3980 /* Draw a box around glyph string S. */
3983 x_draw_glyph_string_box (s
)
3984 struct glyph_string
*s
;
3986 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3987 int left_p
, right_p
;
3988 struct glyph
*last_glyph
;
3989 XRectangle clip_rect
;
3991 last_x
= window_box_right (s
->w
, s
->area
);
3992 if (s
->row
->full_width_p
3993 && !s
->w
->pseudo_window_p
)
3995 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3996 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3997 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4000 /* The glyph that may have a right box line. */
4001 last_glyph
= (s
->cmp
|| s
->img
4003 : s
->first_glyph
+ s
->nchars
- 1);
4005 width
= abs (s
->face
->box_line_width
);
4006 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4008 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4010 : min (last_x
, s
->x
+ s
->background_width
) - 1);
4012 bottom_y
= top_y
+ s
->height
- 1;
4014 left_p
= (s
->first_glyph
->left_box_line_p
4015 || (s
->hl
== DRAW_MOUSE_FACE
4017 || s
->prev
->hl
!= s
->hl
)));
4018 right_p
= (last_glyph
->right_box_line_p
4019 || (s
->hl
== DRAW_MOUSE_FACE
4021 || s
->next
->hl
!= s
->hl
)));
4023 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4025 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4026 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4027 left_p
, right_p
, &clip_rect
);
4030 x_setup_relief_colors (s
);
4031 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4032 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4037 /* Draw foreground of image glyph string S. */
4040 x_draw_image_foreground (s
)
4041 struct glyph_string
*s
;
4044 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4046 /* If first glyph of S has a left box line, start drawing it to the
4047 right of that line. */
4048 if (s
->face
->box
!= FACE_NO_BOX
4049 && s
->first_glyph
->left_box_line_p
)
4050 x
= s
->x
+ abs (s
->face
->box_line_width
);
4054 /* If there is a margin around the image, adjust x- and y-position
4056 x
+= s
->img
->hmargin
;
4057 y
+= s
->img
->vmargin
;
4063 /* We can't set both a clip mask and use XSetClipRectangles
4064 because the latter also sets a clip mask. We also can't
4065 trust on the shape extension to be available
4066 (XShapeCombineRegion). So, compute the rectangle to draw
4068 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4071 XRectangle clip_rect
, image_rect
, r
;
4073 xgcv
.clip_mask
= s
->img
->mask
;
4074 xgcv
.clip_x_origin
= x
;
4075 xgcv
.clip_y_origin
= y
;
4076 xgcv
.function
= GXcopy
;
4077 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4079 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4082 image_rect
.width
= s
->img
->width
;
4083 image_rect
.height
= s
->img
->height
;
4084 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4085 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4086 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4090 unsigned long mask
= GCClipXOrigin
| GCClipYOrigin
| GCFunction
;
4092 XRectangle clip_rect
, image_rect
, r
;
4094 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4097 image_rect
.width
= s
->img
->width
;
4098 image_rect
.height
= s
->img
->height
;
4099 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4100 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4101 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4103 /* When the image has a mask, we can expect that at
4104 least part of a mouse highlight or a block cursor will
4105 be visible. If the image doesn't have a mask, make
4106 a block cursor visible by drawing a rectangle around
4107 the image. I believe it's looking better if we do
4108 nothing here for mouse-face. */
4109 if (s
->hl
== DRAW_CURSOR
)
4110 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4111 s
->img
->width
- 1, s
->img
->height
- 1);
4115 /* Draw a rectangle if image could not be loaded. */
4116 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4117 s
->img
->width
- 1, s
->img
->height
- 1);
4121 /* Draw a relief around the image glyph string S. */
4124 x_draw_image_relief (s
)
4125 struct glyph_string
*s
;
4127 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4130 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4132 /* If first glyph of S has a left box line, start drawing it to the
4133 right of that line. */
4134 if (s
->face
->box
!= FACE_NO_BOX
4135 && s
->first_glyph
->left_box_line_p
)
4136 x
= s
->x
+ abs (s
->face
->box_line_width
);
4140 /* If there is a margin around the image, adjust x- and y-position
4142 x
+= s
->img
->hmargin
;
4143 y
+= s
->img
->vmargin
;
4145 if (s
->hl
== DRAW_IMAGE_SUNKEN
4146 || s
->hl
== DRAW_IMAGE_RAISED
)
4148 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
4149 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4153 thick
= abs (s
->img
->relief
);
4154 raised_p
= s
->img
->relief
> 0;
4159 x1
= x
+ s
->img
->width
+ thick
- 1;
4160 y1
= y
+ s
->img
->height
+ thick
- 1;
4162 x_setup_relief_colors (s
);
4163 x_get_glyph_string_clip_rect (s
, &r
);
4164 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4168 /* Draw the foreground of image glyph string S to PIXMAP. */
4171 x_draw_image_foreground_1 (s
, pixmap
)
4172 struct glyph_string
*s
;
4176 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4178 /* If first glyph of S has a left box line, start drawing it to the
4179 right of that line. */
4180 if (s
->face
->box
!= FACE_NO_BOX
4181 && s
->first_glyph
->left_box_line_p
)
4182 x
= abs (s
->face
->box_line_width
);
4186 /* If there is a margin around the image, adjust x- and y-position
4188 x
+= s
->img
->hmargin
;
4189 y
+= s
->img
->vmargin
;
4195 /* We can't set both a clip mask and use XSetClipRectangles
4196 because the latter also sets a clip mask. We also can't
4197 trust on the shape extension to be available
4198 (XShapeCombineRegion). So, compute the rectangle to draw
4200 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4204 xgcv
.clip_mask
= s
->img
->mask
;
4205 xgcv
.clip_x_origin
= x
;
4206 xgcv
.clip_y_origin
= y
;
4207 xgcv
.function
= GXcopy
;
4208 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4210 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4211 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4212 XSetClipMask (s
->display
, s
->gc
, None
);
4216 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4217 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4219 /* When the image has a mask, we can expect that at
4220 least part of a mouse highlight or a block cursor will
4221 be visible. If the image doesn't have a mask, make
4222 a block cursor visible by drawing a rectangle around
4223 the image. I believe it's looking better if we do
4224 nothing here for mouse-face. */
4225 if (s
->hl
== DRAW_CURSOR
)
4226 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4227 s
->img
->width
- 1, s
->img
->height
- 1);
4231 /* Draw a rectangle if image could not be loaded. */
4232 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4233 s
->img
->width
- 1, s
->img
->height
- 1);
4237 /* Draw part of the background of glyph string S. X, Y, W, and H
4238 give the rectangle to draw. */
4241 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4242 struct glyph_string
*s
;
4247 /* Fill background with a stipple pattern. */
4248 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4249 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4250 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4253 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4257 /* Draw image glyph string S.
4260 s->x +-------------------------
4263 | +-------------------------
4266 | | +-------------------
4272 x_draw_image_glyph_string (s
)
4273 struct glyph_string
*s
;
4276 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4277 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4279 Pixmap pixmap
= None
;
4281 height
= s
->height
- 2 * box_line_vwidth
;
4283 /* Fill background with face under the image. Do it only if row is
4284 taller than image or if image has a clip mask to reduce
4286 s
->stippled_p
= s
->face
->stipple
!= 0;
4287 if (height
> s
->img
->height
4291 || s
->img
->pixmap
== 0
4292 || s
->width
!= s
->background_width
)
4294 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4295 x
= s
->x
+ box_line_hwidth
;
4299 y
= s
->y
+ box_line_vwidth
;
4303 /* Create a pixmap as large as the glyph string. Fill it
4304 with the background color. Copy the image to it, using
4305 its mask. Copy the temporary pixmap to the display. */
4306 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4307 int depth
= DefaultDepthOfScreen (screen
);
4309 /* Create a pixmap as large as the glyph string. */
4310 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4311 s
->background_width
,
4314 /* Don't clip in the following because we're working on the
4316 XSetClipMask (s
->display
, s
->gc
, None
);
4318 /* Fill the pixmap with the background color/stipple. */
4321 /* Fill background with a stipple pattern. */
4322 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4323 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4324 0, 0, s
->background_width
, s
->height
);
4325 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4330 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4332 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4333 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4334 0, 0, s
->background_width
, s
->height
);
4335 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4339 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4341 s
->background_filled_p
= 1;
4344 /* Draw the foreground. */
4347 x_draw_image_foreground_1 (s
, pixmap
);
4348 x_set_glyph_string_clipping (s
);
4349 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4350 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4351 XFreePixmap (s
->display
, pixmap
);
4354 x_draw_image_foreground (s
);
4356 /* If we must draw a relief around the image, do it. */
4358 || s
->hl
== DRAW_IMAGE_RAISED
4359 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4360 x_draw_image_relief (s
);
4364 /* Draw stretch glyph string S. */
4367 x_draw_stretch_glyph_string (s
)
4368 struct glyph_string
*s
;
4370 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4371 s
->stippled_p
= s
->face
->stipple
!= 0;
4373 if (s
->hl
== DRAW_CURSOR
4374 && !x_stretch_cursor_p
)
4376 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4377 as wide as the stretch glyph. */
4378 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4381 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4383 /* Clear rest using the GC of the original non-cursor face. */
4384 if (width
< s
->background_width
)
4386 GC gc
= s
->face
->gc
;
4387 int x
= s
->x
+ width
, y
= s
->y
;
4388 int w
= s
->background_width
- width
, h
= s
->height
;
4391 x_get_glyph_string_clip_rect (s
, &r
);
4392 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4394 if (s
->face
->stipple
)
4396 /* Fill background with a stipple pattern. */
4397 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4398 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4399 XSetFillStyle (s
->display
, gc
, FillSolid
);
4404 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4405 XSetForeground (s
->display
, gc
, xgcv
.background
);
4406 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4407 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4412 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4415 s
->background_filled_p
= 1;
4419 /* Draw glyph string S. */
4422 x_draw_glyph_string (s
)
4423 struct glyph_string
*s
;
4425 int relief_drawn_p
= 0;
4427 /* If S draws into the background of its successor, draw the
4428 background of the successor first so that S can draw into it.
4429 This makes S->next use XDrawString instead of XDrawImageString. */
4430 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4432 xassert (s
->next
->img
== NULL
);
4433 x_set_glyph_string_gc (s
->next
);
4434 x_set_glyph_string_clipping (s
->next
);
4435 x_draw_glyph_string_background (s
->next
, 1);
4438 /* Set up S->gc, set clipping and draw S. */
4439 x_set_glyph_string_gc (s
);
4440 x_set_glyph_string_clipping (s
);
4442 /* Draw relief (if any) in advance for char/composition so that the
4443 glyph string can be drawn over it. */
4444 if (!s
->for_overlaps_p
4445 && s
->face
->box
!= FACE_NO_BOX
4446 && (s
->first_glyph
->type
== CHAR_GLYPH
4447 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4450 x_draw_glyph_string_background (s
, 1);
4451 x_draw_glyph_string_box (s
);
4455 switch (s
->first_glyph
->type
)
4458 x_draw_image_glyph_string (s
);
4462 x_draw_stretch_glyph_string (s
);
4466 if (s
->for_overlaps_p
)
4467 s
->background_filled_p
= 1;
4469 x_draw_glyph_string_background (s
, 0);
4470 x_draw_glyph_string_foreground (s
);
4473 case COMPOSITE_GLYPH
:
4474 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4475 s
->background_filled_p
= 1;
4477 x_draw_glyph_string_background (s
, 1);
4478 x_draw_composite_glyph_string_foreground (s
);
4485 if (!s
->for_overlaps_p
)
4487 /* Draw underline. */
4488 if (s
->face
->underline_p
)
4490 unsigned long tem
, h
;
4493 /* Get the underline thickness. Default is 1 pixel. */
4494 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4497 /* Get the underline position. This is the recommended
4498 vertical offset in pixels from the baseline to the top of
4499 the underline. This is a signed value according to the
4500 specs, and its default is
4502 ROUND ((maximum descent) / 2), with
4503 ROUND(x) = floor (x + 0.5) */
4505 if (x_use_underline_position_properties
4506 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4507 y
= s
->ybase
+ (long) tem
;
4508 else if (s
->face
->font
)
4509 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4511 y
= s
->y
+ s
->height
- h
;
4513 if (s
->face
->underline_defaulted_p
)
4514 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4515 s
->x
, y
, s
->width
, h
);
4519 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4520 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4521 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4522 s
->x
, y
, s
->width
, h
);
4523 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4527 /* Draw overline. */
4528 if (s
->face
->overline_p
)
4530 unsigned long dy
= 0, h
= 1;
4532 if (s
->face
->overline_color_defaulted_p
)
4533 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4538 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4539 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4540 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4542 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4546 /* Draw strike-through. */
4547 if (s
->face
->strike_through_p
)
4549 unsigned long h
= 1;
4550 unsigned long dy
= (s
->height
- h
) / 2;
4552 if (s
->face
->strike_through_color_defaulted_p
)
4553 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4558 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4559 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4560 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4562 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4566 /* Draw relief if not yet drawn. */
4567 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4568 x_draw_glyph_string_box (s
);
4571 /* Reset clipping. */
4572 XSetClipMask (s
->display
, s
->gc
, None
);
4576 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4577 struct face
**, int));
4580 /* Fill glyph string S with composition components specified by S->cmp.
4582 FACES is an array of faces for all components of this composition.
4583 S->gidx is the index of the first component for S.
4584 OVERLAPS_P non-zero means S should draw the foreground only, and
4585 use its physical height for clipping.
4587 Value is the index of a component not in S. */
4590 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4591 struct glyph_string
*s
;
4592 struct face
**faces
;
4599 s
->for_overlaps_p
= overlaps_p
;
4601 s
->face
= faces
[s
->gidx
];
4602 s
->font
= s
->face
->font
;
4603 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4605 /* For all glyphs of this composition, starting at the offset
4606 S->gidx, until we reach the end of the definition or encounter a
4607 glyph that requires the different face, add it to S. */
4609 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4612 /* All glyph strings for the same composition has the same width,
4613 i.e. the width set for the first component of the composition. */
4615 s
->width
= s
->first_glyph
->pixel_width
;
4617 /* If the specified font could not be loaded, use the frame's
4618 default font, but record the fact that we couldn't load it in
4619 the glyph string so that we can draw rectangles for the
4620 characters of the glyph string. */
4621 if (s
->font
== NULL
)
4623 s
->font_not_found_p
= 1;
4624 s
->font
= FRAME_FONT (s
->f
);
4627 /* Adjust base line for subscript/superscript text. */
4628 s
->ybase
+= s
->first_glyph
->voffset
;
4630 xassert (s
->face
&& s
->face
->gc
);
4632 /* This glyph string must always be drawn with 16-bit functions. */
4635 return s
->gidx
+ s
->nchars
;
4639 /* Fill glyph string S from a sequence of character glyphs.
4641 FACE_ID is the face id of the string. START is the index of the
4642 first glyph to consider, END is the index of the last + 1.
4643 OVERLAPS_P non-zero means S should draw the foreground only, and
4644 use its physical height for clipping.
4646 Value is the index of the first glyph not in S. */
4649 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4650 struct glyph_string
*s
;
4652 int start
, end
, overlaps_p
;
4654 struct glyph
*glyph
, *last
;
4656 int glyph_not_available_p
;
4658 xassert (s
->f
== XFRAME (s
->w
->frame
));
4659 xassert (s
->nchars
== 0);
4660 xassert (start
>= 0 && end
> start
);
4662 s
->for_overlaps_p
= overlaps_p
,
4663 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4664 last
= s
->row
->glyphs
[s
->area
] + end
;
4665 voffset
= glyph
->voffset
;
4667 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4670 && glyph
->type
== CHAR_GLYPH
4671 && glyph
->voffset
== voffset
4672 /* Same face id implies same font, nowadays. */
4673 && glyph
->face_id
== face_id
4674 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4678 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4679 s
->char2b
+ s
->nchars
,
4681 s
->two_byte_p
= two_byte_p
;
4683 xassert (s
->nchars
<= end
- start
);
4684 s
->width
+= glyph
->pixel_width
;
4688 s
->font
= s
->face
->font
;
4689 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4691 /* If the specified font could not be loaded, use the frame's font,
4692 but record the fact that we couldn't load it in
4693 S->font_not_found_p so that we can draw rectangles for the
4694 characters of the glyph string. */
4695 if (s
->font
== NULL
|| glyph_not_available_p
)
4697 s
->font_not_found_p
= 1;
4698 s
->font
= FRAME_FONT (s
->f
);
4701 /* Adjust base line for subscript/superscript text. */
4702 s
->ybase
+= voffset
;
4704 xassert (s
->face
&& s
->face
->gc
);
4705 return glyph
- s
->row
->glyphs
[s
->area
];
4709 /* Fill glyph string S from image glyph S->first_glyph. */
4712 x_fill_image_glyph_string (s
)
4713 struct glyph_string
*s
;
4715 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4716 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4718 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4719 s
->font
= s
->face
->font
;
4720 s
->width
= s
->first_glyph
->pixel_width
;
4722 /* Adjust base line for subscript/superscript text. */
4723 s
->ybase
+= s
->first_glyph
->voffset
;
4727 /* Fill glyph string S from a sequence of stretch glyphs.
4729 ROW is the glyph row in which the glyphs are found, AREA is the
4730 area within the row. START is the index of the first glyph to
4731 consider, END is the index of the last + 1.
4733 Value is the index of the first glyph not in S. */
4736 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4737 struct glyph_string
*s
;
4738 struct glyph_row
*row
;
4739 enum glyph_row_area area
;
4742 struct glyph
*glyph
, *last
;
4743 int voffset
, face_id
;
4745 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4747 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4748 last
= s
->row
->glyphs
[s
->area
] + end
;
4749 face_id
= glyph
->face_id
;
4750 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4751 s
->font
= s
->face
->font
;
4752 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4753 s
->width
= glyph
->pixel_width
;
4754 voffset
= glyph
->voffset
;
4758 && glyph
->type
== STRETCH_GLYPH
4759 && glyph
->voffset
== voffset
4760 && glyph
->face_id
== face_id
);
4762 s
->width
+= glyph
->pixel_width
;
4764 /* Adjust base line for subscript/superscript text. */
4765 s
->ybase
+= voffset
;
4767 xassert (s
->face
&& s
->face
->gc
);
4768 return glyph
- s
->row
->glyphs
[s
->area
];
4772 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4773 of XChar2b structures for S; it can't be allocated in
4774 x_init_glyph_string because it must be allocated via `alloca'. W
4775 is the window on which S is drawn. ROW and AREA are the glyph row
4776 and area within the row from which S is constructed. START is the
4777 index of the first glyph structure covered by S. HL is a
4778 face-override for drawing S. */
4781 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4782 struct glyph_string
*s
;
4785 struct glyph_row
*row
;
4786 enum glyph_row_area area
;
4788 enum draw_glyphs_face hl
;
4790 bzero (s
, sizeof *s
);
4792 s
->f
= XFRAME (w
->frame
);
4793 s
->display
= FRAME_X_DISPLAY (s
->f
);
4794 s
->window
= FRAME_X_WINDOW (s
->f
);
4799 s
->first_glyph
= row
->glyphs
[area
] + start
;
4800 s
->height
= row
->height
;
4801 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4803 /* Display the internal border below the tool-bar window. */
4804 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4805 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4807 s
->ybase
= s
->y
+ row
->ascent
;
4811 /* Set background width of glyph string S. START is the index of the
4812 first glyph following S. LAST_X is the right-most x-position + 1
4813 in the drawing area. */
4816 x_set_glyph_string_background_width (s
, start
, last_x
)
4817 struct glyph_string
*s
;
4821 /* If the face of this glyph string has to be drawn to the end of
4822 the drawing area, set S->extends_to_end_of_line_p. */
4823 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4825 if (start
== s
->row
->used
[s
->area
]
4826 && s
->hl
== DRAW_NORMAL_TEXT
4827 && s
->area
== TEXT_AREA
4828 && (s
->row
->fill_line_p
4829 || s
->face
->background
!= default_face
->background
4830 || s
->face
->stipple
!= default_face
->stipple
))
4831 s
->extends_to_end_of_line_p
= 1;
4833 /* If S extends its face to the end of the line, set its
4834 background_width to the distance to the right edge of the drawing
4836 if (s
->extends_to_end_of_line_p
)
4837 s
->background_width
= last_x
- s
->x
+ 1;
4839 s
->background_width
= s
->width
;
4843 /* Add a glyph string for a stretch glyph to the list of strings
4844 between HEAD and TAIL. START is the index of the stretch glyph in
4845 row area AREA of glyph row ROW. END is the index of the last glyph
4846 in that glyph row area. X is the current output position assigned
4847 to the new glyph string constructed. HL overrides that face of the
4848 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4849 is the right-most x-position of the drawing area. */
4851 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4852 and below -- keep them on one line. */
4853 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4856 s = (struct glyph_string *) alloca (sizeof *s); \
4857 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4858 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4859 x_append_glyph_string (&HEAD, &TAIL, s); \
4865 /* Add a glyph string for an image glyph to the list of strings
4866 between HEAD and TAIL. START is the index of the image glyph in
4867 row area AREA of glyph row ROW. END is the index of the last glyph
4868 in that glyph row area. X is the current output position assigned
4869 to the new glyph string constructed. HL overrides that face of the
4870 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4871 is the right-most x-position of the drawing area. */
4873 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4876 s = (struct glyph_string *) alloca (sizeof *s); \
4877 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4878 x_fill_image_glyph_string (s); \
4879 x_append_glyph_string (&HEAD, &TAIL, s); \
4886 /* Add a glyph string for a sequence of character glyphs to the list
4887 of strings between HEAD and TAIL. START is the index of the first
4888 glyph in row area AREA of glyph row ROW that is part of the new
4889 glyph string. END is the index of the last glyph in that glyph row
4890 area. X is the current output position assigned to the new glyph
4891 string constructed. HL overrides that face of the glyph; e.g. it
4892 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4893 right-most x-position of the drawing area. */
4895 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4901 c = (ROW)->glyphs[AREA][START].u.ch; \
4902 face_id = (ROW)->glyphs[AREA][START].face_id; \
4904 s = (struct glyph_string *) alloca (sizeof *s); \
4905 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4906 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4907 x_append_glyph_string (&HEAD, &TAIL, s); \
4909 START = x_fill_glyph_string (s, face_id, START, END, \
4915 /* Add a glyph string for a composite sequence to the list of strings
4916 between HEAD and TAIL. START is the index of the first glyph in
4917 row area AREA of glyph row ROW that is part of the new glyph
4918 string. END is the index of the last glyph in that glyph row area.
4919 X is the current output position assigned to the new glyph string
4920 constructed. HL overrides that face of the glyph; e.g. it is
4921 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4922 x-position of the drawing area. */
4924 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4926 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4927 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4928 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4929 struct composition *cmp = composition_table[cmp_id]; \
4930 int glyph_len = cmp->glyph_len; \
4932 struct face **faces; \
4933 struct glyph_string *first_s = NULL; \
4936 base_face = base_face->ascii_face; \
4937 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4938 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4939 /* At first, fill in `char2b' and `faces'. */ \
4940 for (n = 0; n < glyph_len; n++) \
4942 int c = COMPOSITION_GLYPH (cmp, n); \
4943 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4944 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4945 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4946 this_face_id, char2b + n, 1); \
4949 /* Make glyph_strings for each glyph sequence that is drawable by \
4950 the same face, and append them to HEAD/TAIL. */ \
4951 for (n = 0; n < cmp->glyph_len;) \
4953 s = (struct glyph_string *) alloca (sizeof *s); \
4954 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4955 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4963 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4971 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4972 of AREA of glyph row ROW on window W between indices START and END.
4973 HL overrides the face for drawing glyph strings, e.g. it is
4974 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4975 x-positions of the drawing area.
4977 This is an ugly monster macro construct because we must use alloca
4978 to allocate glyph strings (because x_draw_glyphs can be called
4981 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4984 HEAD = TAIL = NULL; \
4985 while (START < END) \
4987 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4988 switch (first_glyph->type) \
4991 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4992 TAIL, HL, X, LAST_X, \
4996 case COMPOSITE_GLYPH: \
4997 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
4998 HEAD, TAIL, HL, X, LAST_X,\
5002 case STRETCH_GLYPH: \
5003 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5004 HEAD, TAIL, HL, X, LAST_X); \
5008 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5009 TAIL, HL, X, LAST_X); \
5016 x_set_glyph_string_background_width (s, START, LAST_X); \
5023 /* Draw glyphs between START and END in AREA of ROW on window W,
5024 starting at x-position X. X is relative to AREA in W. HL is a
5025 face-override with the following meaning:
5027 DRAW_NORMAL_TEXT draw normally
5028 DRAW_CURSOR draw in cursor face
5029 DRAW_MOUSE_FACE draw in mouse face.
5030 DRAW_INVERSE_VIDEO draw in mode line face
5031 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5032 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5034 If REAL_START is non-null, return in *REAL_START the real starting
5035 position for display. This can be different from START in case
5036 overlapping glyphs must be displayed. If REAL_END is non-null,
5037 return in *REAL_END the real end position for display. This can be
5038 different from END in case overlapping glyphs must be displayed.
5040 If OVERLAPS_P is non-zero, draw only the foreground of characters
5041 and clip to the physical height of ROW.
5043 Value is the x-position reached, relative to AREA of W. */
5046 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
5050 struct glyph_row
*row
;
5051 enum glyph_row_area area
;
5053 enum draw_glyphs_face hl
;
5054 int *real_start
, *real_end
;
5057 struct glyph_string
*head
, *tail
;
5058 struct glyph_string
*s
;
5059 int last_x
, area_width
;
5063 /* Let's rather be paranoid than getting a SEGV. */
5064 end
= min (end
, row
->used
[area
]);
5065 start
= max (0, start
);
5066 start
= min (end
, start
);
5068 *real_start
= start
;
5072 /* Translate X to frame coordinates. Set last_x to the right
5073 end of the drawing area. */
5074 if (row
->full_width_p
)
5076 /* X is relative to the left edge of W, without scroll bars
5078 struct frame
*f
= XFRAME (w
->frame
);
5079 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
5080 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5083 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5084 last_x
= window_left_x
+ area_width
;
5086 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5088 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5089 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5095 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5096 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5100 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5101 area_width
= window_box_width (w
, area
);
5102 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5105 /* Build a doubly-linked list of glyph_string structures between
5106 head and tail from what we have to draw. Note that the macro
5107 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5108 the reason we use a separate variable `i'. */
5110 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5113 x_reached
= tail
->x
+ tail
->background_width
;
5117 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5118 the row, redraw some glyphs in front or following the glyph
5119 strings built above. */
5120 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5123 struct glyph_string
*h
, *t
;
5125 /* Compute overhangs for all glyph strings. */
5126 for (s
= head
; s
; s
= s
->next
)
5127 x_compute_glyph_string_overhangs (s
);
5129 /* Prepend glyph strings for glyphs in front of the first glyph
5130 string that are overwritten because of the first glyph
5131 string's left overhang. The background of all strings
5132 prepended must be drawn because the first glyph string
5134 i
= x_left_overwritten (head
);
5138 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5139 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5143 *real_start
= start
;
5144 x_compute_overhangs_and_x (t
, head
->x
, 1);
5145 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5148 /* Prepend glyph strings for glyphs in front of the first glyph
5149 string that overwrite that glyph string because of their
5150 right overhang. For these strings, only the foreground must
5151 be drawn, because it draws over the glyph string at `head'.
5152 The background must not be drawn because this would overwrite
5153 right overhangs of preceding glyphs for which no glyph
5155 i
= x_left_overwriting (head
);
5158 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5159 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5161 for (s
= h
; s
; s
= s
->next
)
5162 s
->background_filled_p
= 1;
5165 x_compute_overhangs_and_x (t
, head
->x
, 1);
5166 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5169 /* Append glyphs strings for glyphs following the last glyph
5170 string tail that are overwritten by tail. The background of
5171 these strings has to be drawn because tail's foreground draws
5173 i
= x_right_overwritten (tail
);
5176 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5177 DRAW_NORMAL_TEXT
, x
, last_x
,
5179 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5180 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5185 /* Append glyph strings for glyphs following the last glyph
5186 string tail that overwrite tail. The foreground of such
5187 glyphs has to be drawn because it writes into the background
5188 of tail. The background must not be drawn because it could
5189 paint over the foreground of following glyphs. */
5190 i
= x_right_overwriting (tail
);
5193 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5194 DRAW_NORMAL_TEXT
, x
, last_x
,
5196 for (s
= h
; s
; s
= s
->next
)
5197 s
->background_filled_p
= 1;
5198 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5199 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5205 /* Draw all strings. */
5206 for (s
= head
; s
; s
= s
->next
)
5207 x_draw_glyph_string (s
);
5209 /* Value is the x-position up to which drawn, relative to AREA of W.
5210 This doesn't include parts drawn because of overhangs. */
5211 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5212 if (!row
->full_width_p
)
5214 if (area
> LEFT_MARGIN_AREA
)
5215 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5216 if (area
> TEXT_AREA
)
5217 x_reached
-= window_box_width (w
, TEXT_AREA
);
5224 /* Fix the display of area AREA of overlapping row ROW in window W. */
5227 x_fix_overlapping_area (w
, row
, area
)
5229 struct glyph_row
*row
;
5230 enum glyph_row_area area
;
5236 if (area
== LEFT_MARGIN_AREA
)
5238 else if (area
== TEXT_AREA
)
5239 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5241 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5242 + window_box_width (w
, TEXT_AREA
));
5244 for (i
= 0; i
< row
->used
[area
];)
5246 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5248 int start
= i
, start_x
= x
;
5252 x
+= row
->glyphs
[area
][i
].pixel_width
;
5255 while (i
< row
->used
[area
]
5256 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5258 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5260 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5265 x
+= row
->glyphs
[area
][i
].pixel_width
;
5274 /* Output LEN glyphs starting at START at the nominal cursor position.
5275 Advance the nominal cursor over the text. The global variable
5276 updated_window contains the window being updated, updated_row is
5277 the glyph row being updated, and updated_area is the area of that
5278 row being updated. */
5281 x_write_glyphs (start
, len
)
5282 struct glyph
*start
;
5285 int x
, hpos
, real_start
, real_end
;
5287 xassert (updated_window
&& updated_row
);
5292 hpos
= start
- updated_row
->glyphs
[updated_area
];
5293 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5294 updated_row
, updated_area
,
5296 (updated_row
->inverse_p
5297 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5298 &real_start
, &real_end
, 0);
5300 /* If we drew over the cursor, note that it is not visible any more. */
5301 note_overwritten_text_cursor (updated_window
, real_start
,
5302 real_end
- real_start
);
5306 /* Advance the output cursor. */
5307 output_cursor
.hpos
+= len
;
5308 output_cursor
.x
= x
;
5312 /* Insert LEN glyphs from START at the nominal cursor position. */
5315 x_insert_glyphs (start
, len
)
5316 struct glyph
*start
;
5321 int line_height
, shift_by_width
, shifted_region_width
;
5322 struct glyph_row
*row
;
5323 struct glyph
*glyph
;
5324 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5326 xassert (updated_window
&& updated_row
);
5329 f
= XFRAME (WINDOW_FRAME (w
));
5331 /* Get the height of the line we are in. */
5333 line_height
= row
->height
;
5335 /* Get the width of the glyphs to insert. */
5337 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5338 shift_by_width
+= glyph
->pixel_width
;
5340 /* Get the width of the region to shift right. */
5341 shifted_region_width
= (window_box_width (w
, updated_area
)
5346 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5347 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5348 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5349 f
->output_data
.x
->normal_gc
,
5351 shifted_region_width
, line_height
,
5352 frame_x
+ shift_by_width
, frame_y
);
5354 /* Write the glyphs. */
5355 hpos
= start
- row
->glyphs
[updated_area
];
5356 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5357 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5358 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5360 /* Advance the output cursor. */
5361 output_cursor
.hpos
+= len
;
5362 output_cursor
.x
+= shift_by_width
;
5367 /* Delete N glyphs at the nominal cursor position. Not implemented
5378 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
5379 If they are <= 0, this is probably an error. */
5382 x_clear_area (dpy
, window
, x
, y
, width
, height
, exposures
)
5389 xassert (width
> 0 && height
> 0);
5390 XClearArea (dpy
, window
, x
, y
, width
, height
, exposures
);
5394 /* Erase the current text line from the nominal cursor position
5395 (inclusive) to pixel column TO_X (exclusive). The idea is that
5396 everything from TO_X onward is already erased.
5398 TO_X is a pixel position relative to updated_area of
5399 updated_window. TO_X == -1 means clear to the end of this area. */
5402 x_clear_end_of_line (to_x
)
5406 struct window
*w
= updated_window
;
5407 int max_x
, min_y
, max_y
;
5408 int from_x
, from_y
, to_y
;
5410 xassert (updated_window
&& updated_row
);
5411 f
= XFRAME (w
->frame
);
5413 if (updated_row
->full_width_p
)
5415 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5416 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5417 && !w
->pseudo_window_p
)
5418 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5421 max_x
= window_box_width (w
, updated_area
);
5422 max_y
= window_text_bottom_y (w
);
5424 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5425 of window. For TO_X > 0, truncate to end of drawing area. */
5431 to_x
= min (to_x
, max_x
);
5433 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5435 /* Notice if the cursor will be cleared by this operation. */
5436 if (!updated_row
->full_width_p
)
5437 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5439 from_x
= output_cursor
.x
;
5441 /* Translate to frame coordinates. */
5442 if (updated_row
->full_width_p
)
5444 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5445 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5449 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5450 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5453 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5454 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5455 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5457 /* Prevent inadvertently clearing to end of the X window. */
5458 if (to_x
> from_x
&& to_y
> from_y
)
5461 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5462 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5469 /* Clear entire frame. If updating_frame is non-null, clear that
5470 frame. Otherwise clear the selected frame. */
5480 f
= SELECTED_FRAME ();
5482 /* Clearing the frame will erase any cursor, so mark them all as no
5484 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5485 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5486 output_cursor
.x
= -1;
5488 /* We don't set the output cursor here because there will always
5489 follow an explicit cursor_to. */
5491 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5493 /* We have to clear the scroll bars, too. If we have changed
5494 colors or something like that, then they should be notified. */
5495 x_scroll_bar_clear (f
);
5497 XFlush (FRAME_X_DISPLAY (f
));
5503 /* Invert the middle quarter of the frame for .15 sec. */
5505 /* We use the select system call to do the waiting, so we have to make
5506 sure it's available. If it isn't, we just won't do visual bells. */
5508 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5511 /* Subtract the `struct timeval' values X and Y, storing the result in
5512 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5515 timeval_subtract (result
, x
, y
)
5516 struct timeval
*result
, x
, y
;
5518 /* Perform the carry for the later subtraction by updating y. This
5519 is safer because on some systems the tv_sec member is unsigned. */
5520 if (x
.tv_usec
< y
.tv_usec
)
5522 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5523 y
.tv_usec
-= 1000000 * nsec
;
5527 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5529 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5530 y
.tv_usec
+= 1000000 * nsec
;
5534 /* Compute the time remaining to wait. tv_usec is certainly
5536 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5537 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5539 /* Return indication of whether the result should be considered
5541 return x
.tv_sec
< y
.tv_sec
;
5553 /* Create a GC that will use the GXxor function to flip foreground
5554 pixels into background pixels. */
5558 values
.function
= GXxor
;
5559 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5560 ^ f
->output_data
.x
->background_pixel
);
5562 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5563 GCFunction
| GCForeground
, &values
);
5567 /* Get the height not including a menu bar widget. */
5568 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5569 /* Height of each line to flash. */
5570 int flash_height
= FRAME_LINE_HEIGHT (f
);
5571 /* These will be the left and right margins of the rectangles. */
5572 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5573 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5577 /* Don't flash the area between a scroll bar and the frame
5578 edge it is next to. */
5579 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5581 case vertical_scroll_bar_left
:
5582 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5585 case vertical_scroll_bar_right
:
5586 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5593 width
= flash_right
- flash_left
;
5595 /* If window is tall, flash top and bottom line. */
5596 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5598 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5600 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5601 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5602 width
, flash_height
);
5603 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5605 (height
- flash_height
5606 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5607 width
, flash_height
);
5610 /* If it is short, flash it all. */
5611 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5612 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5613 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5618 struct timeval wakeup
;
5620 EMACS_GET_TIME (wakeup
);
5622 /* Compute time to wait until, propagating carry from usecs. */
5623 wakeup
.tv_usec
+= 150000;
5624 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5625 wakeup
.tv_usec
%= 1000000;
5627 /* Keep waiting until past the time wakeup or any input gets
5629 while (! detect_input_pending ())
5631 struct timeval current
;
5632 struct timeval timeout
;
5634 EMACS_GET_TIME (current
);
5636 /* Break if result would be negative. */
5637 if (timeval_subtract (¤t
, wakeup
, current
))
5640 /* How long `select' should wait. */
5642 timeout
.tv_usec
= 10000;
5644 /* Try to wait that long--but we might wake up sooner. */
5645 select (0, NULL
, NULL
, NULL
, &timeout
);
5649 /* If window is tall, flash top and bottom line. */
5650 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5652 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5654 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5655 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5656 width
, flash_height
);
5657 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5659 (height
- flash_height
5660 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5661 width
, flash_height
);
5664 /* If it is short, flash it all. */
5665 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5666 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5667 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5669 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5677 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5680 /* Make audible bell. */
5685 struct frame
*f
= SELECTED_FRAME ();
5687 if (FRAME_X_DISPLAY (f
))
5689 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5696 XBell (FRAME_X_DISPLAY (f
), 0);
5697 XFlush (FRAME_X_DISPLAY (f
));
5704 /* Specify how many text lines, from the top of the window,
5705 should be affected by insert-lines and delete-lines operations.
5706 This, and those operations, are used only within an update
5707 that is bounded by calls to x_update_begin and x_update_end. */
5710 XTset_terminal_window (n
)
5713 /* This function intentionally left blank. */
5718 /***********************************************************************
5720 ***********************************************************************/
5722 /* Perform an insert-lines or delete-lines operation, inserting N
5723 lines or deleting -N lines at vertical position VPOS. */
5726 x_ins_del_lines (vpos
, n
)
5733 /* Scroll part of the display as described by RUN. */
5736 x_scroll_run (w
, run
)
5740 struct frame
*f
= XFRAME (w
->frame
);
5741 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5743 /* Get frame-relative bounding box of the text display area of W,
5744 without mode lines. Include in this box the flags areas to the
5745 left and right of W. */
5746 window_box (w
, -1, &x
, &y
, &width
, &height
);
5747 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5748 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5750 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5751 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5752 bottom_y
= y
+ height
;
5756 /* Scrolling up. Make sure we don't copy part of the mode
5757 line at the bottom. */
5758 if (from_y
+ run
->height
> bottom_y
)
5759 height
= bottom_y
- from_y
;
5761 height
= run
->height
;
5765 /* Scolling down. Make sure we don't copy over the mode line.
5767 if (to_y
+ run
->height
> bottom_y
)
5768 height
= bottom_y
- to_y
;
5770 height
= run
->height
;
5775 /* Cursor off. Will be switched on again in x_update_window_end. */
5779 XCopyArea (FRAME_X_DISPLAY (f
),
5780 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5781 f
->output_data
.x
->normal_gc
,
5791 /***********************************************************************
5793 ***********************************************************************/
5795 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5796 corner of the exposed rectangle. W and H are width and height of
5797 the exposed area. All are pixel values. W or H zero means redraw
5798 the entire frame. */
5801 expose_frame (f
, x
, y
, w
, h
)
5807 TRACE ((stderr
, "expose_frame "));
5809 /* No need to redraw if frame will be redrawn soon. */
5810 if (FRAME_GARBAGED_P (f
))
5812 TRACE ((stderr
, " garbaged\n"));
5816 /* If basic faces haven't been realized yet, there is no point in
5817 trying to redraw anything. This can happen when we get an expose
5818 event while Emacs is starting, e.g. by moving another window. */
5819 if (FRAME_FACE_CACHE (f
) == NULL
5820 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5822 TRACE ((stderr
, " no faces\n"));
5826 if (w
== 0 || h
== 0)
5829 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5830 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5840 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5841 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5843 if (WINDOWP (f
->tool_bar_window
))
5844 expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5846 #ifndef USE_X_TOOLKIT
5847 if (WINDOWP (f
->menu_bar_window
))
5848 expose_window (XWINDOW (f
->menu_bar_window
), &r
);
5849 #endif /* not USE_X_TOOLKIT */
5853 /* Redraw (parts) of all windows in the window tree rooted at W that
5854 intersect R. R contains frame pixel coordinates. */
5857 expose_window_tree (w
, r
)
5863 if (!NILP (w
->hchild
))
5864 expose_window_tree (XWINDOW (w
->hchild
), r
);
5865 else if (!NILP (w
->vchild
))
5866 expose_window_tree (XWINDOW (w
->vchild
), r
);
5868 expose_window (w
, r
);
5869 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5874 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5875 which intersects rectangle R. R is in window-relative coordinates. */
5878 expose_area (w
, row
, r
, area
)
5880 struct glyph_row
*row
;
5882 enum glyph_row_area area
;
5884 struct glyph
*first
= row
->glyphs
[area
];
5885 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5887 int first_x
, start_x
, x
;
5889 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5890 /* If row extends face to end of line write the whole line. */
5891 x_draw_glyphs (w
, 0, row
, area
,
5893 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5897 /* Set START_X to the window-relative start position for drawing glyphs of
5898 AREA. The first glyph of the text area can be partially visible.
5899 The first glyphs of other areas cannot. */
5900 if (area
== LEFT_MARGIN_AREA
)
5902 else if (area
== TEXT_AREA
)
5903 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5905 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5906 + window_box_width (w
, TEXT_AREA
));
5909 /* Find the first glyph that must be redrawn. */
5911 && x
+ first
->pixel_width
< r
->x
)
5913 x
+= first
->pixel_width
;
5917 /* Find the last one. */
5921 && x
< r
->x
+ r
->width
)
5923 x
+= last
->pixel_width
;
5929 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5930 first
- row
->glyphs
[area
],
5931 last
- row
->glyphs
[area
],
5932 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5938 /* Redraw the parts of the glyph row ROW on window W intersecting
5939 rectangle R. R is in window-relative coordinates. */
5942 expose_line (w
, row
, r
)
5944 struct glyph_row
*row
;
5947 xassert (row
->enabled_p
);
5949 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5950 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5951 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5955 if (row
->used
[LEFT_MARGIN_AREA
])
5956 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5957 if (row
->used
[TEXT_AREA
])
5958 expose_area (w
, row
, r
, TEXT_AREA
);
5959 if (row
->used
[RIGHT_MARGIN_AREA
])
5960 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5961 x_draw_row_bitmaps (w
, row
);
5966 /* Return non-zero if W's cursor intersects rectangle R. */
5969 x_phys_cursor_in_rect_p (w
, r
)
5973 XRectangle cr
, result
;
5974 struct glyph
*cursor_glyph
;
5976 cursor_glyph
= get_phys_cursor_glyph (w
);
5979 cr
.x
= w
->phys_cursor
.x
;
5980 cr
.y
= w
->phys_cursor
.y
;
5981 cr
.width
= cursor_glyph
->pixel_width
;
5982 cr
.height
= w
->phys_cursor_height
;
5983 return x_intersect_rectangles (&cr
, r
, &result
);
5990 /* Redraw the part of window W intersection rectangle FR. Pixel
5991 coordinates in FR are frame-relative. Call this function with
5995 expose_window (w
, fr
)
5999 struct frame
*f
= XFRAME (w
->frame
);
6000 struct glyph_row
*row
;
6001 int y
, yb
, cursor_cleared_p
;
6004 /* If window is not yet fully initialized, do nothing. This can
6005 happen when toolkit scroll bars are used and a window is split.
6006 Reconfiguring the scroll bar will generate an expose for a newly
6008 if (w
->current_matrix
== NULL
|| w
== updated_window
)
6011 /* Frame-relative pixel rectangle of W. */
6012 wr
.x
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6013 wr
.y
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6014 wr
.width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6015 wr
.height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6017 if (!x_intersect_rectangles (fr
, &wr
, &r
))
6020 yb
= window_text_bottom_y (w
);
6022 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6023 r
.x
, r
.y
, r
.width
, r
.height
));
6025 /* Convert to window coordinates. */
6026 r
.x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.x
);
6027 r
.y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.y
);
6029 /* Turn off the cursor. */
6030 if (!w
->pseudo_window_p
6031 && x_phys_cursor_in_rect_p (w
, &r
))
6034 cursor_cleared_p
= 1;
6037 cursor_cleared_p
= 0;
6039 /* Find the first row intersecting the rectangle R. */
6040 row
= w
->current_matrix
->rows
;
6042 while (row
->enabled_p
6044 && y
+ row
->height
< r
.y
)
6050 /* Display the text in the rectangle, one text line at a time. */
6051 while (row
->enabled_p
6053 && y
< r
.y
+ r
.height
)
6055 expose_line (w
, row
, &r
);
6060 /* Display the mode line if there is one. */
6061 if (WINDOW_WANTS_MODELINE_P (w
)
6062 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6064 && row
->y
< r
.y
+ r
.height
)
6065 expose_line (w
, row
, &r
);
6067 if (!w
->pseudo_window_p
)
6069 /* Draw border between windows. */
6070 x_draw_vertical_border (w
);
6072 /* Turn the cursor on again. */
6073 if (cursor_cleared_p
)
6074 x_update_window_cursor (w
, 1);
6079 /* Determine the intersection of two rectangles R1 and R2. Return
6080 the intersection in *RESULT. Value is non-zero if RESULT is not
6084 x_intersect_rectangles (r1
, r2
, result
)
6085 XRectangle
*r1
, *r2
, *result
;
6087 XRectangle
*left
, *right
;
6088 XRectangle
*upper
, *lower
;
6089 int intersection_p
= 0;
6091 /* Rearrange so that R1 is the left-most rectangle. */
6093 left
= r1
, right
= r2
;
6095 left
= r2
, right
= r1
;
6097 /* X0 of the intersection is right.x0, if this is inside R1,
6098 otherwise there is no intersection. */
6099 if (right
->x
<= left
->x
+ left
->width
)
6101 result
->x
= right
->x
;
6103 /* The right end of the intersection is the minimum of the
6104 the right ends of left and right. */
6105 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
6108 /* Same game for Y. */
6110 upper
= r1
, lower
= r2
;
6112 upper
= r2
, lower
= r1
;
6114 /* The upper end of the intersection is lower.y0, if this is inside
6115 of upper. Otherwise, there is no intersection. */
6116 if (lower
->y
<= upper
->y
+ upper
->height
)
6118 result
->y
= lower
->y
;
6120 /* The lower end of the intersection is the minimum of the lower
6121 ends of upper and lower. */
6122 result
->height
= (min (lower
->y
+ lower
->height
,
6123 upper
->y
+ upper
->height
)
6129 return intersection_p
;
6140 /* We used to only do this if Vx_no_window_manager was non-nil, but
6141 the ICCCM (section 4.1.6) says that the window's border pixmap
6142 and border pixel are window attributes which are "private to the
6143 client", so we can always change it to whatever we want. */
6145 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6146 f
->output_data
.x
->border_pixel
);
6148 x_update_cursor (f
, 1);
6152 frame_unhighlight (f
)
6155 /* We used to only do this if Vx_no_window_manager was non-nil, but
6156 the ICCCM (section 4.1.6) says that the window's border pixmap
6157 and border pixel are window attributes which are "private to the
6158 client", so we can always change it to whatever we want. */
6160 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6161 f
->output_data
.x
->border_tile
);
6163 x_update_cursor (f
, 1);
6166 /* The focus has changed. Update the frames as necessary to reflect
6167 the new situation. Note that we can't change the selected frame
6168 here, because the Lisp code we are interrupting might become confused.
6169 Each event gets marked with the frame in which it occurred, so the
6170 Lisp code can tell when the switch took place by examining the events. */
6173 x_new_focus_frame (dpyinfo
, frame
)
6174 struct x_display_info
*dpyinfo
;
6175 struct frame
*frame
;
6177 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6179 if (frame
!= dpyinfo
->x_focus_frame
)
6181 /* Set this before calling other routines, so that they see
6182 the correct value of x_focus_frame. */
6183 dpyinfo
->x_focus_frame
= frame
;
6185 if (old_focus
&& old_focus
->auto_lower
)
6186 x_lower_frame (old_focus
);
6189 selected_frame
= frame
;
6190 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6192 Fselect_window (selected_frame
->selected_window
);
6193 choose_minibuf_frame ();
6196 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6197 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6199 pending_autoraise_frame
= 0;
6202 x_frame_rehighlight (dpyinfo
);
6205 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6208 x_mouse_leave (dpyinfo
)
6209 struct x_display_info
*dpyinfo
;
6211 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6214 /* The focus has changed, or we have redirected a frame's focus to
6215 another frame (this happens when a frame uses a surrogate
6216 mini-buffer frame). Shift the highlight as appropriate.
6218 The FRAME argument doesn't necessarily have anything to do with which
6219 frame is being highlighted or un-highlighted; we only use it to find
6220 the appropriate X display info. */
6223 XTframe_rehighlight (frame
)
6224 struct frame
*frame
;
6226 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6230 x_frame_rehighlight (dpyinfo
)
6231 struct x_display_info
*dpyinfo
;
6233 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6235 if (dpyinfo
->x_focus_frame
)
6237 dpyinfo
->x_highlight_frame
6238 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6239 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6240 : dpyinfo
->x_focus_frame
);
6241 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6243 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6244 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6248 dpyinfo
->x_highlight_frame
= 0;
6250 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6253 frame_unhighlight (old_highlight
);
6254 if (dpyinfo
->x_highlight_frame
)
6255 frame_highlight (dpyinfo
->x_highlight_frame
);
6261 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6263 /* Initialize mode_switch_bit and modifier_meaning. */
6265 x_find_modifier_meanings (dpyinfo
)
6266 struct x_display_info
*dpyinfo
;
6268 int min_code
, max_code
;
6271 XModifierKeymap
*mods
;
6273 dpyinfo
->meta_mod_mask
= 0;
6274 dpyinfo
->shift_lock_mask
= 0;
6275 dpyinfo
->alt_mod_mask
= 0;
6276 dpyinfo
->super_mod_mask
= 0;
6277 dpyinfo
->hyper_mod_mask
= 0;
6280 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6282 min_code
= dpyinfo
->display
->min_keycode
;
6283 max_code
= dpyinfo
->display
->max_keycode
;
6286 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6287 min_code
, max_code
- min_code
+ 1,
6289 mods
= XGetModifierMapping (dpyinfo
->display
);
6291 /* Scan the modifier table to see which modifier bits the Meta and
6292 Alt keysyms are on. */
6294 int row
, col
; /* The row and column in the modifier table. */
6296 for (row
= 3; row
< 8; row
++)
6297 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6300 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6302 /* Zeroes are used for filler. Skip them. */
6306 /* Are any of this keycode's keysyms a meta key? */
6310 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6312 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6318 dpyinfo
->meta_mod_mask
|= (1 << row
);
6323 dpyinfo
->alt_mod_mask
|= (1 << row
);
6328 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6333 dpyinfo
->super_mod_mask
|= (1 << row
);
6337 /* Ignore this if it's not on the lock modifier. */
6338 if ((1 << row
) == LockMask
)
6339 dpyinfo
->shift_lock_mask
= LockMask
;
6347 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6348 if (! dpyinfo
->meta_mod_mask
)
6350 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6351 dpyinfo
->alt_mod_mask
= 0;
6354 /* If some keys are both alt and meta,
6355 make them just meta, not alt. */
6356 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6358 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6361 XFree ((char *) syms
);
6362 XFreeModifiermap (mods
);
6365 /* Convert between the modifier bits X uses and the modifier bits
6369 x_x_to_emacs_modifiers (dpyinfo
, state
)
6370 struct x_display_info
*dpyinfo
;
6373 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6374 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6375 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6376 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6377 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6378 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6382 x_emacs_to_x_modifiers (dpyinfo
, state
)
6383 struct x_display_info
*dpyinfo
;
6386 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6387 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6388 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6389 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6390 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6391 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6394 /* Convert a keysym to its name. */
6397 x_get_keysym_name (keysym
)
6403 value
= XKeysymToString (keysym
);
6411 /* Mouse clicks and mouse movement. Rah. */
6413 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6414 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6415 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6416 not force the value into range. */
6419 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6421 register int pix_x
, pix_y
;
6422 register int *x
, *y
;
6426 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6427 even for negative values. */
6429 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6431 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6433 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6434 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6438 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6439 bounds
->height
= f
->output_data
.x
->line_height
;
6440 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6441 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6448 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6449 pix_x
= FRAME_WINDOW_WIDTH (f
);
6453 else if (pix_y
> f
->height
)
6462 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6463 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6464 can't tell the positions because W's display is not up to date,
6468 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6471 int *frame_x
, *frame_y
;
6475 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6476 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6478 if (display_completed
)
6480 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6481 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6482 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6488 *frame_x
+= glyph
->pixel_width
;
6496 *frame_y
= *frame_x
= 0;
6500 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6501 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6506 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6508 If the event is a button press, then note that we have grabbed
6512 construct_mouse_click (result
, event
, f
)
6513 struct input_event
*result
;
6514 XButtonEvent
*event
;
6517 /* Make the event type no_event; we'll change that when we decide
6519 result
->kind
= mouse_click
;
6520 result
->code
= event
->button
- Button1
;
6521 result
->timestamp
= event
->time
;
6522 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6524 | (event
->type
== ButtonRelease
6528 XSETINT (result
->x
, event
->x
);
6529 XSETINT (result
->y
, event
->y
);
6530 XSETFRAME (result
->frame_or_window
, f
);
6536 /* Function to report a mouse movement to the mainstream Emacs code.
6537 The input handler calls this.
6539 We have received a mouse movement event, which is given in *event.
6540 If the mouse is over a different glyph than it was last time, tell
6541 the mainstream emacs code by setting mouse_moved. If not, ask for
6542 another motion event, so we can check again the next time it moves. */
6544 static XMotionEvent last_mouse_motion_event
;
6545 static Lisp_Object last_mouse_motion_frame
;
6548 note_mouse_movement (frame
, event
)
6550 XMotionEvent
*event
;
6552 last_mouse_movement_time
= event
->time
;
6553 last_mouse_motion_event
= *event
;
6554 XSETFRAME (last_mouse_motion_frame
, frame
);
6556 if (event
->window
!= FRAME_X_WINDOW (frame
))
6558 frame
->mouse_moved
= 1;
6559 last_mouse_scroll_bar
= Qnil
;
6560 note_mouse_highlight (frame
, -1, -1);
6563 /* Has the mouse moved off the glyph it was on at the last sighting? */
6564 else if (event
->x
< last_mouse_glyph
.x
6565 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6566 || event
->y
< last_mouse_glyph
.y
6567 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6569 frame
->mouse_moved
= 1;
6570 last_mouse_scroll_bar
= Qnil
;
6571 note_mouse_highlight (frame
, event
->x
, event
->y
);
6575 /* This is used for debugging, to turn off note_mouse_highlight. */
6577 int disable_mouse_highlight
;
6581 /************************************************************************
6583 ************************************************************************/
6585 /* Find the glyph under window-relative coordinates X/Y in window W.
6586 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6587 strings. Return in *HPOS and *VPOS the row and column number of
6588 the glyph found. Return in *AREA the glyph area containing X.
6589 Value is a pointer to the glyph found or null if X/Y is not on
6590 text, or we can't tell because W's current matrix is not up to
6593 static struct glyph
*
6594 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6597 int *hpos
, *vpos
, *area
;
6600 struct glyph
*glyph
, *end
;
6601 struct glyph_row
*row
= NULL
;
6602 int x0
, i
, left_area_width
;
6604 /* Find row containing Y. Give up if some row is not enabled. */
6605 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6607 row
= MATRIX_ROW (w
->current_matrix
, i
);
6608 if (!row
->enabled_p
)
6610 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6617 /* Give up if Y is not in the window. */
6618 if (i
== w
->current_matrix
->nrows
)
6621 /* Get the glyph area containing X. */
6622 if (w
->pseudo_window_p
)
6629 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6630 if (x
< left_area_width
)
6632 *area
= LEFT_MARGIN_AREA
;
6635 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6638 x0
= row
->x
+ left_area_width
;
6642 *area
= RIGHT_MARGIN_AREA
;
6643 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6647 /* Find glyph containing X. */
6648 glyph
= row
->glyphs
[*area
];
6649 end
= glyph
+ row
->used
[*area
];
6652 if (x
< x0
+ glyph
->pixel_width
)
6654 if (w
->pseudo_window_p
)
6656 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6660 x0
+= glyph
->pixel_width
;
6667 *hpos
= glyph
- row
->glyphs
[*area
];
6672 /* Convert frame-relative x/y to coordinates relative to window W.
6673 Takes pseudo-windows into account. */
6676 frame_to_window_pixel_xy (w
, x
, y
)
6680 if (w
->pseudo_window_p
)
6682 /* A pseudo-window is always full-width, and starts at the
6683 left edge of the frame, plus a frame border. */
6684 struct frame
*f
= XFRAME (w
->frame
);
6685 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6686 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6690 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6691 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6696 /* Take proper action when mouse has moved to the mode or header line of
6697 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6698 mode line. X is relative to the start of the text display area of
6699 W, so the width of bitmap areas and scroll bars must be subtracted
6700 to get a position relative to the start of the mode line. */
6703 note_mode_line_highlight (w
, x
, mode_line_p
)
6707 struct frame
*f
= XFRAME (w
->frame
);
6708 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6709 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6710 struct glyph_row
*row
;
6713 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6715 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6719 struct glyph
*glyph
, *end
;
6720 Lisp_Object help
, map
;
6723 /* Find the glyph under X. */
6724 glyph
= row
->glyphs
[TEXT_AREA
];
6725 end
= glyph
+ row
->used
[TEXT_AREA
];
6726 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6727 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6730 && x
>= x0
+ glyph
->pixel_width
)
6732 x0
+= glyph
->pixel_width
;
6737 && STRINGP (glyph
->object
)
6738 && XSTRING (glyph
->object
)->intervals
6739 && glyph
->charpos
>= 0
6740 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6742 /* If we're on a string with `help-echo' text property,
6743 arrange for the help to be displayed. This is done by
6744 setting the global variable help_echo to the help string. */
6745 help
= Fget_text_property (make_number (glyph
->charpos
),
6746 Qhelp_echo
, glyph
->object
);
6750 XSETWINDOW (help_echo_window
, w
);
6751 help_echo_object
= glyph
->object
;
6752 help_echo_pos
= glyph
->charpos
;
6755 /* Change the mouse pointer according to what is under X/Y. */
6756 map
= Fget_text_property (make_number (glyph
->charpos
),
6757 Qlocal_map
, glyph
->object
);
6759 cursor
= f
->output_data
.x
->nontext_cursor
;
6762 map
= Fget_text_property (make_number (glyph
->charpos
),
6763 Qkeymap
, glyph
->object
);
6765 cursor
= f
->output_data
.x
->nontext_cursor
;
6770 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6774 /* Take proper action when the mouse has moved to position X, Y on
6775 frame F as regards highlighting characters that have mouse-face
6776 properties. Also de-highlighting chars where the mouse was before.
6777 X and Y can be negative or out of range. */
6780 note_mouse_highlight (f
, x
, y
)
6784 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6789 /* When a menu is active, don't highlight because this looks odd. */
6790 #ifdef USE_X_TOOLKIT
6791 if (popup_activated ())
6795 if (disable_mouse_highlight
6796 || !f
->glyphs_initialized_p
)
6799 dpyinfo
->mouse_face_mouse_x
= x
;
6800 dpyinfo
->mouse_face_mouse_y
= y
;
6801 dpyinfo
->mouse_face_mouse_frame
= f
;
6803 if (dpyinfo
->mouse_face_defer
)
6808 dpyinfo
->mouse_face_deferred_gc
= 1;
6812 /* Which window is that in? */
6813 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6815 /* If we were displaying active text in another window, clear that. */
6816 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6817 clear_mouse_face (dpyinfo
);
6819 /* Not on a window -> return. */
6820 if (!WINDOWP (window
))
6823 /* Convert to window-relative pixel coordinates. */
6824 w
= XWINDOW (window
);
6825 frame_to_window_pixel_xy (w
, &x
, &y
);
6827 /* Handle tool-bar window differently since it doesn't display a
6829 if (EQ (window
, f
->tool_bar_window
))
6831 note_tool_bar_highlight (f
, x
, y
);
6835 if (portion
== 1 || portion
== 3)
6837 /* Mouse is on the mode or top line. */
6838 note_mode_line_highlight (w
, x
, portion
== 1);
6841 else if (portion
== 2)
6842 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6843 f
->output_data
.x
->horizontal_drag_cursor
);
6845 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6846 f
->output_data
.x
->text_cursor
);
6848 /* Are we in a window whose display is up to date?
6849 And verify the buffer's text has not changed. */
6850 if (/* Within text portion of the window. */
6852 && EQ (w
->window_end_valid
, w
->buffer
)
6853 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6854 && (XFASTINT (w
->last_overlay_modified
)
6855 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6857 int hpos
, vpos
, pos
, i
, area
;
6858 struct glyph
*glyph
;
6861 /* Find the glyph under X/Y. */
6862 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6864 /* Clear mouse face if X/Y not over text. */
6866 || area
!= TEXT_AREA
6867 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6869 clear_mouse_face (dpyinfo
);
6873 pos
= glyph
->charpos
;
6874 object
= glyph
->object
;
6875 if (!STRINGP (object
) && !BUFFERP (object
))
6879 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6880 Lisp_Object
*overlay_vec
= NULL
;
6882 struct buffer
*obuf
;
6885 /* If we get an out-of-range value, return now; avoid an error. */
6886 if (BUFFERP (object
) && pos
> BUF_Z (XBUFFER (w
->buffer
)))
6889 /* Make the window's buffer temporarily current for
6890 overlays_at and compute_char_face. */
6891 obuf
= current_buffer
;
6892 current_buffer
= XBUFFER (w
->buffer
);
6898 /* Is this char mouse-active or does it have help-echo? */
6899 position
= make_number (pos
);
6901 if (BUFFERP (object
))
6903 /* Put all the overlays we want in a vector in overlay_vec.
6904 Store the length in len. If there are more than 10, make
6905 enough space for all, and try again. */
6907 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6908 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6909 if (noverlays
> len
)
6912 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6913 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6916 /* Sort overlays into increasing priority order. */
6917 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6922 /* Check mouse-face highlighting. */
6923 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6924 && vpos
>= dpyinfo
->mouse_face_beg_row
6925 && vpos
<= dpyinfo
->mouse_face_end_row
6926 && (vpos
> dpyinfo
->mouse_face_beg_row
6927 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6928 && (vpos
< dpyinfo
->mouse_face_end_row
6929 || hpos
< dpyinfo
->mouse_face_end_col
6930 || dpyinfo
->mouse_face_past_end
))
6931 /* If there exists an overlay with mouse-face overlapping
6932 the one we are currently highlighting, we have to
6933 check if we enter the overlapping overlay, and then
6934 highlight only that. */
6935 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6936 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6939 /* Clear the display of the old active region, if any. */
6940 clear_mouse_face (dpyinfo
);
6942 /* Find the highest priority overlay that has a mouse-face
6945 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6947 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6948 if (!NILP (mouse_face
))
6949 overlay
= overlay_vec
[i
];
6951 dpyinfo
->mouse_face_overlay
= overlay
;
6953 /* If no overlay applies, get a text property. */
6955 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6957 /* Handle the overlay case. */
6958 if (!NILP (overlay
))
6960 /* Find the range of text around this char that
6961 should be active. */
6962 Lisp_Object before
, after
;
6965 before
= Foverlay_start (overlay
);
6966 after
= Foverlay_end (overlay
);
6967 /* Record this as the current active region. */
6968 fast_find_position (w
, XFASTINT (before
),
6969 &dpyinfo
->mouse_face_beg_col
,
6970 &dpyinfo
->mouse_face_beg_row
,
6971 &dpyinfo
->mouse_face_beg_x
,
6972 &dpyinfo
->mouse_face_beg_y
);
6973 dpyinfo
->mouse_face_past_end
6974 = !fast_find_position (w
, XFASTINT (after
),
6975 &dpyinfo
->mouse_face_end_col
,
6976 &dpyinfo
->mouse_face_end_row
,
6977 &dpyinfo
->mouse_face_end_x
,
6978 &dpyinfo
->mouse_face_end_y
);
6979 dpyinfo
->mouse_face_window
= window
;
6980 dpyinfo
->mouse_face_face_id
6981 = face_at_buffer_position (w
, pos
, 0, 0,
6982 &ignore
, pos
+ 1, 1);
6984 /* Display it as active. */
6985 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6987 /* Handle the text property case. */
6988 else if (!NILP (mouse_face
) && BUFFERP (object
))
6990 /* Find the range of text around this char that
6991 should be active. */
6992 Lisp_Object before
, after
, beginning
, end
;
6995 beginning
= Fmarker_position (w
->start
);
6996 end
= make_number (BUF_Z (XBUFFER (object
))
6997 - XFASTINT (w
->window_end_pos
));
6999 = Fprevious_single_property_change (make_number (pos
+ 1),
7003 = Fnext_single_property_change (position
, Qmouse_face
,
7006 /* Record this as the current active region. */
7007 fast_find_position (w
, XFASTINT (before
),
7008 &dpyinfo
->mouse_face_beg_col
,
7009 &dpyinfo
->mouse_face_beg_row
,
7010 &dpyinfo
->mouse_face_beg_x
,
7011 &dpyinfo
->mouse_face_beg_y
);
7012 dpyinfo
->mouse_face_past_end
7013 = !fast_find_position (w
, XFASTINT (after
),
7014 &dpyinfo
->mouse_face_end_col
,
7015 &dpyinfo
->mouse_face_end_row
,
7016 &dpyinfo
->mouse_face_end_x
,
7017 &dpyinfo
->mouse_face_end_y
);
7018 dpyinfo
->mouse_face_window
= window
;
7020 if (BUFFERP (object
))
7021 dpyinfo
->mouse_face_face_id
7022 = face_at_buffer_position (w
, pos
, 0, 0,
7023 &ignore
, pos
+ 1, 1);
7025 /* Display it as active. */
7026 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7028 else if (!NILP (mouse_face
) && STRINGP (object
))
7033 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7036 e
= Fnext_single_property_change (position
, Qmouse_face
,
7039 b
= make_number (0);
7041 e
= make_number (XSTRING (object
)->size
- 1);
7042 fast_find_string_pos (w
, XINT (b
), object
,
7043 &dpyinfo
->mouse_face_beg_col
,
7044 &dpyinfo
->mouse_face_beg_row
,
7045 &dpyinfo
->mouse_face_beg_x
,
7046 &dpyinfo
->mouse_face_beg_y
, 0);
7047 fast_find_string_pos (w
, XINT (e
), object
,
7048 &dpyinfo
->mouse_face_end_col
,
7049 &dpyinfo
->mouse_face_end_row
,
7050 &dpyinfo
->mouse_face_end_x
,
7051 &dpyinfo
->mouse_face_end_y
, 1);
7052 dpyinfo
->mouse_face_past_end
= 0;
7053 dpyinfo
->mouse_face_window
= window
;
7054 dpyinfo
->mouse_face_face_id
7055 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7057 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7061 /* Look for a `help-echo' property. */
7063 Lisp_Object help
, overlay
;
7065 /* Check overlays first. */
7066 help
= overlay
= Qnil
;
7067 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7069 overlay
= overlay_vec
[i
];
7070 help
= Foverlay_get (overlay
, Qhelp_echo
);
7076 help_echo_window
= window
;
7077 help_echo_object
= overlay
;
7078 help_echo_pos
= pos
;
7082 Lisp_Object object
= glyph
->object
;
7083 int charpos
= glyph
->charpos
;
7085 /* Try text properties. */
7086 if (STRINGP (object
)
7088 && charpos
< XSTRING (object
)->size
)
7090 help
= Fget_text_property (make_number (charpos
),
7091 Qhelp_echo
, object
);
7094 /* If the string itself doesn't specify a help-echo,
7095 see if the buffer text ``under'' it does. */
7097 = MATRIX_ROW (w
->current_matrix
, vpos
);
7098 int start
= MATRIX_ROW_START_CHARPOS (r
);
7099 int pos
= string_buffer_position (w
, object
, start
);
7102 help
= Fget_text_property (make_number (pos
),
7103 Qhelp_echo
, w
->buffer
);
7112 else if (BUFFERP (object
)
7115 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7121 help_echo_window
= window
;
7122 help_echo_object
= object
;
7123 help_echo_pos
= charpos
;
7130 current_buffer
= obuf
;
7136 redo_mouse_highlight ()
7138 if (!NILP (last_mouse_motion_frame
)
7139 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7140 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7141 last_mouse_motion_event
.x
,
7142 last_mouse_motion_event
.y
);
7147 /***********************************************************************
7149 ***********************************************************************/
7151 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7152 struct glyph
**, int *, int *, int *));
7154 /* Tool-bar item index of the item on which a mouse button was pressed
7157 static int last_tool_bar_item
;
7160 /* Get information about the tool-bar item at position X/Y on frame F.
7161 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7162 the current matrix of the tool-bar window of F, or NULL if not
7163 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7164 item in F->tool_bar_items. Value is
7166 -1 if X/Y is not on a tool-bar item
7167 0 if X/Y is on the same item that was highlighted before.
7171 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7174 struct glyph
**glyph
;
7175 int *hpos
, *vpos
, *prop_idx
;
7177 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7178 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7181 /* Find the glyph under X/Y. */
7182 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7186 /* Get the start of this tool-bar item's properties in
7187 f->tool_bar_items. */
7188 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7191 /* Is mouse on the highlighted item? */
7192 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7193 && *vpos
>= dpyinfo
->mouse_face_beg_row
7194 && *vpos
<= dpyinfo
->mouse_face_end_row
7195 && (*vpos
> dpyinfo
->mouse_face_beg_row
7196 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7197 && (*vpos
< dpyinfo
->mouse_face_end_row
7198 || *hpos
< dpyinfo
->mouse_face_end_col
7199 || dpyinfo
->mouse_face_past_end
))
7206 /* Handle mouse button event on the tool-bar of frame F, at
7207 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7211 x_handle_tool_bar_click (f
, button_event
)
7213 XButtonEvent
*button_event
;
7215 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7216 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7217 int hpos
, vpos
, prop_idx
;
7218 struct glyph
*glyph
;
7219 Lisp_Object enabled_p
;
7220 int x
= button_event
->x
;
7221 int y
= button_event
->y
;
7223 /* If not on the highlighted tool-bar item, return. */
7224 frame_to_window_pixel_xy (w
, &x
, &y
);
7225 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7228 /* If item is disabled, do nothing. */
7229 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7230 if (NILP (enabled_p
))
7233 if (button_event
->type
== ButtonPress
)
7235 /* Show item in pressed state. */
7236 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7237 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7238 last_tool_bar_item
= prop_idx
;
7242 Lisp_Object key
, frame
;
7243 struct input_event event
;
7245 /* Show item in released state. */
7246 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7247 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7249 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7251 XSETFRAME (frame
, f
);
7252 event
.kind
= TOOL_BAR_EVENT
;
7253 event
.frame_or_window
= frame
;
7255 kbd_buffer_store_event (&event
);
7257 event
.kind
= TOOL_BAR_EVENT
;
7258 event
.frame_or_window
= frame
;
7260 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7261 button_event
->state
);
7262 kbd_buffer_store_event (&event
);
7263 last_tool_bar_item
= -1;
7268 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7269 tool-bar window-relative coordinates X/Y. Called from
7270 note_mouse_highlight. */
7273 note_tool_bar_highlight (f
, x
, y
)
7277 Lisp_Object window
= f
->tool_bar_window
;
7278 struct window
*w
= XWINDOW (window
);
7279 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7281 struct glyph
*glyph
;
7282 struct glyph_row
*row
;
7284 Lisp_Object enabled_p
;
7286 enum draw_glyphs_face draw
;
7287 int mouse_down_p
, rc
;
7289 /* Function note_mouse_highlight is called with negative x(y
7290 values when mouse moves outside of the frame. */
7291 if (x
<= 0 || y
<= 0)
7293 clear_mouse_face (dpyinfo
);
7297 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7300 /* Not on tool-bar item. */
7301 clear_mouse_face (dpyinfo
);
7307 clear_mouse_face (dpyinfo
);
7309 /* Mouse is down, but on different tool-bar item? */
7310 mouse_down_p
= (dpyinfo
->grabbed
7311 && f
== last_mouse_frame
7312 && FRAME_LIVE_P (f
));
7314 && last_tool_bar_item
!= prop_idx
)
7317 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7318 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7320 /* If tool-bar item is not enabled, don't highlight it. */
7321 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7322 if (!NILP (enabled_p
))
7324 /* Compute the x-position of the glyph. In front and past the
7325 image is a space. We include this is the highlighted area. */
7326 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7327 for (i
= x
= 0; i
< hpos
; ++i
)
7328 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7330 /* Record this as the current active region. */
7331 dpyinfo
->mouse_face_beg_col
= hpos
;
7332 dpyinfo
->mouse_face_beg_row
= vpos
;
7333 dpyinfo
->mouse_face_beg_x
= x
;
7334 dpyinfo
->mouse_face_beg_y
= row
->y
;
7335 dpyinfo
->mouse_face_past_end
= 0;
7337 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7338 dpyinfo
->mouse_face_end_row
= vpos
;
7339 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7340 dpyinfo
->mouse_face_end_y
= row
->y
;
7341 dpyinfo
->mouse_face_window
= window
;
7342 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7344 /* Display it as active. */
7345 show_mouse_face (dpyinfo
, draw
);
7346 dpyinfo
->mouse_face_image_state
= draw
;
7351 /* Set help_echo to a help string.to display for this tool-bar item.
7352 XTread_socket does the rest. */
7353 help_echo_object
= help_echo_window
= Qnil
;
7355 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7356 if (NILP (help_echo
))
7357 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7362 /* Find the glyph matrix position of buffer position POS in window W.
7363 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7364 current glyphs must be up to date. If POS is above window start
7365 return (0, 0, 0, 0). If POS is after end of W, return end of
7369 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
7372 int *hpos
, *vpos
, *x
, *y
;
7376 int maybe_next_line_p
= 0;
7377 int line_start_position
;
7378 int yb
= window_text_bottom_y (w
);
7379 struct glyph_row
*row
, *best_row
;
7380 int row_vpos
, best_row_vpos
;
7383 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7384 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7388 if (row
->used
[TEXT_AREA
])
7389 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7391 line_start_position
= 0;
7393 if (line_start_position
> pos
)
7395 /* If the position sought is the end of the buffer,
7396 don't include the blank lines at the bottom of the window. */
7397 else if (line_start_position
== pos
7398 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7400 maybe_next_line_p
= 1;
7403 else if (line_start_position
> 0)
7406 best_row_vpos
= row_vpos
;
7409 if (row
->y
+ row
->height
>= yb
)
7416 /* Find the right column within BEST_ROW. */
7418 current_x
= best_row
->x
;
7419 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7421 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7424 charpos
= glyph
->charpos
;
7428 *vpos
= best_row_vpos
;
7433 else if (charpos
> pos
)
7435 else if (charpos
> 0)
7438 current_x
+= glyph
->pixel_width
;
7441 /* If we're looking for the end of the buffer,
7442 and we didn't find it in the line we scanned,
7443 use the start of the following line. */
7444 if (maybe_next_line_p
)
7449 current_x
= best_row
->x
;
7452 *vpos
= best_row_vpos
;
7453 *hpos
= lastcol
+ 1;
7460 /* Find the position of the the glyph for position POS in OBJECT in
7461 window W's current matrix, and return in *X/*Y the pixel
7462 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7464 RIGHT_P non-zero means return the position of the right edge of the
7465 glyph, RIGHT_P zero means return the left edge position.
7467 If no glyph for POS exists in the matrix, return the position of
7468 the glyph with the next smaller position that is in the matrix, if
7469 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7470 exists in the matrix, return the position of the glyph with the
7471 next larger position in OBJECT.
7473 Value is non-zero if a glyph was found. */
7476 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7480 int *hpos
, *vpos
, *x
, *y
;
7483 int yb
= window_text_bottom_y (w
);
7484 struct glyph_row
*r
;
7485 struct glyph
*best_glyph
= NULL
;
7486 struct glyph_row
*best_row
= NULL
;
7489 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7490 r
->enabled_p
&& r
->y
< yb
;
7493 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7494 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7497 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7498 if (EQ (g
->object
, object
))
7500 if (g
->charpos
== pos
)
7507 else if (best_glyph
== NULL
7508 || ((abs (g
->charpos
- pos
)
7509 < abs (best_glyph
->charpos
- pos
))
7512 : g
->charpos
> pos
)))
7526 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7530 *x
+= best_glyph
->pixel_width
;
7535 *vpos
= best_row
- w
->current_matrix
->rows
;
7538 return best_glyph
!= NULL
;
7542 /* Display the active region described by mouse_face_*
7543 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7546 show_mouse_face (dpyinfo
, draw
)
7547 struct x_display_info
*dpyinfo
;
7548 enum draw_glyphs_face draw
;
7550 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7551 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7553 int cursor_off_p
= 0;
7554 struct cursor_pos saved_cursor
;
7556 saved_cursor
= output_cursor
;
7558 /* If window is in the process of being destroyed, don't bother
7560 if (w
->current_matrix
== NULL
)
7563 /* Recognize when we are called to operate on rows that don't exist
7564 anymore. This can happen when a window is split. */
7565 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7568 set_output_cursor (&w
->phys_cursor
);
7570 /* Note that mouse_face_beg_row etc. are window relative. */
7571 for (i
= dpyinfo
->mouse_face_beg_row
;
7572 i
<= dpyinfo
->mouse_face_end_row
;
7575 int start_hpos
, end_hpos
, start_x
;
7576 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7578 /* Don't do anything if row doesn't have valid contents. */
7579 if (!row
->enabled_p
)
7582 /* For all but the first row, the highlight starts at column 0. */
7583 if (i
== dpyinfo
->mouse_face_beg_row
)
7585 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7586 start_x
= dpyinfo
->mouse_face_beg_x
;
7594 if (i
== dpyinfo
->mouse_face_end_row
)
7595 end_hpos
= dpyinfo
->mouse_face_end_col
;
7597 end_hpos
= row
->used
[TEXT_AREA
];
7599 /* If the cursor's in the text we are about to rewrite, turn the
7601 if (!w
->pseudo_window_p
7602 && i
== output_cursor
.vpos
7603 && output_cursor
.hpos
>= start_hpos
- 1
7604 && output_cursor
.hpos
<= end_hpos
)
7606 x_update_window_cursor (w
, 0);
7610 if (end_hpos
> start_hpos
)
7612 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7613 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7614 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7618 /* If we turned the cursor off, turn it back on. */
7620 x_display_cursor (w
, 1,
7621 output_cursor
.hpos
, output_cursor
.vpos
,
7622 output_cursor
.x
, output_cursor
.y
);
7624 output_cursor
= saved_cursor
;
7628 /* Change the mouse cursor. */
7629 if (draw
== DRAW_NORMAL_TEXT
)
7630 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7631 f
->output_data
.x
->text_cursor
);
7632 else if (draw
== DRAW_MOUSE_FACE
)
7633 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7634 f
->output_data
.x
->cross_cursor
);
7636 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7637 f
->output_data
.x
->nontext_cursor
);
7640 /* Clear out the mouse-highlighted active region.
7641 Redraw it un-highlighted first. */
7644 clear_mouse_face (dpyinfo
)
7645 struct x_display_info
*dpyinfo
;
7647 #if 0 /* This prevents redrawing tool bar items when changing from one
7648 to another while a tooltip is open, so don't do it. */
7649 if (!NILP (tip_frame
))
7653 if (! NILP (dpyinfo
->mouse_face_window
))
7654 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7656 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7657 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7658 dpyinfo
->mouse_face_window
= Qnil
;
7662 /* Clear any mouse-face on window W. This function is part of the
7663 redisplay interface, and is called from try_window_id and similar
7664 functions to ensure the mouse-highlight is off. */
7667 x_clear_mouse_face (w
)
7670 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7674 XSETWINDOW (window
, w
);
7675 if (EQ (window
, dpyinfo
->mouse_face_window
))
7676 clear_mouse_face (dpyinfo
);
7681 /* Just discard the mouse face information for frame F, if any.
7682 This is used when the size of F is changed. */
7685 cancel_mouse_face (f
)
7689 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7691 window
= dpyinfo
->mouse_face_window
;
7692 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7694 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7695 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7696 dpyinfo
->mouse_face_window
= Qnil
;
7701 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
7704 /* Try to determine frame pixel position and size of the glyph under
7705 frame pixel coordinates X/Y on frame F . Return the position and
7706 size in *RECT. Value is non-zero if we could compute these
7710 glyph_rect (f
, x
, y
, rect
)
7716 int part
, found
= 0;
7718 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7721 struct window
*w
= XWINDOW (window
);
7722 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7723 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7726 frame_to_window_pixel_xy (w
, &x
, &y
);
7728 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7731 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7732 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7735 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7738 rect
->width
= g
->pixel_width
;
7739 rect
->height
= r
->height
;
7740 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7741 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7751 /* Return the current position of the mouse.
7752 *FP should be a frame which indicates which display to ask about.
7754 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
7755 and *PART to the frame, window, and scroll bar part that the mouse
7756 is over. Set *X and *Y to the portion and whole of the mouse's
7757 position on the scroll bar.
7759 If the mouse movement started elsewhere, set *FP to the frame the
7760 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
7763 Set *TIME to the server time-stamp for the time at which the mouse
7764 was at this position.
7766 Don't store anything if we don't have a valid set of values to report.
7768 This clears the mouse_moved flag, so we can wait for the next mouse
7772 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7775 Lisp_Object
*bar_window
;
7776 enum scroll_bar_part
*part
;
7778 unsigned long *time
;
7784 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7785 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7791 Window dummy_window
;
7794 Lisp_Object frame
, tail
;
7796 /* Clear the mouse-moved flag for every frame on this display. */
7797 FOR_EACH_FRAME (tail
, frame
)
7798 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7799 XFRAME (frame
)->mouse_moved
= 0;
7801 last_mouse_scroll_bar
= Qnil
;
7803 /* Figure out which root window we're on. */
7804 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7805 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7807 /* The root window which contains the pointer. */
7810 /* Trash which we can't trust if the pointer is on
7811 a different screen. */
7814 /* The position on that root window. */
7817 /* More trash we can't trust. */
7820 /* Modifier keys and pointer buttons, about which
7822 (unsigned int *) &dummy
);
7824 /* Now we have a position on the root; find the innermost window
7825 containing the pointer. */
7829 int parent_x
= 0, parent_y
= 0;
7834 /* XTranslateCoordinates can get errors if the window
7835 structure is changing at the same time this function
7836 is running. So at least we must not crash from them. */
7838 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
7840 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7841 && FRAME_LIVE_P (last_mouse_frame
))
7843 /* If mouse was grabbed on a frame, give coords for that frame
7844 even if the mouse is now outside it. */
7845 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7847 /* From-window, to-window. */
7848 root
, FRAME_X_WINDOW (last_mouse_frame
),
7850 /* From-position, to-position. */
7851 root_x
, root_y
, &win_x
, &win_y
,
7855 f1
= last_mouse_frame
;
7861 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7863 /* From-window, to-window. */
7866 /* From-position, to-position. */
7867 root_x
, root_y
, &win_x
, &win_y
,
7872 if (child
== None
|| child
== win
)
7880 /* Now we know that:
7881 win is the innermost window containing the pointer
7882 (XTC says it has no child containing the pointer),
7883 win_x and win_y are the pointer's position in it
7884 (XTC did this the last time through), and
7885 parent_x and parent_y are the pointer's position in win's parent.
7886 (They are what win_x and win_y were when win was child.
7887 If win is the root window, it has no parent, and
7888 parent_{x,y} are invalid, but that's okay, because we'll
7889 never use them in that case.) */
7891 /* Is win one of our frames? */
7892 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
7894 #ifdef USE_X_TOOLKIT
7895 /* If we end up with the menu bar window, say it's not
7898 && f1
->output_data
.x
->menubar_widget
7899 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
7901 #endif /* USE_X_TOOLKIT */
7904 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
7907 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
7909 /* If not, is it one of our scroll bars? */
7912 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
7916 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7922 if (f1
== 0 && insist
> 0)
7923 f1
= SELECTED_FRAME ();
7927 /* Ok, we found a frame. Store all the values.
7928 last_mouse_glyph is a rectangle used to reduce the
7929 generation of mouse events. To not miss any motion
7930 events, we must divide the frame into rectangles of the
7931 size of the smallest character that could be displayed
7932 on it, i.e. into the same rectangles that matrices on
7933 the frame are divided into. */
7935 int width
, height
, gx
, gy
;
7938 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
7939 last_mouse_glyph
= rect
;
7942 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7943 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7947 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7948 round down even for negative values. */
7953 gx
= (gx
+ width
- 1) / width
* width
;
7954 gy
= (gy
+ height
- 1) / height
* height
;
7956 last_mouse_glyph
.width
= width
;
7957 last_mouse_glyph
.height
= height
;
7958 last_mouse_glyph
.x
= gx
;
7959 last_mouse_glyph
.y
= gy
;
7965 XSETINT (*x
, win_x
);
7966 XSETINT (*y
, win_y
);
7967 *time
= last_mouse_movement_time
;
7976 #ifdef USE_X_TOOLKIT
7978 /* Atimer callback function for TIMER. Called every 0.1s to process
7979 Xt timeouts, if needed. We must avoid calling XtAppPending as
7980 much as possible because that function does an implicit XFlush
7981 that slows us down. */
7984 x_process_timeouts (timer
)
7985 struct atimer
*timer
;
7987 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
7990 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
7991 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
7996 #endif /* USE_X_TOOLKIT */
7999 /* Scroll bar support. */
8001 /* Given an X window ID, find the struct scroll_bar which manages it.
8002 This can be called in GC, so we have to make sure to strip off mark
8005 static struct scroll_bar
*
8006 x_window_to_scroll_bar (window_id
)
8011 for (tail
= Vframe_list
;
8012 XGCTYPE (tail
) == Lisp_Cons
;
8015 Lisp_Object frame
, bar
, condemned
;
8017 frame
= XCAR (tail
);
8018 /* All elements of Vframe_list should be frames. */
8019 if (! GC_FRAMEP (frame
))
8022 /* Scan this frame's scroll bar list for a scroll bar with the
8024 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
8025 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
8026 /* This trick allows us to search both the ordinary and
8027 condemned scroll bar lists with one loop. */
8028 ! GC_NILP (bar
) || (bar
= condemned
,
8031 bar
= XSCROLL_BAR (bar
)->next
)
8032 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
8033 return XSCROLL_BAR (bar
);
8041 /************************************************************************
8043 ************************************************************************/
8045 #ifdef USE_TOOLKIT_SCROLL_BARS
8047 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
8048 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
8049 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
8050 struct scroll_bar
*));
8051 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
8055 /* Id of action hook installed for scroll bars. */
8057 static XtActionHookId action_hook_id
;
8059 /* Lisp window being scrolled. Set when starting to interact with
8060 a toolkit scroll bar, reset to nil when ending the interaction. */
8062 static Lisp_Object window_being_scrolled
;
8064 /* Last scroll bar part sent in xm_scroll_callback. */
8066 static int last_scroll_bar_part
;
8068 /* Whether this is an Xaw with arrow-scrollbars. This should imply
8069 that movements of 1/20 of the screen size are mapped to up/down. */
8071 static Boolean xaw3d_arrow_scroll
;
8073 /* Whether the drag scrolling maintains the mouse at the top of the
8074 thumb. If not, resizing the thumb needs to be done more carefully
8075 to avoid jerkyness. */
8077 static Boolean xaw3d_pick_top
;
8080 /* Action hook installed via XtAppAddActionHook when toolkit scroll
8081 bars are used.. The hook is responsible for detecting when
8082 the user ends an interaction with the scroll bar, and generates
8083 a `end-scroll' scroll_bar_click' event if so. */
8086 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
8089 XtPointer client_data
;
8093 Cardinal
*num_params
;
8099 scroll_bar_p
= XmIsScrollBar (widget
);
8100 end_action
= "Release";
8101 #else /* !USE_MOTIF i.e. use Xaw */
8102 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
8103 end_action
= "EndScroll";
8104 #endif /* USE_MOTIF */
8107 && strcmp (action_name
, end_action
) == 0
8108 && WINDOWP (window_being_scrolled
))
8112 x_send_scroll_bar_event (window_being_scrolled
,
8113 scroll_bar_end_scroll
, 0, 0);
8114 w
= XWINDOW (window_being_scrolled
);
8115 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
8116 window_being_scrolled
= Qnil
;
8117 last_scroll_bar_part
= -1;
8119 /* Xt timeouts no longer needed. */
8120 toolkit_scroll_bar_interaction
= 0;
8124 /* A vector of windows used for communication between
8125 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
8127 static struct window
**scroll_bar_windows
;
8128 static int scroll_bar_windows_size
;
8131 /* Send a client message with message type Xatom_Scrollbar for a
8132 scroll action to the frame of WINDOW. PART is a value identifying
8133 the part of the scroll bar that was clicked on. PORTION is the
8134 amount to scroll of a whole of WHOLE. */
8137 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8139 int part
, portion
, whole
;
8142 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8143 struct window
*w
= XWINDOW (window
);
8144 struct frame
*f
= XFRAME (w
->frame
);
8149 /* Construct a ClientMessage event to send to the frame. */
8150 ev
->type
= ClientMessage
;
8151 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8152 ev
->display
= FRAME_X_DISPLAY (f
);
8153 ev
->window
= FRAME_X_WINDOW (f
);
8156 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8157 not enough to store a pointer or Lisp_Object on a 64 bit system.
8158 So, store the window in scroll_bar_windows and pass the index
8159 into that array in the event. */
8160 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8161 if (scroll_bar_windows
[i
] == NULL
)
8164 if (i
== scroll_bar_windows_size
)
8166 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8167 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8168 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8170 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8172 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8173 scroll_bar_windows_size
= new_size
;
8176 scroll_bar_windows
[i
] = w
;
8177 ev
->data
.l
[0] = (long) i
;
8178 ev
->data
.l
[1] = (long) part
;
8179 ev
->data
.l
[2] = (long) 0;
8180 ev
->data
.l
[3] = (long) portion
;
8181 ev
->data
.l
[4] = (long) whole
;
8183 /* Make Xt timeouts work while the scroll bar is active. */
8184 toolkit_scroll_bar_interaction
= 1;
8186 /* Setting the event mask to zero means that the message will
8187 be sent to the client that created the window, and if that
8188 window no longer exists, no event will be sent. */
8189 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8194 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8198 x_scroll_bar_to_input_event (event
, ievent
)
8200 struct input_event
*ievent
;
8202 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8207 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8208 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8210 XSETWINDOW (window
, w
);
8211 f
= XFRAME (w
->frame
);
8213 ievent
->kind
= scroll_bar_click
;
8214 ievent
->frame_or_window
= window
;
8216 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8217 ievent
->part
= ev
->data
.l
[1];
8218 ievent
->code
= ev
->data
.l
[2];
8219 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8220 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8221 ievent
->modifiers
= 0;
8227 /* Minimum and maximum values used for Motif scroll bars. */
8230 #define XM_SB_MAX 10000000
8231 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8234 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8235 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8236 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
8239 xm_scroll_callback (widget
, client_data
, call_data
)
8241 XtPointer client_data
, call_data
;
8243 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8244 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8246 int part
= -1, whole
= 0, portion
= 0;
8250 case XmCR_DECREMENT
:
8251 bar
->dragging
= Qnil
;
8252 part
= scroll_bar_up_arrow
;
8255 case XmCR_INCREMENT
:
8256 bar
->dragging
= Qnil
;
8257 part
= scroll_bar_down_arrow
;
8260 case XmCR_PAGE_DECREMENT
:
8261 bar
->dragging
= Qnil
;
8262 part
= scroll_bar_above_handle
;
8265 case XmCR_PAGE_INCREMENT
:
8266 bar
->dragging
= Qnil
;
8267 part
= scroll_bar_below_handle
;
8271 bar
->dragging
= Qnil
;
8272 part
= scroll_bar_to_top
;
8275 case XmCR_TO_BOTTOM
:
8276 bar
->dragging
= Qnil
;
8277 part
= scroll_bar_to_bottom
;
8283 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8284 && XINT (bar
->dragging
) <= cs
->value
);
8286 /* Get the slider size. */
8288 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8291 /* At the max position of the scroll bar, do a line-wise
8292 movement. Without doing anything, we would be called with
8293 the same cs->value again and again. If we want to make
8294 sure that we can reach the end of the buffer, we have to do
8297 Implementation note: setting bar->dragging always to
8298 cs->value gives a smoother movement at the max position.
8299 Setting it to nil when doing line-wise movement gives
8300 a better slider behavior. */
8302 if (cs
->value
+ slider_size
== XM_SB_MAX
8304 && last_scroll_bar_part
== scroll_bar_down_arrow
))
8306 part
= scroll_bar_down_arrow
;
8307 bar
->dragging
= Qnil
;
8311 whole
= XM_SB_RANGE
;
8312 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
8313 part
= scroll_bar_handle
;
8314 bar
->dragging
= make_number (cs
->value
);
8319 case XmCR_VALUE_CHANGED
:
8325 window_being_scrolled
= bar
->window
;
8326 last_scroll_bar_part
= part
;
8327 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8332 #else /* !USE_MOTIF, i.e. Xaw. */
8335 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8336 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8337 scroll bar struct. CALL_DATA is a pointer to a float saying where
8341 xaw_jump_callback (widget
, client_data
, call_data
)
8343 XtPointer client_data
, call_data
;
8345 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8346 float top
= *(float *) call_data
;
8348 int whole
, portion
, height
;
8351 /* Get the size of the thumb, a value between 0 and 1. */
8353 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8357 portion
= shown
< 1 ? top
* whole
: 0;
8359 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8360 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8361 the bottom, so we force the scrolling whenever we see that we're
8362 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8363 we try to ensure that we always stay two pixels away from the
8365 part
= scroll_bar_down_arrow
;
8367 part
= scroll_bar_handle
;
8369 window_being_scrolled
= bar
->window
;
8370 bar
->dragging
= make_number (portion
);
8371 last_scroll_bar_part
= part
;
8372 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8376 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8377 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8378 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8379 the scroll bar. CALL_DATA is an integer specifying the action that
8380 has taken place. It's magnitude is in the range 0..height of the
8381 scroll bar. Negative values mean scroll towards buffer start.
8382 Values < height of scroll bar mean line-wise movement. */
8385 xaw_scroll_callback (widget
, client_data
, call_data
)
8387 XtPointer client_data
, call_data
;
8389 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8390 int position
= (int) call_data
;
8394 /* Get the height of the scroll bar. */
8396 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8399 if (abs (position
) >= height
)
8400 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8402 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8403 it maps line-movement to call_data = max(5, height/20). */
8404 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8405 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8407 part
= scroll_bar_move_ratio
;
8409 window_being_scrolled
= bar
->window
;
8410 bar
->dragging
= Qnil
;
8411 last_scroll_bar_part
= part
;
8412 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8416 #endif /* not USE_MOTIF */
8419 /* Create the widget for scroll bar BAR on frame F. Record the widget
8420 and X window of the scroll bar in BAR. */
8423 x_create_toolkit_scroll_bar (f
, bar
)
8425 struct scroll_bar
*bar
;
8431 char *scroll_bar_name
= "verticalScrollBar";
8432 unsigned long pixel
;
8437 /* Set resources. Create the widget. */
8438 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8439 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8440 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8441 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8442 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8443 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8444 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8446 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8449 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8453 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8456 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8460 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8461 scroll_bar_name
, av
, ac
);
8463 /* Add one callback for everything that can happen. */
8464 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8466 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8468 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8470 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8472 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8474 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8476 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8479 /* Realize the widget. Only after that is the X window created. */
8480 XtRealizeWidget (widget
);
8482 /* Set the cursor to an arrow. I didn't find a resource to do that.
8483 And I'm wondering why it hasn't an arrow cursor by default. */
8484 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8485 f
->output_data
.x
->nontext_cursor
);
8487 #else /* !USE_MOTIF i.e. use Xaw */
8489 /* Set resources. Create the widget. The background of the
8490 Xaw3d scroll bar widget is a little bit light for my taste.
8491 We don't alter it here to let users change it according
8492 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8493 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8494 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8495 /* For smoother scrolling with Xaw3d -sm */
8496 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8497 /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
8499 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8502 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8506 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8509 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8513 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8514 f
->output_data
.x
->edit_widget
, av
, ac
);
8518 char *val
= initial
;
8519 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8520 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8522 { /* ARROW_SCROLL */
8523 xaw3d_arrow_scroll
= True
;
8524 /* Isn't that just a personal preference ? -sm */
8525 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8529 /* Define callbacks. */
8530 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8531 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8534 /* Realize the widget. Only after that is the X window created. */
8535 XtRealizeWidget (widget
);
8537 #endif /* !USE_MOTIF */
8539 /* Install an action hook that let's us detect when the user
8540 finishes interacting with a scroll bar. */
8541 if (action_hook_id
== 0)
8542 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8544 /* Remember X window and widget in the scroll bar vector. */
8545 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8546 xwindow
= XtWindow (widget
);
8547 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8553 /* Set the thumb size and position of scroll bar BAR. We are currently
8554 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8557 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8558 struct scroll_bar
*bar
;
8559 int portion
, position
, whole
;
8561 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8562 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8569 top
= (float) position
/ whole
;
8570 shown
= (float) portion
/ whole
;
8578 XmScrollBarWidget sb
;
8580 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8581 is the scroll bar's maximum and MIN is the scroll bar's minimum
8583 size
= shown
* XM_SB_RANGE
;
8584 size
= min (size
, XM_SB_RANGE
);
8585 size
= max (size
, 1);
8587 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8588 value
= top
* XM_SB_RANGE
;
8589 value
= min (value
, XM_SB_MAX
- size
);
8590 value
= max (value
, XM_SB_MIN
);
8592 if (NILP (bar
->dragging
))
8593 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8594 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8595 /* This has the negative side effect that the slider value is
8596 not what it would be if we scrolled here using line-wise or
8597 page-wise movement. */
8598 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8601 /* If currently dragging, only update the slider size.
8602 This reduces flicker effects. */
8603 int old_value
, old_size
, increment
, page_increment
;
8605 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8606 &increment
, &page_increment
);
8607 XmScrollBarSetValues (widget
, old_value
,
8608 min (size
, XM_SB_RANGE
- old_value
),
8612 #else /* !USE_MOTIF i.e. use Xaw */
8614 float old_top
, old_shown
;
8616 XtVaGetValues (widget
,
8617 XtNtopOfThumb
, &old_top
,
8618 XtNshown
, &old_shown
,
8622 /* Massage the top+shown values. */
8623 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8624 top
= max (0, min (1, top
));
8627 /* Keep two pixels available for moving the thumb down. */
8628 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8630 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8631 check that your system's configuration file contains a define
8632 for `NARROWPROTO'. See s/freebsd.h for an example. */
8633 if (top
!= old_top
|| shown
!= old_shown
)
8635 if (NILP (bar
->dragging
))
8636 XawScrollbarSetThumb (widget
, top
, shown
);
8640 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8641 int scroll_mode
= 0;
8643 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8644 if (xaw3d_arrow_scroll
)
8646 /* Xaw3d stupidly ignores resize requests while dragging
8647 so we have to make it believe it's not in dragging mode. */
8648 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8649 if (scroll_mode
== 2)
8650 sb
->scrollbar
.scroll_mode
= 0;
8653 /* Try to make the scrolling a tad smoother. */
8654 if (!xaw3d_pick_top
)
8655 shown
= min (shown
, old_shown
);
8657 XawScrollbarSetThumb (widget
, top
, shown
);
8660 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8661 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8666 #endif /* !USE_MOTIF */
8671 #endif /* USE_TOOLKIT_SCROLL_BARS */
8675 /************************************************************************
8676 Scroll bars, general
8677 ************************************************************************/
8679 /* Create a scroll bar and return the scroll bar vector for it. W is
8680 the Emacs window on which to create the scroll bar. TOP, LEFT,
8681 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8684 static struct scroll_bar
*
8685 x_scroll_bar_create (w
, top
, left
, width
, height
)
8687 int top
, left
, width
, height
;
8689 struct frame
*f
= XFRAME (w
->frame
);
8690 struct scroll_bar
*bar
8691 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8695 #ifdef USE_TOOLKIT_SCROLL_BARS
8696 x_create_toolkit_scroll_bar (f
, bar
);
8697 #else /* not USE_TOOLKIT_SCROLL_BARS */
8699 XSetWindowAttributes a
;
8703 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8704 if (a
.background_pixel
== -1)
8705 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8707 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8708 | ButtonMotionMask
| PointerMotionHintMask
8710 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8712 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8714 /* Clear the area of W that will serve as a scroll bar. This is
8715 for the case that a window has been split horizontally. In
8716 this case, no clear_frame is generated to reduce flickering. */
8717 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8719 window_box_height (w
), False
);
8721 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8722 /* Position and size of scroll bar. */
8723 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8725 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8727 /* Border width, depth, class, and visual. */
8734 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8736 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8738 XSETWINDOW (bar
->window
, w
);
8739 XSETINT (bar
->top
, top
);
8740 XSETINT (bar
->left
, left
);
8741 XSETINT (bar
->width
, width
);
8742 XSETINT (bar
->height
, height
);
8743 XSETINT (bar
->start
, 0);
8744 XSETINT (bar
->end
, 0);
8745 bar
->dragging
= Qnil
;
8747 /* Add bar to its frame's list of scroll bars. */
8748 bar
->next
= FRAME_SCROLL_BARS (f
);
8750 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8751 if (!NILP (bar
->next
))
8752 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8754 /* Map the window/widget. */
8755 #ifdef USE_TOOLKIT_SCROLL_BARS
8757 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8758 XtConfigureWidget (scroll_bar
,
8759 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8761 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8762 max (height
, 1), 0);
8763 XtMapWidget (scroll_bar
);
8765 #else /* not USE_TOOLKIT_SCROLL_BARS */
8766 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8767 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8774 /* Draw BAR's handle in the proper position.
8776 If the handle is already drawn from START to END, don't bother
8777 redrawing it, unless REBUILD is non-zero; in that case, always
8778 redraw it. (REBUILD is handy for drawing the handle after expose
8781 Normally, we want to constrain the start and end of the handle to
8782 fit inside its rectangle, but if the user is dragging the scroll
8783 bar handle, we want to let them drag it down all the way, so that
8784 the bar's top is as far down as it goes; otherwise, there's no way
8785 to move to the very end of the buffer. */
8787 #ifndef USE_TOOLKIT_SCROLL_BARS
8790 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8791 struct scroll_bar
*bar
;
8795 int dragging
= ! NILP (bar
->dragging
);
8796 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8797 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8798 GC gc
= f
->output_data
.x
->normal_gc
;
8800 /* If the display is already accurate, do nothing. */
8802 && start
== XINT (bar
->start
)
8803 && end
== XINT (bar
->end
))
8809 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
8810 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8811 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8813 /* Make sure the values are reasonable, and try to preserve
8814 the distance between start and end. */
8816 int length
= end
- start
;
8820 else if (start
> top_range
)
8822 end
= start
+ length
;
8826 else if (end
> top_range
&& ! dragging
)
8830 /* Store the adjusted setting in the scroll bar. */
8831 XSETINT (bar
->start
, start
);
8832 XSETINT (bar
->end
, end
);
8834 /* Clip the end position, just for display. */
8835 if (end
> top_range
)
8838 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
8839 below top positions, to make sure the handle is always at least
8840 that many pixels tall. */
8841 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8843 /* Draw the empty space above the handle. Note that we can't clear
8844 zero-height areas; that means "clear to end of window." */
8846 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8847 /* x, y, width, height, and exposures. */
8848 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8849 VERTICAL_SCROLL_BAR_TOP_BORDER
,
8850 inside_width
, start
,
8853 /* Change to proper foreground color if one is specified. */
8854 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8855 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8856 f
->output_data
.x
->scroll_bar_foreground_pixel
);
8858 /* Draw the handle itself. */
8859 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8860 /* x, y, width, height */
8861 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8862 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
8863 inside_width
, end
- start
);
8865 /* Restore the foreground color of the GC if we changed it above. */
8866 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8867 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8868 f
->output_data
.x
->foreground_pixel
);
8870 /* Draw the empty space below the handle. Note that we can't
8871 clear zero-height areas; that means "clear to end of window." */
8872 if (end
< inside_height
)
8873 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8874 /* x, y, width, height, and exposures. */
8875 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8876 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
8877 inside_width
, inside_height
- end
,
8885 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8887 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8891 x_scroll_bar_remove (bar
)
8892 struct scroll_bar
*bar
;
8894 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8897 #ifdef USE_TOOLKIT_SCROLL_BARS
8898 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
8900 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8903 /* Disassociate this scroll bar from its window. */
8904 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8910 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8911 that we are displaying PORTION characters out of a total of WHOLE
8912 characters, starting at POSITION. If WINDOW has no scroll bar,
8916 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8918 int portion
, whole
, position
;
8920 struct frame
*f
= XFRAME (w
->frame
);
8921 struct scroll_bar
*bar
;
8922 int top
, height
, left
, sb_left
, width
, sb_width
;
8923 int window_x
, window_y
, window_width
, window_height
;
8925 /* Get window dimensions. */
8926 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8928 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8929 height
= window_height
;
8931 /* Compute the left edge of the scroll bar area. */
8932 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8933 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8935 left
= XFASTINT (w
->left
);
8936 left
*= CANON_X_UNIT (f
);
8937 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8939 /* Compute the width of the scroll bar which might be less than
8940 the width of the area reserved for the scroll bar. */
8941 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8942 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8946 /* Compute the left edge of the scroll bar. */
8947 #ifdef USE_TOOLKIT_SCROLL_BARS
8948 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8949 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8951 sb_left
= left
+ (width
- sb_width
) / 2;
8953 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8954 sb_left
= left
+ width
- sb_width
;
8959 /* Does the scroll bar exist yet? */
8960 if (NILP (w
->vertical_scroll_bar
))
8963 if (width
&& height
)
8964 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8965 left
, top
, width
, height
, False
);
8967 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8971 /* It may just need to be moved and resized. */
8972 unsigned int mask
= 0;
8974 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8978 if (sb_left
!= XINT (bar
->left
))
8980 if (top
!= XINT (bar
->top
))
8982 if (sb_width
!= XINT (bar
->width
))
8984 if (height
!= XINT (bar
->height
))
8987 #ifdef USE_TOOLKIT_SCROLL_BARS
8989 /* Since toolkit scroll bars are smaller than the space reserved
8990 for them on the frame, we have to clear "under" them. */
8991 if (width
&& height
)
8992 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8993 left
, top
, width
, height
, False
);
8995 /* Move/size the scroll bar widget. */
8997 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
8998 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9000 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9001 max (height
, 1), 0);
9003 #else /* not USE_TOOLKIT_SCROLL_BARS */
9005 /* Clear areas not covered by the scroll bar because of
9006 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
9007 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
9009 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9010 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9012 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9013 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9014 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9018 /* Clear areas not covered by the scroll bar because it's not as
9019 wide as the area reserved for it . This makes sure a
9020 previous mode line display is cleared after C-x 2 C-x 1, for
9023 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9024 int rest
= area_width
- sb_width
;
9026 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9027 left
+ area_width
- rest
, 0,
9028 rest
, max (height
, 1), False
);
9031 /* Move/size the scroll bar window. */
9036 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9038 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
9040 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
9044 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9046 /* Remember new settings. */
9047 XSETINT (bar
->left
, sb_left
);
9048 XSETINT (bar
->top
, top
);
9049 XSETINT (bar
->width
, sb_width
);
9050 XSETINT (bar
->height
, height
);
9055 #ifdef USE_TOOLKIT_SCROLL_BARS
9056 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
9057 #else /* not USE_TOOLKIT_SCROLL_BARS */
9058 /* Set the scroll bar's current state, unless we're currently being
9060 if (NILP (bar
->dragging
))
9062 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
9065 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
9068 int start
= ((double) position
* top_range
) / whole
;
9069 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
9070 x_scroll_bar_set_handle (bar
, start
, end
, 0);
9073 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9075 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
9079 /* The following three hooks are used when we're doing a thorough
9080 redisplay of the frame. We don't explicitly know which scroll bars
9081 are going to be deleted, because keeping track of when windows go
9082 away is a real pain - "Can you say set-window-configuration, boys
9083 and girls?" Instead, we just assert at the beginning of redisplay
9084 that *all* scroll bars are to be removed, and then save a scroll bar
9085 from the fiery pit when we actually redisplay its window. */
9087 /* Arrange for all scroll bars on FRAME to be removed at the next call
9088 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
9089 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
9092 XTcondemn_scroll_bars (frame
)
9095 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
9096 while (! NILP (FRAME_SCROLL_BARS (frame
)))
9099 bar
= FRAME_SCROLL_BARS (frame
);
9100 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
9101 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
9102 XSCROLL_BAR (bar
)->prev
= Qnil
;
9103 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
9104 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
9105 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
9110 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
9111 Note that WINDOW isn't necessarily condemned at all. */
9114 XTredeem_scroll_bar (window
)
9115 struct window
*window
;
9117 struct scroll_bar
*bar
;
9120 /* We can't redeem this window's scroll bar if it doesn't have one. */
9121 if (NILP (window
->vertical_scroll_bar
))
9124 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
9126 /* Unlink it from the condemned list. */
9127 f
= XFRAME (WINDOW_FRAME (window
));
9128 if (NILP (bar
->prev
))
9130 /* If the prev pointer is nil, it must be the first in one of
9132 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9133 /* It's not condemned. Everything's fine. */
9135 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9136 window
->vertical_scroll_bar
))
9137 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9139 /* If its prev pointer is nil, it must be at the front of
9140 one or the other! */
9144 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9146 if (! NILP (bar
->next
))
9147 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9149 bar
->next
= FRAME_SCROLL_BARS (f
);
9151 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9152 if (! NILP (bar
->next
))
9153 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9156 /* Remove all scroll bars on FRAME that haven't been saved since the
9157 last call to `*condemn_scroll_bars_hook'. */
9160 XTjudge_scroll_bars (f
)
9163 Lisp_Object bar
, next
;
9165 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9167 /* Clear out the condemned list now so we won't try to process any
9168 more events on the hapless scroll bars. */
9169 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9171 for (; ! NILP (bar
); bar
= next
)
9173 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9175 x_scroll_bar_remove (b
);
9178 b
->next
= b
->prev
= Qnil
;
9181 /* Now there should be no references to the condemned scroll bars,
9182 and they should get garbage-collected. */
9186 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9187 is a no-op when using toolkit scroll bars.
9189 This may be called from a signal handler, so we have to ignore GC
9193 x_scroll_bar_expose (bar
, event
)
9194 struct scroll_bar
*bar
;
9197 #ifndef USE_TOOLKIT_SCROLL_BARS
9199 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9200 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9201 GC gc
= f
->output_data
.x
->normal_gc
;
9202 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9206 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9208 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9209 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9211 /* x, y, width, height */
9213 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9214 XINT (bar
->height
) - 1);
9218 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9221 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9222 is set to something other than no_event, it is enqueued.
9224 This may be called from a signal handler, so we have to ignore GC
9227 #ifndef USE_TOOLKIT_SCROLL_BARS
9230 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9231 struct scroll_bar
*bar
;
9233 struct input_event
*emacs_event
;
9235 if (! GC_WINDOWP (bar
->window
))
9238 emacs_event
->kind
= scroll_bar_click
;
9239 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9240 emacs_event
->modifiers
9241 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9242 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9243 event
->xbutton
.state
)
9244 | (event
->type
== ButtonRelease
9247 emacs_event
->frame_or_window
= bar
->window
;
9248 emacs_event
->arg
= Qnil
;
9249 emacs_event
->timestamp
= event
->xbutton
.time
;
9252 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9254 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9257 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9258 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9261 if (y
> top_range
) y
= top_range
;
9263 if (y
< XINT (bar
->start
))
9264 emacs_event
->part
= scroll_bar_above_handle
;
9265 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9266 emacs_event
->part
= scroll_bar_handle
;
9268 emacs_event
->part
= scroll_bar_below_handle
;
9270 /* Just because the user has clicked on the handle doesn't mean
9271 they want to drag it. Lisp code needs to be able to decide
9272 whether or not we're dragging. */
9274 /* If the user has just clicked on the handle, record where they're
9276 if (event
->type
== ButtonPress
9277 && emacs_event
->part
== scroll_bar_handle
)
9278 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9281 /* If the user has released the handle, set it to its final position. */
9282 if (event
->type
== ButtonRelease
9283 && ! NILP (bar
->dragging
))
9285 int new_start
= y
- XINT (bar
->dragging
);
9286 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9288 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9289 bar
->dragging
= Qnil
;
9292 /* Same deal here as the other #if 0. */
9294 /* Clicks on the handle are always reported as occurring at the top of
9296 if (emacs_event
->part
== scroll_bar_handle
)
9297 emacs_event
->x
= bar
->start
;
9299 XSETINT (emacs_event
->x
, y
);
9301 XSETINT (emacs_event
->x
, y
);
9304 XSETINT (emacs_event
->y
, top_range
);
9308 /* Handle some mouse motion while someone is dragging the scroll bar.
9310 This may be called from a signal handler, so we have to ignore GC
9314 x_scroll_bar_note_movement (bar
, event
)
9315 struct scroll_bar
*bar
;
9318 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9320 last_mouse_movement_time
= event
->xmotion
.time
;
9323 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9325 /* If we're dragging the bar, display it. */
9326 if (! GC_NILP (bar
->dragging
))
9328 /* Where should the handle be now? */
9329 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9331 if (new_start
!= XINT (bar
->start
))
9333 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9335 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9340 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9342 /* Return information to the user about the current position of the mouse
9343 on the scroll bar. */
9346 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9348 Lisp_Object
*bar_window
;
9349 enum scroll_bar_part
*part
;
9351 unsigned long *time
;
9353 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9354 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9355 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9357 Window dummy_window
;
9359 unsigned int dummy_mask
;
9363 /* Get the mouse's position relative to the scroll bar window, and
9365 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9367 /* Root, child, root x and root y. */
9368 &dummy_window
, &dummy_window
,
9369 &dummy_coord
, &dummy_coord
,
9371 /* Position relative to scroll bar. */
9374 /* Mouse buttons and modifier keys. */
9381 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9384 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9386 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9388 if (! NILP (bar
->dragging
))
9389 win_y
-= XINT (bar
->dragging
);
9393 if (win_y
> top_range
)
9397 *bar_window
= bar
->window
;
9399 if (! NILP (bar
->dragging
))
9400 *part
= scroll_bar_handle
;
9401 else if (win_y
< XINT (bar
->start
))
9402 *part
= scroll_bar_above_handle
;
9403 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9404 *part
= scroll_bar_handle
;
9406 *part
= scroll_bar_below_handle
;
9408 XSETINT (*x
, win_y
);
9409 XSETINT (*y
, top_range
);
9412 last_mouse_scroll_bar
= Qnil
;
9415 *time
= last_mouse_movement_time
;
9421 /* The screen has been cleared so we may have changed foreground or
9422 background colors, and the scroll bars may need to be redrawn.
9423 Clear out the scroll bars, and ask for expose events, so we can
9427 x_scroll_bar_clear (f
)
9430 #ifndef USE_TOOLKIT_SCROLL_BARS
9433 /* We can have scroll bars even if this is 0,
9434 if we just turned off scroll bar mode.
9435 But in that case we should not clear them. */
9436 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9437 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9438 bar
= XSCROLL_BAR (bar
)->next
)
9439 XClearArea (FRAME_X_DISPLAY (f
),
9440 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9442 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9445 /* This processes Expose events from the menu-bar specific X event
9446 loop in xmenu.c. This allows to redisplay the frame if necessary
9447 when handling menu-bar or pop-up items. */
9450 process_expose_from_menu (event
)
9454 struct x_display_info
*dpyinfo
;
9455 int frame_exposed_p
= 0;
9459 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
9460 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9463 if (f
->async_visible
== 0)
9465 f
->async_visible
= 1;
9466 f
->async_iconified
= 0;
9467 f
->output_data
.x
->has_been_visible
= 1;
9468 SET_FRAME_GARBAGED (f
);
9472 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9473 event
.xexpose
.x
, event
.xexpose
.y
,
9474 event
.xexpose
.width
, event
.xexpose
.height
);
9475 frame_exposed_p
= 1;
9480 struct scroll_bar
*bar
9481 = x_window_to_scroll_bar (event
.xexpose
.window
);
9484 x_scroll_bar_expose (bar
, &event
);
9488 return frame_exposed_p
;
9491 /* Define a queue to save up SelectionRequest events for later handling. */
9493 struct selection_event_queue
9496 struct selection_event_queue
*next
;
9499 static struct selection_event_queue
*queue
;
9501 /* Nonzero means queue up certain events--don't process them yet. */
9503 static int x_queue_selection_requests
;
9505 /* Queue up an X event *EVENT, to be processed later. */
9508 x_queue_event (f
, event
)
9512 struct selection_event_queue
*queue_tmp
9513 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9515 if (queue_tmp
!= NULL
)
9517 queue_tmp
->event
= *event
;
9518 queue_tmp
->next
= queue
;
9523 /* Take all the queued events and put them back
9524 so that they get processed afresh. */
9527 x_unqueue_events (display
)
9530 while (queue
!= NULL
)
9532 struct selection_event_queue
*queue_tmp
= queue
;
9533 XPutBackEvent (display
, &queue_tmp
->event
);
9534 queue
= queue_tmp
->next
;
9535 xfree ((char *)queue_tmp
);
9539 /* Start queuing SelectionRequest events. */
9542 x_start_queuing_selection_requests (display
)
9545 x_queue_selection_requests
++;
9548 /* Stop queuing SelectionRequest events. */
9551 x_stop_queuing_selection_requests (display
)
9554 x_queue_selection_requests
--;
9555 x_unqueue_events (display
);
9558 /* The main X event-reading loop - XTread_socket. */
9560 /* Time stamp of enter window event. This is only used by XTread_socket,
9561 but we have to put it out here, since static variables within functions
9562 sometimes don't work. */
9564 static Time enter_timestamp
;
9566 /* This holds the state XLookupString needs to implement dead keys
9567 and other tricks known as "compose processing". _X Window System_
9568 says that a portable program can't use this, but Stephen Gildea assures
9569 me that letting the compiler initialize it to zeros will work okay.
9571 This must be defined outside of XTread_socket, for the same reasons
9572 given for enter_time stamp, above. */
9574 static XComposeStatus compose_status
;
9576 /* Record the last 100 characters stored
9577 to help debug the loss-of-chars-during-GC problem. */
9579 static int temp_index
;
9580 static short temp_buffer
[100];
9582 /* Set this to nonzero to fake an "X I/O error"
9583 on a particular display. */
9585 struct x_display_info
*XTread_socket_fake_io_error
;
9587 /* When we find no input here, we occasionally do a no-op command
9588 to verify that the X server is still running and we can still talk with it.
9589 We try all the open displays, one by one.
9590 This variable is used for cycling thru the displays. */
9592 static struct x_display_info
*next_noop_dpyinfo
;
9594 #define SET_SAVED_MENU_EVENT(size) \
9597 if (f->output_data.x->saved_menu_event == 0) \
9598 f->output_data.x->saved_menu_event \
9599 = (XEvent *) xmalloc (sizeof (XEvent)); \
9600 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9601 if (numchars >= 1) \
9603 bufp->kind = menu_bar_activate_event; \
9604 XSETFRAME (bufp->frame_or_window, f); \
9613 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9614 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9616 /* Read events coming from the X server.
9617 This routine is called by the SIGIO handler.
9618 We return as soon as there are no more events to be read.
9620 Events representing keys are stored in buffer BUFP,
9621 which can hold up to NUMCHARS characters.
9622 We return the number of characters stored into the buffer,
9623 thus pretending to be `read'.
9625 EXPECTED is nonzero if the caller knows input is available. */
9628 XTread_socket (sd
, bufp
, numchars
, expected
)
9630 /* register */ struct input_event
*bufp
;
9631 /* register */ int numchars
;
9638 int event_found
= 0;
9639 struct x_display_info
*dpyinfo
;
9640 struct coding_system coding
;
9642 if (interrupt_input_blocked
)
9644 interrupt_input_pending
= 1;
9648 interrupt_input_pending
= 0;
9651 /* So people can tell when we have read the available input. */
9652 input_signal_count
++;
9655 abort (); /* Don't think this happens. */
9659 /* The input should be decoded if it is from XIM. Currently the
9660 locale of XIM is the same as that of the system. So, we can use
9661 Vlocale_coding_system which is initialized properly at Emacs
9663 setup_coding_system (Vlocale_coding_system
, &coding
);
9664 coding
.src_multibyte
= 0;
9665 coding
.dst_multibyte
= 1;
9666 /* The input is converted to events, thus we can't handle
9667 composition. Anyway, there's no XIM that gives us composition
9669 coding
.composing
= COMPOSITION_DISABLED
;
9671 /* Find the display we are supposed to read input for.
9672 It's the one communicating on descriptor SD. */
9673 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9675 #if 0 /* This ought to be unnecessary; let's verify it. */
9677 /* If available, Xlib uses FIOSNBIO to make the socket
9678 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9679 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9680 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9681 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9682 #endif /* ! defined (FIOSNBIO) */
9685 #if 0 /* This code can't be made to work, with multiple displays,
9686 and appears not to be used on any system any more.
9687 Also keyboard.c doesn't turn O_NDELAY on and off
9688 for X connections. */
9691 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9693 extern int read_alarm_should_throw
;
9694 read_alarm_should_throw
= 1;
9695 XPeekEvent (dpyinfo
->display
, &event
);
9696 read_alarm_should_throw
= 0;
9698 #endif /* HAVE_SELECT */
9702 /* For debugging, this gives a way to fake an I/O error. */
9703 if (dpyinfo
== XTread_socket_fake_io_error
)
9705 XTread_socket_fake_io_error
= 0;
9706 x_io_error_quitter (dpyinfo
->display
);
9709 while (XPending (dpyinfo
->display
))
9711 XNextEvent (dpyinfo
->display
, &event
);
9715 /* Filter events for the current X input method.
9716 XFilterEvent returns non-zero if the input method has
9717 consumed the event. We pass the frame's X window to
9718 XFilterEvent because that's the one for which the IC
9720 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9721 event
.xclient
.window
);
9722 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9732 if (event
.xclient
.message_type
9733 == dpyinfo
->Xatom_wm_protocols
9734 && event
.xclient
.format
== 32)
9736 if (event
.xclient
.data
.l
[0]
9737 == dpyinfo
->Xatom_wm_take_focus
)
9739 /* Use x_any_window_to_frame because this
9740 could be the shell widget window
9741 if the frame has no title bar. */
9742 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9744 /* Not quite sure this is needed -pd */
9745 if (f
&& FRAME_XIC (f
))
9746 XSetICFocus (FRAME_XIC (f
));
9748 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
9749 instructs the WM to set the input focus automatically for
9750 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
9751 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
9752 it has set the focus. So, XSetInputFocus below is not
9755 The call to XSetInputFocus below has also caused trouble. In
9756 cases where the XSetInputFocus done by the WM and the one
9757 below are temporally close (on a fast machine), the call
9758 below can generate additional FocusIn events which confuse
9761 /* Since we set WM_TAKE_FOCUS, we must call
9762 XSetInputFocus explicitly. But not if f is null,
9763 since that might be an event for a deleted frame. */
9766 Display
*d
= event
.xclient
.display
;
9767 /* Catch and ignore errors, in case window has been
9768 iconified by a window manager such as GWM. */
9769 int count
= x_catch_errors (d
);
9770 XSetInputFocus (d
, event
.xclient
.window
,
9771 /* The ICCCM says this is
9772 the only valid choice. */
9774 event
.xclient
.data
.l
[1]);
9775 /* This is needed to detect the error
9776 if there is an error. */
9778 x_uncatch_errors (d
, count
);
9780 /* Not certain about handling scroll bars here */
9783 else if (event
.xclient
.data
.l
[0]
9784 == dpyinfo
->Xatom_wm_save_yourself
)
9786 /* Save state modify the WM_COMMAND property to
9787 something which can reinstate us. This notifies
9788 the session manager, who's looking for such a
9789 PropertyNotify. Can restart processing when
9790 a keyboard or mouse event arrives. */
9793 f
= x_top_window_to_frame (dpyinfo
,
9794 event
.xclient
.window
);
9796 /* This is just so we only give real data once
9797 for a single Emacs process. */
9798 if (f
== SELECTED_FRAME ())
9799 XSetCommand (FRAME_X_DISPLAY (f
),
9800 event
.xclient
.window
,
9801 initial_argv
, initial_argc
);
9803 XSetCommand (FRAME_X_DISPLAY (f
),
9804 event
.xclient
.window
,
9808 else if (event
.xclient
.data
.l
[0]
9809 == dpyinfo
->Xatom_wm_delete_window
)
9812 = x_any_window_to_frame (dpyinfo
,
9813 event
.xclient
.window
);
9820 bufp
->kind
= delete_window_event
;
9821 XSETFRAME (bufp
->frame_or_window
, f
);
9830 else if (event
.xclient
.message_type
9831 == dpyinfo
->Xatom_wm_configure_denied
)
9834 else if (event
.xclient
.message_type
9835 == dpyinfo
->Xatom_wm_window_moved
)
9839 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9841 new_x
= event
.xclient
.data
.s
[0];
9842 new_y
= event
.xclient
.data
.s
[1];
9846 f
->output_data
.x
->left_pos
= new_x
;
9847 f
->output_data
.x
->top_pos
= new_y
;
9851 else if (event
.xclient
.message_type
9852 == dpyinfo
->Xatom_editres
)
9855 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9856 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
9859 #endif /* HACK_EDITRES */
9860 else if ((event
.xclient
.message_type
9861 == dpyinfo
->Xatom_DONE
)
9862 || (event
.xclient
.message_type
9863 == dpyinfo
->Xatom_PAGE
))
9865 /* Ghostview job completed. Kill it. We could
9866 reply with "Next" if we received "Page", but we
9867 currently never do because we are interested in
9868 images, only, which should have 1 page. */
9869 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
9871 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9872 x_kill_gs_process (pixmap
, f
);
9873 expose_frame (f
, 0, 0, 0, 0);
9875 #ifdef USE_TOOLKIT_SCROLL_BARS
9876 /* Scroll bar callbacks send a ClientMessage from which
9877 we construct an input_event. */
9878 else if (event
.xclient
.message_type
9879 == dpyinfo
->Xatom_Scrollbar
)
9881 x_scroll_bar_to_input_event (&event
, bufp
);
9882 ++bufp
, ++count
, --numchars
;
9885 #endif /* USE_TOOLKIT_SCROLL_BARS */
9891 case SelectionNotify
:
9892 #ifdef USE_X_TOOLKIT
9893 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
9895 #endif /* not USE_X_TOOLKIT */
9896 x_handle_selection_notify (&event
.xselection
);
9899 case SelectionClear
: /* Someone has grabbed ownership. */
9900 #ifdef USE_X_TOOLKIT
9901 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
9903 #endif /* USE_X_TOOLKIT */
9905 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
9910 bufp
->kind
= selection_clear_event
;
9911 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9912 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9913 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9914 bufp
->frame_or_window
= Qnil
;
9923 case SelectionRequest
: /* Someone wants our selection. */
9924 #ifdef USE_X_TOOLKIT
9925 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
9927 #endif /* USE_X_TOOLKIT */
9928 if (x_queue_selection_requests
)
9929 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
9933 XSelectionRequestEvent
*eventp
= (XSelectionRequestEvent
*) &event
;
9938 bufp
->kind
= selection_request_event
;
9939 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9940 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
9941 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9942 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
9943 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
9944 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9945 bufp
->frame_or_window
= Qnil
;
9954 case PropertyNotify
:
9955 #ifdef USE_X_TOOLKIT
9956 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
9958 #endif /* not USE_X_TOOLKIT */
9959 x_handle_property_notify (&event
.xproperty
);
9962 case ReparentNotify
:
9963 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
9967 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
9968 x_real_positions (f
, &x
, &y
);
9969 f
->output_data
.x
->left_pos
= x
;
9970 f
->output_data
.x
->top_pos
= y
;
9975 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9978 if (f
->async_visible
== 0)
9980 f
->async_visible
= 1;
9981 f
->async_iconified
= 0;
9982 f
->output_data
.x
->has_been_visible
= 1;
9983 SET_FRAME_GARBAGED (f
);
9986 expose_frame (x_window_to_frame (dpyinfo
,
9987 event
.xexpose
.window
),
9988 event
.xexpose
.x
, event
.xexpose
.y
,
9989 event
.xexpose
.width
, event
.xexpose
.height
);
9993 #ifdef USE_TOOLKIT_SCROLL_BARS
9994 /* Dispatch event to the widget. */
9996 #else /* not USE_TOOLKIT_SCROLL_BARS */
9997 struct scroll_bar
*bar
9998 = x_window_to_scroll_bar (event
.xexpose
.window
);
10001 x_scroll_bar_expose (bar
, &event
);
10002 #ifdef USE_X_TOOLKIT
10005 #endif /* USE_X_TOOLKIT */
10006 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10010 case GraphicsExpose
: /* This occurs when an XCopyArea's
10011 source area was obscured or not
10013 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
10017 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
10018 event
.xgraphicsexpose
.width
,
10019 event
.xgraphicsexpose
.height
);
10021 #ifdef USE_X_TOOLKIT
10024 #endif /* USE_X_TOOLKIT */
10027 case NoExpose
: /* This occurs when an XCopyArea's
10028 source area was completely
10033 /* Redo the mouse-highlight after the tooltip has gone. */
10034 if (event
.xmap
.window
== tip_window
)
10037 redo_mouse_highlight ();
10040 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
10041 if (f
) /* F may no longer exist if
10042 the frame was deleted. */
10044 /* While a frame is unmapped, display generation is
10045 disabled; you don't want to spend time updating a
10046 display that won't ever be seen. */
10047 f
->async_visible
= 0;
10048 /* We can't distinguish, from the event, whether the window
10049 has become iconified or invisible. So assume, if it
10050 was previously visible, than now it is iconified.
10051 But x_make_frame_invisible clears both
10052 the visible flag and the iconified flag;
10053 and that way, we know the window is not iconified now. */
10054 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
10056 f
->async_iconified
= 1;
10058 bufp
->kind
= iconify_event
;
10059 XSETFRAME (bufp
->frame_or_window
, f
);
10069 if (event
.xmap
.window
== tip_window
)
10070 /* The tooltip has been drawn already. Avoid
10071 the SET_FRAME_GARBAGED below. */
10074 /* We use x_top_window_to_frame because map events can
10075 come for sub-windows and they don't mean that the
10076 frame is visible. */
10077 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
10080 f
->async_visible
= 1;
10081 f
->async_iconified
= 0;
10082 f
->output_data
.x
->has_been_visible
= 1;
10084 /* wait_reading_process_input will notice this and update
10085 the frame's display structures. */
10086 SET_FRAME_GARBAGED (f
);
10090 bufp
->kind
= deiconify_event
;
10091 XSETFRAME (bufp
->frame_or_window
, f
);
10097 else if (! NILP (Vframe_list
)
10098 && ! NILP (XCDR (Vframe_list
)))
10099 /* Force a redisplay sooner or later
10100 to update the frame titles
10101 in case this is the second frame. */
10102 record_asynch_buffer_change ();
10107 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
10109 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10112 /* Scroll bars consume key events, but we want
10113 the keys to go to the scroll bar's frame. */
10114 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
10115 event
.xkey
.window
);
10116 if (widget
&& XmIsScrollBar (widget
))
10118 widget
= XtParent (widget
);
10119 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
10122 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10126 KeySym keysym
, orig_keysym
;
10127 /* al%imercury@uunet.uu.net says that making this 81
10128 instead of 80 fixed a bug whereby meta chars made
10131 It seems that some version of XmbLookupString has
10132 a bug of not returning XBufferOverflow in
10133 status_return even if the input is too long to
10134 fit in 81 bytes. So, we must prepare sufficient
10135 bytes for copy_buffer. 513 bytes (256 chars for
10136 two-byte character set) seems to be a faily good
10137 approximation. -- 2000.8.10 handa@etl.go.jp */
10138 unsigned char copy_buffer
[513];
10139 unsigned char *copy_bufptr
= copy_buffer
;
10140 int copy_bufsiz
= sizeof (copy_buffer
);
10144 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10145 extra_keyboard_modifiers
);
10146 modifiers
= event
.xkey
.state
;
10148 /* This will have to go some day... */
10150 /* make_lispy_event turns chars into control chars.
10151 Don't do it here because XLookupString is too eager. */
10152 event
.xkey
.state
&= ~ControlMask
;
10153 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10154 | dpyinfo
->super_mod_mask
10155 | dpyinfo
->hyper_mod_mask
10156 | dpyinfo
->alt_mod_mask
);
10158 /* In case Meta is ComposeCharacter,
10159 clear its status. According to Markus Ehrnsperger
10160 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10161 this enables ComposeCharacter to work whether or
10162 not it is combined with Meta. */
10163 if (modifiers
& dpyinfo
->meta_mod_mask
)
10164 bzero (&compose_status
, sizeof (compose_status
));
10169 Status status_return
;
10171 nbytes
= XmbLookupString (FRAME_XIC (f
),
10172 &event
.xkey
, copy_bufptr
,
10173 copy_bufsiz
, &keysym
,
10175 if (status_return
== XBufferOverflow
)
10177 copy_bufsiz
= nbytes
+ 1;
10178 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10179 nbytes
= XmbLookupString (FRAME_XIC (f
),
10180 &event
.xkey
, copy_bufptr
,
10181 copy_bufsiz
, &keysym
,
10185 if (status_return
== XLookupNone
)
10187 else if (status_return
== XLookupChars
)
10192 else if (status_return
!= XLookupKeySym
10193 && status_return
!= XLookupBoth
)
10197 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10198 copy_bufsiz
, &keysym
,
10201 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10202 copy_bufsiz
, &keysym
,
10206 orig_keysym
= keysym
;
10210 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10211 || keysym
== XK_Delete
10212 #ifdef XK_ISO_Left_Tab
10213 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
10215 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
10216 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10217 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10219 /* This recognizes the "extended function keys".
10220 It seems there's no cleaner way.
10221 Test IsModifierKey to avoid handling mode_switch
10223 || ((unsigned) (keysym
) >= XK_Select
10224 && (unsigned)(keysym
) < XK_KP_Space
)
10226 #ifdef XK_dead_circumflex
10227 || orig_keysym
== XK_dead_circumflex
10229 #ifdef XK_dead_grave
10230 || orig_keysym
== XK_dead_grave
10232 #ifdef XK_dead_tilde
10233 || orig_keysym
== XK_dead_tilde
10235 #ifdef XK_dead_diaeresis
10236 || orig_keysym
== XK_dead_diaeresis
10238 #ifdef XK_dead_macron
10239 || orig_keysym
== XK_dead_macron
10241 #ifdef XK_dead_degree
10242 || orig_keysym
== XK_dead_degree
10244 #ifdef XK_dead_acute
10245 || orig_keysym
== XK_dead_acute
10247 #ifdef XK_dead_cedilla
10248 || orig_keysym
== XK_dead_cedilla
10250 #ifdef XK_dead_breve
10251 || orig_keysym
== XK_dead_breve
10253 #ifdef XK_dead_ogonek
10254 || orig_keysym
== XK_dead_ogonek
10256 #ifdef XK_dead_caron
10257 || orig_keysym
== XK_dead_caron
10259 #ifdef XK_dead_doubleacute
10260 || orig_keysym
== XK_dead_doubleacute
10262 #ifdef XK_dead_abovedot
10263 || orig_keysym
== XK_dead_abovedot
10265 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10266 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10267 /* Any "vendor-specific" key is ok. */
10268 || (orig_keysym
& (1 << 28)))
10269 && ! (IsModifierKey (orig_keysym
)
10271 #ifdef XK_Mode_switch
10272 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10275 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10277 #endif /* not HAVE_X11R5 */
10280 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10282 temp_buffer
[temp_index
++] = keysym
;
10283 bufp
->kind
= non_ascii_keystroke
;
10284 bufp
->code
= keysym
;
10285 XSETFRAME (bufp
->frame_or_window
, f
);
10288 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10290 bufp
->timestamp
= event
.xkey
.time
;
10295 else if (numchars
> nbytes
)
10301 for (i
= 0; i
< nbytes
; i
++)
10303 if (temp_index
== (sizeof temp_buffer
10306 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10309 if (/* If the event is not from XIM, */
10310 event
.xkey
.keycode
!= 0
10311 /* or the current locale doesn't request
10312 decoding of the intup data, ... */
10313 || coding
.type
== coding_type_raw_text
10314 || coding
.type
== coding_type_no_conversion
)
10316 /* ... we can use the input data as is. */
10321 /* We have to decode the input data. */
10325 require
= decoding_buffer_size (&coding
, nbytes
);
10326 p
= (unsigned char *) alloca (require
);
10327 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10328 decode_coding (&coding
, copy_bufptr
, p
,
10330 nbytes
= coding
.produced
;
10331 nchars
= coding
.produced_char
;
10335 /* Convert the input data to a sequence of
10336 character events. */
10337 for (i
= 0; i
< nbytes
; i
+= len
)
10339 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10341 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10343 : multibyte_char_keystroke
);
10345 XSETFRAME (bufp
->frame_or_window
, f
);
10348 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10350 bufp
->timestamp
= event
.xkey
.time
;
10355 numchars
-= nchars
;
10357 if (keysym
== NoSymbol
)
10367 /* Don't dispatch this event since XtDispatchEvent calls
10368 XFilterEvent, and two calls in a row may freeze the
10377 /* Don't dispatch this event since XtDispatchEvent calls
10378 XFilterEvent, and two calls in a row may freeze the
10385 /* Here's a possible interpretation of the whole
10386 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10387 you get a FocusIn event, you have to get a FocusOut
10388 event before you relinquish the focus. If you
10389 haven't received a FocusIn event, then a mere
10390 LeaveNotify is enough to free you. */
10394 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10396 if (event
.xcrossing
.focus
)
10398 /* Avoid nasty pop/raise loops. */
10399 if (f
&& (!(f
->auto_raise
)
10400 || !(f
->auto_lower
)
10401 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10403 x_new_focus_frame (dpyinfo
, f
);
10404 enter_timestamp
= event
.xcrossing
.time
;
10407 else if (f
== dpyinfo
->x_focus_frame
)
10408 x_new_focus_frame (dpyinfo
, 0);
10410 /* EnterNotify counts as mouse movement,
10411 so update things that depend on mouse position. */
10412 if (f
&& !f
->output_data
.x
->hourglass_p
)
10413 note_mouse_movement (f
, &event
.xmotion
);
10418 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10419 if (event
.xfocus
.detail
!= NotifyPointer
)
10420 dpyinfo
->x_focus_event_frame
= f
;
10423 x_new_focus_frame (dpyinfo
, f
);
10425 /* Don't stop displaying the initial startup message
10426 for a switch-frame event we don't need. */
10427 if (GC_NILP (Vterminal_frame
)
10428 && GC_CONSP (Vframe_list
)
10429 && !GC_NILP (XCDR (Vframe_list
)))
10431 bufp
->kind
= FOCUS_IN_EVENT
;
10432 XSETFRAME (bufp
->frame_or_window
, f
);
10434 ++bufp
, ++count
, --numchars
;
10439 if (f
&& FRAME_XIC (f
))
10440 XSetICFocus (FRAME_XIC (f
));
10446 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10449 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10451 /* If we move outside the frame, then we're
10452 certainly no longer on any text in the frame. */
10453 clear_mouse_face (dpyinfo
);
10454 dpyinfo
->mouse_face_mouse_frame
= 0;
10457 /* Generate a nil HELP_EVENT to cancel a help-echo.
10458 Do it only if there's something to cancel.
10459 Otherwise, the startup message is cleared when
10460 the mouse leaves the frame. */
10461 if (any_help_event_p
)
10466 XSETFRAME (frame
, f
);
10468 n
= gen_help_event (bufp
, numchars
,
10469 Qnil
, frame
, Qnil
, Qnil
, 0);
10470 bufp
+= n
, count
+= n
, numchars
-= n
;
10473 if (event
.xcrossing
.focus
)
10474 x_mouse_leave (dpyinfo
);
10477 if (f
== dpyinfo
->x_focus_event_frame
)
10478 dpyinfo
->x_focus_event_frame
= 0;
10479 if (f
== dpyinfo
->x_focus_frame
)
10480 x_new_focus_frame (dpyinfo
, 0);
10486 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10487 if (event
.xfocus
.detail
!= NotifyPointer
10488 && f
== dpyinfo
->x_focus_event_frame
)
10489 dpyinfo
->x_focus_event_frame
= 0;
10490 if (f
&& f
== dpyinfo
->x_focus_frame
)
10491 x_new_focus_frame (dpyinfo
, 0);
10494 if (f
&& FRAME_XIC (f
))
10495 XUnsetICFocus (FRAME_XIC (f
));
10502 previous_help_echo
= help_echo
;
10503 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10504 help_echo_pos
= -1;
10506 if (dpyinfo
->grabbed
&& last_mouse_frame
10507 && FRAME_LIVE_P (last_mouse_frame
))
10508 f
= last_mouse_frame
;
10510 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10513 note_mouse_movement (f
, &event
.xmotion
);
10516 #ifndef USE_TOOLKIT_SCROLL_BARS
10517 struct scroll_bar
*bar
10518 = x_window_to_scroll_bar (event
.xmotion
.window
);
10521 x_scroll_bar_note_movement (bar
, &event
);
10522 #endif /* USE_TOOLKIT_SCROLL_BARS */
10524 /* If we move outside the frame, then we're
10525 certainly no longer on any text in the frame. */
10526 clear_mouse_face (dpyinfo
);
10529 /* If the contents of the global variable help_echo
10530 has changed, generate a HELP_EVENT. */
10531 if (!NILP (help_echo
)
10532 || !NILP (previous_help_echo
))
10538 XSETFRAME (frame
, f
);
10542 any_help_event_p
= 1;
10543 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10544 help_echo_window
, help_echo_object
,
10546 bufp
+= n
, count
+= n
, numchars
-= n
;
10552 case ConfigureNotify
:
10553 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10556 #ifndef USE_X_TOOLKIT
10557 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10558 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10560 /* In the toolkit version, change_frame_size
10561 is called by the code that handles resizing
10562 of the EmacsFrame widget. */
10564 /* Even if the number of character rows and columns has
10565 not changed, the font size may have changed, so we need
10566 to check the pixel dimensions as well. */
10567 if (columns
!= f
->width
10568 || rows
!= f
->height
10569 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10570 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10572 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10573 SET_FRAME_GARBAGED (f
);
10574 cancel_mouse_face (f
);
10578 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10579 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10581 /* What we have now is the position of Emacs's own window.
10582 Convert that to the position of the window manager window. */
10583 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10584 &f
->output_data
.x
->top_pos
);
10587 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10588 xic_set_statusarea (f
);
10591 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10593 /* Since the WM decorations come below top_pos now,
10594 we must put them below top_pos in the future. */
10595 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10596 x_wm_set_size_hint (f
, (long) 0, 0);
10599 /* Some window managers pass (0,0) as the location of
10600 the window, and the Motif event handler stores it
10601 in the emacs widget, which messes up Motif menus. */
10602 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10604 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10605 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10607 #endif /* USE_MOTIF */
10612 case ButtonRelease
:
10614 /* If we decide we want to generate an event to be seen
10615 by the rest of Emacs, we put it here. */
10616 struct input_event emacs_event
;
10617 int tool_bar_p
= 0;
10619 emacs_event
.kind
= no_event
;
10620 bzero (&compose_status
, sizeof (compose_status
));
10622 if (dpyinfo
->grabbed
10623 && last_mouse_frame
10624 && FRAME_LIVE_P (last_mouse_frame
))
10625 f
= last_mouse_frame
;
10627 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10631 /* Is this in the tool-bar? */
10632 if (WINDOWP (f
->tool_bar_window
)
10633 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10635 Lisp_Object window
;
10638 x
= event
.xbutton
.x
;
10639 y
= event
.xbutton
.y
;
10642 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10643 if (EQ (window
, f
->tool_bar_window
))
10645 x_handle_tool_bar_click (f
, &event
.xbutton
);
10651 if (!dpyinfo
->x_focus_frame
10652 || f
== dpyinfo
->x_focus_frame
)
10653 construct_mouse_click (&emacs_event
, &event
, f
);
10657 #ifndef USE_TOOLKIT_SCROLL_BARS
10658 struct scroll_bar
*bar
10659 = x_window_to_scroll_bar (event
.xbutton
.window
);
10662 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10663 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10666 if (event
.type
== ButtonPress
)
10668 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10669 last_mouse_frame
= f
;
10670 /* Ignore any mouse motion that happened
10671 before this event; any subsequent mouse-movement
10672 Emacs events should reflect only motion after
10673 the ButtonPress. */
10675 f
->mouse_moved
= 0;
10678 last_tool_bar_item
= -1;
10682 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10685 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10687 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10693 #ifdef USE_X_TOOLKIT
10694 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10695 /* For a down-event in the menu bar,
10696 don't pass it to Xt right now.
10697 Instead, save it away
10698 and we will pass it to Xt from kbd_buffer_get_event.
10699 That way, we can run some Lisp code first. */
10700 if (f
&& event
.type
== ButtonPress
10701 /* Verify the event is really within the menu bar
10702 and not just sent to it due to grabbing. */
10703 && event
.xbutton
.x
>= 0
10704 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10705 && event
.xbutton
.y
>= 0
10706 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10707 && event
.xbutton
.same_screen
)
10709 SET_SAVED_BUTTON_EVENT
;
10710 XSETFRAME (last_mouse_press_frame
, f
);
10712 else if (event
.type
== ButtonPress
)
10714 last_mouse_press_frame
= Qnil
;
10718 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10719 but I am trying to be cautious. */
10720 else if (event
.type
== ButtonRelease
)
10722 if (!NILP (last_mouse_press_frame
))
10724 f
= XFRAME (last_mouse_press_frame
);
10725 if (f
->output_data
.x
)
10726 SET_SAVED_BUTTON_EVENT
;
10731 #endif /* USE_MOTIF */
10734 #endif /* USE_X_TOOLKIT */
10738 case CirculateNotify
:
10741 case CirculateRequest
:
10744 case VisibilityNotify
:
10747 case MappingNotify
:
10748 /* Someone has changed the keyboard mapping - update the
10750 switch (event
.xmapping
.request
)
10752 case MappingModifier
:
10753 x_find_modifier_meanings (dpyinfo
);
10754 /* This is meant to fall through. */
10755 case MappingKeyboard
:
10756 XRefreshKeyboardMapping (&event
.xmapping
);
10762 #ifdef USE_X_TOOLKIT
10764 XtDispatchEvent (&event
);
10766 #endif /* USE_X_TOOLKIT */
10774 /* On some systems, an X bug causes Emacs to get no more events
10775 when the window is destroyed. Detect that. (1994.) */
10778 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
10779 One XNOOP in 100 loops will make Emacs terminate.
10780 B. Bretthauer, 1994 */
10782 if (x_noop_count
>= 100)
10786 if (next_noop_dpyinfo
== 0)
10787 next_noop_dpyinfo
= x_display_list
;
10789 XNoOp (next_noop_dpyinfo
->display
);
10791 /* Each time we get here, cycle through the displays now open. */
10792 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
10796 /* If the focus was just given to an auto-raising frame,
10798 /* ??? This ought to be able to handle more than one such frame. */
10799 if (pending_autoraise_frame
)
10801 x_raise_frame (pending_autoraise_frame
);
10802 pending_autoraise_frame
= 0;
10813 /***********************************************************************
10815 ***********************************************************************/
10817 /* Note if the text cursor of window W has been overwritten by a
10818 drawing operation that outputs N glyphs starting at HPOS in the
10819 line given by output_cursor.vpos. N < 0 means all the rest of the
10820 line after HPOS has been written. */
10823 note_overwritten_text_cursor (w
, hpos
, n
)
10827 if (updated_area
== TEXT_AREA
10828 && output_cursor
.vpos
== w
->phys_cursor
.vpos
10829 && hpos
<= w
->phys_cursor
.hpos
10831 || hpos
+ n
> w
->phys_cursor
.hpos
))
10832 w
->phys_cursor_on_p
= 0;
10836 /* Set clipping for output in glyph row ROW. W is the window in which
10837 we operate. GC is the graphics context to set clipping in.
10838 WHOLE_LINE_P non-zero means include the areas used for truncation
10839 mark display and alike in the clipping rectangle.
10841 ROW may be a text row or, e.g., a mode line. Text rows must be
10842 clipped to the interior of the window dedicated to text display,
10843 mode lines must be clipped to the whole window. */
10846 x_clip_to_row (w
, row
, gc
, whole_line_p
)
10848 struct glyph_row
*row
;
10852 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10853 XRectangle clip_rect
;
10854 int window_x
, window_y
, window_width
, window_height
;
10856 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
10858 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
10859 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
10860 clip_rect
.y
= max (clip_rect
.y
, window_y
);
10861 clip_rect
.width
= window_width
;
10862 clip_rect
.height
= row
->visible_height
;
10864 /* If clipping to the whole line, including trunc marks, extend
10865 the rectangle to the left and increase its width. */
10868 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
10869 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
10872 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
10876 /* Draw a hollow box cursor on window W in glyph row ROW. */
10879 x_draw_hollow_cursor (w
, row
)
10881 struct glyph_row
*row
;
10883 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10884 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10885 Display
*dpy
= FRAME_X_DISPLAY (f
);
10888 struct glyph
*cursor_glyph
;
10891 /* Compute frame-relative coordinates from window-relative
10893 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10894 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
10895 + row
->ascent
- w
->phys_cursor_ascent
);
10896 h
= row
->height
- 1;
10898 /* Get the glyph the cursor is on. If we can't tell because
10899 the current matrix is invalid or such, give up. */
10900 cursor_glyph
= get_phys_cursor_glyph (w
);
10901 if (cursor_glyph
== NULL
)
10904 /* Compute the width of the rectangle to draw. If on a stretch
10905 glyph, and `x-stretch-block-cursor' is nil, don't draw a
10906 rectangle as wide as the glyph, but use a canonical character
10908 wd
= cursor_glyph
->pixel_width
- 1;
10909 if (cursor_glyph
->type
== STRETCH_GLYPH
10910 && !x_stretch_cursor_p
)
10911 wd
= min (CANON_X_UNIT (f
), wd
);
10913 /* The foreground of cursor_gc is typically the same as the normal
10914 background color, which can cause the cursor box to be invisible. */
10915 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10916 if (dpyinfo
->scratch_cursor_gc
)
10917 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
10919 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
10920 GCForeground
, &xgcv
);
10921 gc
= dpyinfo
->scratch_cursor_gc
;
10923 /* Set clipping, draw the rectangle, and reset clipping again. */
10924 x_clip_to_row (w
, row
, gc
, 0);
10925 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
10926 XSetClipMask (dpy
, gc
, None
);
10930 /* Draw a bar cursor on window W in glyph row ROW.
10932 Implementation note: One would like to draw a bar cursor with an
10933 angle equal to the one given by the font property XA_ITALIC_ANGLE.
10934 Unfortunately, I didn't find a font yet that has this property set.
10938 x_draw_bar_cursor (w
, row
, width
)
10940 struct glyph_row
*row
;
10943 struct frame
*f
= XFRAME (w
->frame
);
10944 struct glyph
*cursor_glyph
;
10947 unsigned long mask
;
10952 /* If cursor is out of bounds, don't draw garbage. This can happen
10953 in mini-buffer windows when switching between echo area glyphs
10954 and mini-buffer. */
10955 cursor_glyph
= get_phys_cursor_glyph (w
);
10956 if (cursor_glyph
== NULL
)
10959 /* If on an image, draw like a normal cursor. That's usually better
10960 visible than drawing a bar, esp. if the image is large so that
10961 the bar might not be in the window. */
10962 if (cursor_glyph
->type
== IMAGE_GLYPH
)
10964 struct glyph_row
*row
;
10965 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
10966 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
10970 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
10971 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10972 xgcv
.graphics_exposures
= 0;
10973 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
10974 dpy
= FRAME_X_DISPLAY (f
);
10975 window
= FRAME_X_WINDOW (f
);
10976 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
10979 XChangeGC (dpy
, gc
, mask
, &xgcv
);
10982 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
10983 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
10987 width
= f
->output_data
.x
->cursor_width
;
10989 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10990 x_clip_to_row (w
, row
, gc
, 0);
10991 XFillRectangle (dpy
, window
, gc
,
10993 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
10994 min (cursor_glyph
->pixel_width
, width
),
10996 XSetClipMask (dpy
, gc
, None
);
11001 /* Clear the cursor of window W to background color, and mark the
11002 cursor as not shown. This is used when the text where the cursor
11003 is is about to be rewritten. */
11009 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11010 x_update_window_cursor (w
, 0);
11014 /* Draw the cursor glyph of window W in glyph row ROW. See the
11015 comment of x_draw_glyphs for the meaning of HL. */
11018 x_draw_phys_cursor_glyph (w
, row
, hl
)
11020 struct glyph_row
*row
;
11021 enum draw_glyphs_face hl
;
11023 /* If cursor hpos is out of bounds, don't draw garbage. This can
11024 happen in mini-buffer windows when switching between echo area
11025 glyphs and mini-buffer. */
11026 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11028 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11029 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11032 /* When we erase the cursor, and ROW is overlapped by other
11033 rows, make sure that these overlapping parts of other rows
11035 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11037 if (row
> w
->current_matrix
->rows
11038 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11039 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11041 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11042 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11043 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11049 /* Erase the image of a cursor of window W from the screen. */
11052 x_erase_phys_cursor (w
)
11055 struct frame
*f
= XFRAME (w
->frame
);
11056 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11057 int hpos
= w
->phys_cursor
.hpos
;
11058 int vpos
= w
->phys_cursor
.vpos
;
11059 int mouse_face_here_p
= 0;
11060 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11061 struct glyph_row
*cursor_row
;
11062 struct glyph
*cursor_glyph
;
11063 enum draw_glyphs_face hl
;
11065 /* No cursor displayed or row invalidated => nothing to do on the
11067 if (w
->phys_cursor_type
== NO_CURSOR
)
11068 goto mark_cursor_off
;
11070 /* VPOS >= active_glyphs->nrows means that window has been resized.
11071 Don't bother to erase the cursor. */
11072 if (vpos
>= active_glyphs
->nrows
)
11073 goto mark_cursor_off
;
11075 /* If row containing cursor is marked invalid, there is nothing we
11077 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11078 if (!cursor_row
->enabled_p
)
11079 goto mark_cursor_off
;
11081 /* This can happen when the new row is shorter than the old one.
11082 In this case, either x_draw_glyphs or clear_end_of_line
11083 should have cleared the cursor. Note that we wouldn't be
11084 able to erase the cursor in this case because we don't have a
11085 cursor glyph at hand. */
11086 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11087 goto mark_cursor_off
;
11089 /* If the cursor is in the mouse face area, redisplay that when
11090 we clear the cursor. */
11091 if (! NILP (dpyinfo
->mouse_face_window
)
11092 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11093 && (vpos
> dpyinfo
->mouse_face_beg_row
11094 || (vpos
== dpyinfo
->mouse_face_beg_row
11095 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11096 && (vpos
< dpyinfo
->mouse_face_end_row
11097 || (vpos
== dpyinfo
->mouse_face_end_row
11098 && hpos
< dpyinfo
->mouse_face_end_col
))
11099 /* Don't redraw the cursor's spot in mouse face if it is at the
11100 end of a line (on a newline). The cursor appears there, but
11101 mouse highlighting does not. */
11102 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11103 mouse_face_here_p
= 1;
11105 /* Maybe clear the display under the cursor. */
11106 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11109 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11111 cursor_glyph
= get_phys_cursor_glyph (w
);
11112 if (cursor_glyph
== NULL
)
11113 goto mark_cursor_off
;
11115 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11117 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11119 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11121 cursor_glyph
->pixel_width
,
11122 cursor_row
->visible_height
,
11126 /* Erase the cursor by redrawing the character underneath it. */
11127 if (mouse_face_here_p
)
11128 hl
= DRAW_MOUSE_FACE
;
11129 else if (cursor_row
->inverse_p
)
11130 hl
= DRAW_INVERSE_VIDEO
;
11132 hl
= DRAW_NORMAL_TEXT
;
11133 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11136 w
->phys_cursor_on_p
= 0;
11137 w
->phys_cursor_type
= NO_CURSOR
;
11141 /* Display or clear cursor of window W. If ON is zero, clear the
11142 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11143 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11146 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11148 int on
, hpos
, vpos
, x
, y
;
11150 struct frame
*f
= XFRAME (w
->frame
);
11151 int new_cursor_type
;
11152 int new_cursor_width
;
11153 struct glyph_matrix
*current_glyphs
;
11154 struct glyph_row
*glyph_row
;
11155 struct glyph
*glyph
;
11157 /* This is pointless on invisible frames, and dangerous on garbaged
11158 windows and frames; in the latter case, the frame or window may
11159 be in the midst of changing its size, and x and y may be off the
11161 if (! FRAME_VISIBLE_P (f
)
11162 || FRAME_GARBAGED_P (f
)
11163 || vpos
>= w
->current_matrix
->nrows
11164 || hpos
>= w
->current_matrix
->matrix_w
)
11167 /* If cursor is off and we want it off, return quickly. */
11168 if (!on
&& !w
->phys_cursor_on_p
)
11171 current_glyphs
= w
->current_matrix
;
11172 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11173 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11175 /* If cursor row is not enabled, we don't really know where to
11176 display the cursor. */
11177 if (!glyph_row
->enabled_p
)
11179 w
->phys_cursor_on_p
= 0;
11183 xassert (interrupt_input_blocked
);
11185 /* Set new_cursor_type to the cursor we want to be displayed. In a
11186 mini-buffer window, we want the cursor only to appear if we are
11187 reading input from this window. For the selected window, we want
11188 the cursor type given by the frame parameter. If explicitly
11189 marked off, draw no cursor. In all other cases, we want a hollow
11191 new_cursor_width
= -1;
11192 if (cursor_in_echo_area
11193 && FRAME_HAS_MINIBUF_P (f
)
11194 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11196 if (w
== XWINDOW (echo_area_window
))
11197 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11199 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11203 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11204 || w
!= XWINDOW (f
->selected_window
))
11206 extern int cursor_in_non_selected_windows
;
11208 if (MINI_WINDOW_P (w
)
11209 || !cursor_in_non_selected_windows
11210 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11211 new_cursor_type
= NO_CURSOR
;
11213 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11215 else if (w
->cursor_off_p
)
11216 new_cursor_type
= NO_CURSOR
;
11219 struct buffer
*b
= XBUFFER (w
->buffer
);
11221 if (EQ (b
->cursor_type
, Qt
))
11222 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11224 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11225 &new_cursor_width
);
11229 /* If cursor is currently being shown and we don't want it to be or
11230 it is in the wrong place, or the cursor type is not what we want,
11232 if (w
->phys_cursor_on_p
11234 || w
->phys_cursor
.x
!= x
11235 || w
->phys_cursor
.y
!= y
11236 || new_cursor_type
!= w
->phys_cursor_type
))
11237 x_erase_phys_cursor (w
);
11239 /* If the cursor is now invisible and we want it to be visible,
11241 if (on
&& !w
->phys_cursor_on_p
)
11243 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11244 w
->phys_cursor_height
= glyph_row
->height
;
11246 /* Set phys_cursor_.* before x_draw_.* is called because some
11247 of them may need the information. */
11248 w
->phys_cursor
.x
= x
;
11249 w
->phys_cursor
.y
= glyph_row
->y
;
11250 w
->phys_cursor
.hpos
= hpos
;
11251 w
->phys_cursor
.vpos
= vpos
;
11252 w
->phys_cursor_type
= new_cursor_type
;
11253 w
->phys_cursor_on_p
= 1;
11255 switch (new_cursor_type
)
11257 case HOLLOW_BOX_CURSOR
:
11258 x_draw_hollow_cursor (w
, glyph_row
);
11261 case FILLED_BOX_CURSOR
:
11262 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11266 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11277 if (w
== XWINDOW (f
->selected_window
))
11278 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11279 xic_set_preeditarea (w
, x
, y
);
11284 if (updating_frame
!= f
)
11285 XFlush (FRAME_X_DISPLAY (f
));
11290 /* Display the cursor on window W, or clear it. X and Y are window
11291 relative pixel coordinates. HPOS and VPOS are glyph matrix
11292 positions. If W is not the selected window, display a hollow
11293 cursor. ON non-zero means display the cursor at X, Y which
11294 correspond to HPOS, VPOS, otherwise it is cleared. */
11297 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11299 int on
, hpos
, vpos
, x
, y
;
11302 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11307 /* Display the cursor on window W, or clear it, according to ON_P.
11308 Don't change the cursor's position. */
11311 x_update_cursor (f
, on_p
)
11314 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11318 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11319 in the window tree rooted at W. */
11322 x_update_cursor_in_window_tree (w
, on_p
)
11328 if (!NILP (w
->hchild
))
11329 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11330 else if (!NILP (w
->vchild
))
11331 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11333 x_update_window_cursor (w
, on_p
);
11335 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11340 /* Switch the display of W's cursor on or off, according to the value
11344 x_update_window_cursor (w
, on
)
11348 /* Don't update cursor in windows whose frame is in the process
11349 of being deleted. */
11350 if (w
->current_matrix
)
11353 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11354 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11364 /* Refresh bitmap kitchen sink icon for frame F
11365 when we get an expose event for it. */
11371 /* Normally, the window manager handles this function. */
11374 /* Make the x-window of frame F use the gnu icon bitmap. */
11377 x_bitmap_icon (f
, file
)
11383 if (FRAME_X_WINDOW (f
) == 0)
11386 /* Free up our existing icon bitmap if any. */
11387 if (f
->output_data
.x
->icon_bitmap
> 0)
11388 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11389 f
->output_data
.x
->icon_bitmap
= 0;
11391 if (STRINGP (file
))
11392 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11395 /* Create the GNU bitmap if necessary. */
11396 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11397 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11398 = x_create_bitmap_from_data (f
, gnu_bits
,
11399 gnu_width
, gnu_height
);
11401 /* The first time we create the GNU bitmap,
11402 this increments the ref-count one extra time.
11403 As a result, the GNU bitmap is never freed.
11404 That way, we don't have to worry about allocating it again. */
11405 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11407 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11410 x_wm_set_icon_pixmap (f
, bitmap_id
);
11411 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11417 /* Make the x-window of frame F use a rectangle with text.
11418 Use ICON_NAME as the text. */
11421 x_text_icon (f
, icon_name
)
11425 if (FRAME_X_WINDOW (f
) == 0)
11430 XTextProperty text
;
11431 text
.value
= (unsigned char *) icon_name
;
11432 text
.encoding
= XA_STRING
;
11434 text
.nitems
= strlen (icon_name
);
11435 #ifdef USE_X_TOOLKIT
11436 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11438 #else /* not USE_X_TOOLKIT */
11439 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11440 #endif /* not USE_X_TOOLKIT */
11442 #else /* not HAVE_X11R4 */
11443 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11444 #endif /* not HAVE_X11R4 */
11446 if (f
->output_data
.x
->icon_bitmap
> 0)
11447 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11448 f
->output_data
.x
->icon_bitmap
= 0;
11449 x_wm_set_icon_pixmap (f
, 0);
11454 #define X_ERROR_MESSAGE_SIZE 200
11456 /* If non-nil, this should be a string.
11457 It means catch X errors and store the error message in this string. */
11459 static Lisp_Object x_error_message_string
;
11461 /* An X error handler which stores the error message in
11462 x_error_message_string. This is called from x_error_handler if
11463 x_catch_errors is in effect. */
11466 x_error_catcher (display
, error
)
11468 XErrorEvent
*error
;
11470 XGetErrorText (display
, error
->error_code
,
11471 XSTRING (x_error_message_string
)->data
,
11472 X_ERROR_MESSAGE_SIZE
);
11475 /* Begin trapping X errors for display DPY. Actually we trap X errors
11476 for all displays, but DPY should be the display you are actually
11479 After calling this function, X protocol errors no longer cause
11480 Emacs to exit; instead, they are recorded in the string
11481 stored in x_error_message_string.
11483 Calling x_check_errors signals an Emacs error if an X error has
11484 occurred since the last call to x_catch_errors or x_check_errors.
11486 Calling x_uncatch_errors resumes the normal error handling. */
11488 void x_check_errors ();
11489 static Lisp_Object
x_catch_errors_unwind ();
11492 x_catch_errors (dpy
)
11495 int count
= specpdl_ptr
- specpdl
;
11497 /* Make sure any errors from previous requests have been dealt with. */
11498 XSync (dpy
, False
);
11500 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11502 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11503 XSTRING (x_error_message_string
)->data
[0] = 0;
11508 /* Unbind the binding that we made to check for X errors. */
11511 x_catch_errors_unwind (old_val
)
11512 Lisp_Object old_val
;
11514 x_error_message_string
= old_val
;
11518 /* If any X protocol errors have arrived since the last call to
11519 x_catch_errors or x_check_errors, signal an Emacs error using
11520 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11523 x_check_errors (dpy
, format
)
11527 /* Make sure to catch any errors incurred so far. */
11528 XSync (dpy
, False
);
11530 if (XSTRING (x_error_message_string
)->data
[0])
11531 error (format
, XSTRING (x_error_message_string
)->data
);
11534 /* Nonzero if we had any X protocol errors
11535 since we did x_catch_errors on DPY. */
11538 x_had_errors_p (dpy
)
11541 /* Make sure to catch any errors incurred so far. */
11542 XSync (dpy
, False
);
11544 return XSTRING (x_error_message_string
)->data
[0] != 0;
11547 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11550 x_clear_errors (dpy
)
11553 XSTRING (x_error_message_string
)->data
[0] = 0;
11556 /* Stop catching X protocol errors and let them make Emacs die.
11557 DPY should be the display that was passed to x_catch_errors.
11558 COUNT should be the value that was returned by
11559 the corresponding call to x_catch_errors. */
11562 x_uncatch_errors (dpy
, count
)
11566 unbind_to (count
, Qnil
);
11570 static unsigned int x_wire_count
;
11573 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11578 /* Handle SIGPIPE, which can happen when the connection to a server
11579 simply goes away. SIGPIPE is handled by x_connection_signal.
11580 Don't need to do anything, because the write which caused the
11581 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11582 which will do the appropriate cleanup for us. */
11585 x_connection_signal (signalnum
) /* If we don't have an argument, */
11586 int signalnum
; /* some compilers complain in signal calls. */
11589 /* USG systems forget handlers when they are used;
11590 must reestablish each time */
11591 signal (signalnum
, x_connection_signal
);
11596 /************************************************************************
11598 ************************************************************************/
11600 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11601 the text of an error message that lead to the connection loss. */
11604 x_connection_closed (dpy
, error_message
)
11606 char *error_message
;
11608 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11609 Lisp_Object frame
, tail
;
11613 msg
= (char *) alloca (strlen (error_message
) + 1);
11614 strcpy (msg
, error_message
);
11615 handling_signal
= 0;
11617 /* Prevent being called recursively because of an error condition
11618 below. Otherwise, we might end up with printing ``can't find per
11619 display information'' in the recursive call instead of printing
11620 the original message here. */
11621 count
= x_catch_errors (dpy
);
11623 /* We have to close the display to inform Xt that it doesn't
11624 exist anymore. If we don't, Xt will continue to wait for
11625 events from the display. As a consequence, a sequence of
11627 M-x make-frame-on-display RET :1 RET
11628 ...kill the new frame, so that we get an IO error...
11629 M-x make-frame-on-display RET :1 RET
11631 will indefinitely wait in Xt for events for display `:1', opened
11632 in the first class to make-frame-on-display.
11634 Closing the display is reported to lead to a bus error on
11635 OpenWindows in certain situations. I suspect that is a bug
11636 in OpenWindows. I don't know how to cicumvent it here. */
11638 #ifdef USE_X_TOOLKIT
11639 /* If DPYINFO is null, this means we didn't open the display
11640 in the first place, so don't try to close it. */
11642 XtCloseDisplay (dpy
);
11645 /* Indicate that this display is dead. */
11647 dpyinfo
->display
= 0;
11649 /* First delete frames whose mini-buffers are on frames
11650 that are on the dead display. */
11651 FOR_EACH_FRAME (tail
, frame
)
11653 Lisp_Object minibuf_frame
;
11655 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11656 if (FRAME_X_P (XFRAME (frame
))
11657 && FRAME_X_P (XFRAME (minibuf_frame
))
11658 && ! EQ (frame
, minibuf_frame
)
11659 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11660 Fdelete_frame (frame
, Qt
);
11663 /* Now delete all remaining frames on the dead display.
11664 We are now sure none of these is used as the mini-buffer
11665 for another frame that we need to delete. */
11666 FOR_EACH_FRAME (tail
, frame
)
11667 if (FRAME_X_P (XFRAME (frame
))
11668 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11670 /* Set this to t so that Fdelete_frame won't get confused
11671 trying to find a replacement. */
11672 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
11673 Fdelete_frame (frame
, Qt
);
11677 x_delete_display (dpyinfo
);
11679 x_uncatch_errors (dpy
, count
);
11681 if (x_display_list
== 0)
11683 fprintf (stderr
, "%s\n", msg
);
11684 shut_down_emacs (0, 0, Qnil
);
11688 /* Ordinary stack unwind doesn't deal with these. */
11690 sigunblock (sigmask (SIGIO
));
11692 sigunblock (sigmask (SIGALRM
));
11693 TOTALLY_UNBLOCK_INPUT
;
11695 clear_waiting_for_input ();
11700 /* This is the usual handler for X protocol errors.
11701 It kills all frames on the display that we got the error for.
11702 If that was the only one, it prints an error message and kills Emacs. */
11705 x_error_quitter (display
, error
)
11707 XErrorEvent
*error
;
11709 char buf
[256], buf1
[356];
11711 /* Note that there is no real way portable across R3/R4 to get the
11712 original error handler. */
11714 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
11715 sprintf (buf1
, "X protocol error: %s on protocol request %d",
11716 buf
, error
->request_code
);
11717 x_connection_closed (display
, buf1
);
11721 /* This is the first-level handler for X protocol errors.
11722 It calls x_error_quitter or x_error_catcher. */
11725 x_error_handler (display
, error
)
11727 XErrorEvent
*error
;
11729 if (! NILP (x_error_message_string
))
11730 x_error_catcher (display
, error
);
11732 x_error_quitter (display
, error
);
11736 /* This is the handler for X IO errors, always.
11737 It kills all frames on the display that we lost touch with.
11738 If that was the only one, it prints an error message and kills Emacs. */
11741 x_io_error_quitter (display
)
11746 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
11747 x_connection_closed (display
, buf
);
11751 /* Changing the font of the frame. */
11753 /* Give frame F the font named FONTNAME as its default font, and
11754 return the full name of that font. FONTNAME may be a wildcard
11755 pattern; in that case, we choose some font that fits the pattern.
11756 The return value shows which font we chose. */
11759 x_new_font (f
, fontname
)
11761 register char *fontname
;
11763 struct font_info
*fontp
11764 = FS_LOAD_FONT (f
, 0, fontname
, -1);
11769 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
11770 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
11771 f
->output_data
.x
->fontset
= -1;
11773 /* Compute the scroll bar width in character columns. */
11774 if (f
->scroll_bar_pixel_width
> 0)
11776 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11777 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
11781 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11782 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
11785 /* Now make the frame display the given font. */
11786 if (FRAME_X_WINDOW (f
) != 0)
11788 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
11789 f
->output_data
.x
->font
->fid
);
11790 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
11791 f
->output_data
.x
->font
->fid
);
11792 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
11793 f
->output_data
.x
->font
->fid
);
11795 frame_update_line_height (f
);
11797 /* Don't change the size of a tip frame; there's no point in
11798 doing it because it's done in Fx_show_tip, and it leads to
11799 problems because the tip frame has no widget. */
11800 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
11801 x_set_window_size (f
, 0, f
->width
, f
->height
);
11804 /* If we are setting a new frame's font for the first time,
11805 there are no faces yet, so this font's height is the line height. */
11806 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
11808 return build_string (fontp
->full_name
);
11811 /* Give frame F the fontset named FONTSETNAME as its default font, and
11812 return the full name of that fontset. FONTSETNAME may be a wildcard
11813 pattern; in that case, we choose some fontset that fits the pattern.
11814 The return value shows which fontset we chose. */
11817 x_new_fontset (f
, fontsetname
)
11821 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
11822 Lisp_Object result
;
11827 if (f
->output_data
.x
->fontset
== fontset
)
11828 /* This fontset is already set in frame F. There's nothing more
11830 return fontset_name (fontset
);
11832 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
11834 if (!STRINGP (result
))
11835 /* Can't load ASCII font. */
11838 /* Since x_new_font doesn't update any fontset information, do it now. */
11839 f
->output_data
.x
->fontset
= fontset
;
11843 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
11844 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
11847 return build_string (fontsetname
);
11851 /***********************************************************************
11853 ***********************************************************************/
11859 /* XIM destroy callback function, which is called whenever the
11860 connection to input method XIM dies. CLIENT_DATA contains a
11861 pointer to the x_display_info structure corresponding to XIM. */
11864 xim_destroy_callback (xim
, client_data
, call_data
)
11866 XPointer client_data
;
11867 XPointer call_data
;
11869 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
11870 Lisp_Object frame
, tail
;
11874 /* No need to call XDestroyIC.. */
11875 FOR_EACH_FRAME (tail
, frame
)
11877 struct frame
*f
= XFRAME (frame
);
11878 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
11880 FRAME_XIC (f
) = NULL
;
11881 if (FRAME_XIC_FONTSET (f
))
11883 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
11884 FRAME_XIC_FONTSET (f
) = NULL
;
11889 /* No need to call XCloseIM. */
11890 dpyinfo
->xim
= NULL
;
11891 XFree (dpyinfo
->xim_styles
);
11895 #endif /* HAVE_X11R6 */
11897 /* Open the connection to the XIM server on display DPYINFO.
11898 RESOURCE_NAME is the resource name Emacs uses. */
11901 xim_open_dpy (dpyinfo
, resource_name
)
11902 struct x_display_info
*dpyinfo
;
11903 char *resource_name
;
11908 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
11909 dpyinfo
->xim
= xim
;
11914 XIMCallback destroy
;
11917 /* Get supported styles and XIM values. */
11918 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
11921 destroy
.callback
= xim_destroy_callback
;
11922 destroy
.client_data
= (XPointer
)dpyinfo
;
11923 /* This isn't prptotyped in OSF 5.0. */
11924 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
11928 #else /* not USE_XIM */
11929 dpyinfo
->xim
= NULL
;
11930 #endif /* not USE_XIM */
11934 #ifdef HAVE_X11R6_XIM
11938 struct x_display_info
*dpyinfo
;
11939 char *resource_name
;
11942 /* XIM instantiate callback function, which is called whenever an XIM
11943 server is available. DISPLAY is teh display of the XIM.
11944 CLIENT_DATA contains a pointer to an xim_inst_t structure created
11945 when the callback was registered. */
11948 xim_instantiate_callback (display
, client_data
, call_data
)
11950 XPointer client_data
;
11951 XPointer call_data
;
11953 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
11954 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
11956 /* We don't support multiple XIM connections. */
11960 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
11962 /* Create XIC for the existing frames on the same display, as long
11963 as they have no XIC. */
11964 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
11966 Lisp_Object tail
, frame
;
11969 FOR_EACH_FRAME (tail
, frame
)
11971 struct frame
*f
= XFRAME (frame
);
11973 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
11974 if (FRAME_XIC (f
) == NULL
)
11976 create_frame_xic (f
);
11977 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
11978 xic_set_statusarea (f
);
11979 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
11981 struct window
*w
= XWINDOW (f
->selected_window
);
11982 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
11991 #endif /* HAVE_X11R6_XIM */
11994 /* Open a connection to the XIM server on display DPYINFO.
11995 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
11996 connection only at the first time. On X11R6, open the connection
11997 in the XIM instantiate callback function. */
12000 xim_initialize (dpyinfo
, resource_name
)
12001 struct x_display_info
*dpyinfo
;
12002 char *resource_name
;
12005 #ifdef HAVE_X11R6_XIM
12006 struct xim_inst_t
*xim_inst
;
12009 dpyinfo
->xim
= NULL
;
12010 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12011 xim_inst
->dpyinfo
= dpyinfo
;
12012 len
= strlen (resource_name
);
12013 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12014 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12015 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12016 resource_name
, EMACS_CLASS
,
12017 xim_instantiate_callback
,
12018 /* Fixme: This is XPointer in
12019 XFree86 but (XPointer *) on
12020 Tru64, at least. */
12021 (XPointer
) xim_inst
);
12022 #else /* not HAVE_X11R6_XIM */
12023 dpyinfo
->xim
= NULL
;
12024 xim_open_dpy (dpyinfo
, resource_name
);
12025 #endif /* not HAVE_X11R6_XIM */
12027 #else /* not USE_XIM */
12028 dpyinfo
->xim
= NULL
;
12029 #endif /* not USE_XIM */
12033 /* Close the connection to the XIM server on display DPYINFO. */
12036 xim_close_dpy (dpyinfo
)
12037 struct x_display_info
*dpyinfo
;
12040 #ifdef HAVE_X11R6_XIM
12041 if (dpyinfo
->display
)
12042 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12044 xim_instantiate_callback
, NULL
);
12045 #endif /* not HAVE_X11R6_XIM */
12046 if (dpyinfo
->display
)
12047 XCloseIM (dpyinfo
->xim
);
12048 dpyinfo
->xim
= NULL
;
12049 XFree (dpyinfo
->xim_styles
);
12050 #endif /* USE_XIM */
12053 #endif /* not HAVE_X11R6_XIM */
12057 /* Calculate the absolute position in frame F
12058 from its current recorded position values and gravity. */
12061 x_calc_absolute_position (f
)
12065 int win_x
= 0, win_y
= 0;
12066 int flags
= f
->output_data
.x
->size_hint_flags
;
12069 /* We have nothing to do if the current position
12070 is already for the top-left corner. */
12071 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12074 #ifdef USE_X_TOOLKIT
12075 this_window
= XtWindow (f
->output_data
.x
->widget
);
12077 this_window
= FRAME_X_WINDOW (f
);
12080 /* Find the position of the outside upper-left corner of
12081 the inner window, with respect to the outer window.
12082 But do this only if we will need the results. */
12083 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12088 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12091 x_clear_errors (FRAME_X_DISPLAY (f
));
12092 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12094 /* From-window, to-window. */
12096 f
->output_data
.x
->parent_desc
,
12098 /* From-position, to-position. */
12099 0, 0, &win_x
, &win_y
,
12101 /* Child of win. */
12103 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12105 Window newroot
, newparent
= 0xdeadbeef;
12106 Window
*newchildren
;
12107 unsigned int nchildren
;
12109 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12110 &newparent
, &newchildren
, &nchildren
))
12113 XFree ((char *) newchildren
);
12115 f
->output_data
.x
->parent_desc
= newparent
;
12121 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12125 /* Treat negative positions as relative to the leftmost bottommost
12126 position that fits on the screen. */
12127 if (flags
& XNegative
)
12128 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12129 - 2 * f
->output_data
.x
->border_width
- win_x
12131 + f
->output_data
.x
->left_pos
);
12134 int height
= PIXEL_HEIGHT (f
);
12136 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12137 /* Something is fishy here. When using Motif, starting Emacs with
12138 `-g -0-0', the frame appears too low by a few pixels.
12140 This seems to be so because initially, while Emacs is starting,
12141 the column widget's height and the frame's pixel height are
12142 different. The column widget's height is the right one. In
12143 later invocations, when Emacs is up, the frame's pixel height
12146 It's not obvious where the initial small difference comes from.
12147 2000-12-01, gerd. */
12149 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12152 if (flags
& YNegative
)
12153 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12154 - 2 * f
->output_data
.x
->border_width
12157 + f
->output_data
.x
->top_pos
);
12160 /* The left_pos and top_pos
12161 are now relative to the top and left screen edges,
12162 so the flags should correspond. */
12163 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12166 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12167 to really change the position, and 0 when calling from
12168 x_make_frame_visible (in that case, XOFF and YOFF are the current
12169 position values). It is -1 when calling from x_set_frame_parameters,
12170 which means, do adjust for borders but don't change the gravity. */
12173 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12175 register int xoff
, yoff
;
12176 int change_gravity
;
12178 int modified_top
, modified_left
;
12180 if (change_gravity
> 0)
12182 f
->output_data
.x
->top_pos
= yoff
;
12183 f
->output_data
.x
->left_pos
= xoff
;
12184 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12186 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12188 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12189 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12191 x_calc_absolute_position (f
);
12194 x_wm_set_size_hint (f
, (long) 0, 0);
12196 modified_left
= f
->output_data
.x
->left_pos
;
12197 modified_top
= f
->output_data
.x
->top_pos
;
12198 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12199 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12200 /* It is a mystery why we need to add the border_width here
12201 when the frame is already visible, but experiment says we do. */
12202 if (change_gravity
!= 0)
12204 modified_left
+= f
->output_data
.x
->border_width
;
12205 modified_top
+= f
->output_data
.x
->border_width
;
12209 #ifdef USE_X_TOOLKIT
12210 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12211 modified_left
, modified_top
);
12212 #else /* not USE_X_TOOLKIT */
12213 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12214 modified_left
, modified_top
);
12215 #endif /* not USE_X_TOOLKIT */
12220 /* Change the size of frame F's X window to COLS/ROWS in the case F
12221 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12222 top-left-corner window gravity for this size change and subsequent
12223 size changes. Otherwise we leave the window gravity unchanged. */
12226 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12228 int change_gravity
;
12231 int pixelwidth
, pixelheight
;
12233 check_frame_size (f
, &rows
, &cols
);
12234 f
->output_data
.x
->vertical_scroll_bar_extra
12235 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12237 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12238 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12239 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12240 f
->output_data
.x
->flags_areas_extra
12241 = FRAME_FLAGS_AREA_WIDTH (f
);
12242 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12243 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12245 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12246 x_wm_set_size_hint (f
, (long) 0, 0);
12248 XSync (FRAME_X_DISPLAY (f
), False
);
12249 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12250 pixelwidth
, pixelheight
);
12252 /* Now, strictly speaking, we can't be sure that this is accurate,
12253 but the window manager will get around to dealing with the size
12254 change request eventually, and we'll hear how it went when the
12255 ConfigureNotify event gets here.
12257 We could just not bother storing any of this information here,
12258 and let the ConfigureNotify event set everything up, but that
12259 might be kind of confusing to the Lisp code, since size changes
12260 wouldn't be reported in the frame parameters until some random
12261 point in the future when the ConfigureNotify event arrives.
12263 We pass 1 for DELAY since we can't run Lisp code inside of
12265 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12266 PIXEL_WIDTH (f
) = pixelwidth
;
12267 PIXEL_HEIGHT (f
) = pixelheight
;
12269 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12270 receive in the ConfigureNotify event; if we get what we asked
12271 for, then the event won't cause the screen to become garbaged, so
12272 we have to make sure to do it here. */
12273 SET_FRAME_GARBAGED (f
);
12275 XFlush (FRAME_X_DISPLAY (f
));
12279 /* Call this to change the size of frame F's x-window.
12280 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12281 for this size change and subsequent size changes.
12282 Otherwise we leave the window gravity unchanged. */
12285 x_set_window_size (f
, change_gravity
, cols
, rows
)
12287 int change_gravity
;
12292 #ifdef USE_X_TOOLKIT
12294 if (f
->output_data
.x
->widget
!= NULL
)
12296 /* The x and y position of the widget is clobbered by the
12297 call to XtSetValues within EmacsFrameSetCharSize.
12298 This is a real kludge, but I don't understand Xt so I can't
12299 figure out a correct fix. Can anyone else tell me? -- rms. */
12300 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12301 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12302 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12303 f
->output_data
.x
->widget
->core
.x
= xpos
;
12304 f
->output_data
.x
->widget
->core
.y
= ypos
;
12307 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12309 #else /* not USE_X_TOOLKIT */
12311 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12313 #endif /* not USE_X_TOOLKIT */
12315 /* If cursor was outside the new size, mark it as off. */
12316 mark_window_cursors_off (XWINDOW (f
->root_window
));
12318 /* Clear out any recollection of where the mouse highlighting was,
12319 since it might be in a place that's outside the new frame size.
12320 Actually checking whether it is outside is a pain in the neck,
12321 so don't try--just let the highlighting be done afresh with new size. */
12322 cancel_mouse_face (f
);
12327 /* Mouse warping. */
12330 x_set_mouse_position (f
, x
, y
)
12336 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12337 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12339 if (pix_x
< 0) pix_x
= 0;
12340 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12342 if (pix_y
< 0) pix_y
= 0;
12343 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12347 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12348 0, 0, 0, 0, pix_x
, pix_y
);
12352 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12355 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12361 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12362 0, 0, 0, 0, pix_x
, pix_y
);
12366 /* focus shifting, raising and lowering. */
12369 x_focus_on_frame (f
)
12372 #if 0 /* This proves to be unpleasant. */
12376 /* I don't think that the ICCCM allows programs to do things like this
12377 without the interaction of the window manager. Whatever you end up
12378 doing with this code, do it to x_unfocus_frame too. */
12379 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12380 RevertToPointerRoot
, CurrentTime
);
12385 x_unfocus_frame (f
)
12389 /* Look at the remarks in x_focus_on_frame. */
12390 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12391 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12392 RevertToPointerRoot
, CurrentTime
);
12396 /* Raise frame F. */
12402 if (f
->async_visible
)
12405 #ifdef USE_X_TOOLKIT
12406 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12407 #else /* not USE_X_TOOLKIT */
12408 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12409 #endif /* not USE_X_TOOLKIT */
12410 XFlush (FRAME_X_DISPLAY (f
));
12415 /* Lower frame F. */
12421 if (f
->async_visible
)
12424 #ifdef USE_X_TOOLKIT
12425 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12426 #else /* not USE_X_TOOLKIT */
12427 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12428 #endif /* not USE_X_TOOLKIT */
12429 XFlush (FRAME_X_DISPLAY (f
));
12435 XTframe_raise_lower (f
, raise_flag
)
12445 /* Change of visibility. */
12447 /* This tries to wait until the frame is really visible.
12448 However, if the window manager asks the user where to position
12449 the frame, this will return before the user finishes doing that.
12450 The frame will not actually be visible at that time,
12451 but it will become visible later when the window manager
12452 finishes with it. */
12455 x_make_frame_visible (f
)
12459 int original_top
, original_left
;
12460 int retry_count
= 2;
12466 type
= x_icon_type (f
);
12468 x_bitmap_icon (f
, type
);
12470 if (! FRAME_VISIBLE_P (f
))
12472 /* We test FRAME_GARBAGED_P here to make sure we don't
12473 call x_set_offset a second time
12474 if we get to x_make_frame_visible a second time
12475 before the window gets really visible. */
12476 if (! FRAME_ICONIFIED_P (f
)
12477 && ! f
->output_data
.x
->asked_for_visible
)
12478 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12480 f
->output_data
.x
->asked_for_visible
= 1;
12482 if (! EQ (Vx_no_window_manager
, Qt
))
12483 x_wm_set_window_state (f
, NormalState
);
12484 #ifdef USE_X_TOOLKIT
12485 /* This was XtPopup, but that did nothing for an iconified frame. */
12486 XtMapWidget (f
->output_data
.x
->widget
);
12487 #else /* not USE_X_TOOLKIT */
12488 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12489 #endif /* not USE_X_TOOLKIT */
12490 #if 0 /* This seems to bring back scroll bars in the wrong places
12491 if the window configuration has changed. They seem
12492 to come back ok without this. */
12493 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12494 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12498 XFlush (FRAME_X_DISPLAY (f
));
12500 /* Synchronize to ensure Emacs knows the frame is visible
12501 before we do anything else. We do this loop with input not blocked
12502 so that incoming events are handled. */
12506 /* This must be before UNBLOCK_INPUT
12507 since events that arrive in response to the actions above
12508 will set it when they are handled. */
12509 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12511 original_left
= f
->output_data
.x
->left_pos
;
12512 original_top
= f
->output_data
.x
->top_pos
;
12514 /* This must come after we set COUNT. */
12517 /* We unblock here so that arriving X events are processed. */
12519 /* Now move the window back to where it was "supposed to be".
12520 But don't do it if the gravity is negative.
12521 When the gravity is negative, this uses a position
12522 that is 3 pixels too low. Perhaps that's really the border width.
12524 Don't do this if the window has never been visible before,
12525 because the window manager may choose the position
12526 and we don't want to override it. */
12528 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12529 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12530 && previously_visible
)
12534 unsigned int width
, height
, border
, depth
;
12538 /* On some window managers (such as FVWM) moving an existing
12539 window, even to the same place, causes the window manager
12540 to introduce an offset. This can cause the window to move
12541 to an unexpected location. Check the geometry (a little
12542 slow here) and then verify that the window is in the right
12543 place. If the window is not in the right place, move it
12544 there, and take the potential window manager hit. */
12545 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12546 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12548 if (original_left
!= x
|| original_top
!= y
)
12549 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12550 original_left
, original_top
);
12555 XSETFRAME (frame
, f
);
12557 /* Wait until the frame is visible. Process X events until a
12558 MapNotify event has been seen, or until we think we won't get a
12559 MapNotify at all.. */
12560 for (count
= input_signal_count
+ 10;
12561 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12563 /* Force processing of queued events. */
12566 /* Machines that do polling rather than SIGIO have been
12567 observed to go into a busy-wait here. So we'll fake an
12568 alarm signal to let the handler know that there's something
12569 to be read. We used to raise a real alarm, but it seems
12570 that the handler isn't always enabled here. This is
12572 if (input_polling_used ())
12574 /* It could be confusing if a real alarm arrives while
12575 processing the fake one. Turn it off and let the
12576 handler reset it. */
12577 extern void poll_for_input_1
P_ ((void));
12578 int old_poll_suppress_count
= poll_suppress_count
;
12579 poll_suppress_count
= 1;
12580 poll_for_input_1 ();
12581 poll_suppress_count
= old_poll_suppress_count
;
12584 /* See if a MapNotify event has been processed. */
12585 FRAME_SAMPLE_VISIBILITY (f
);
12590 (let ((f (selected-frame)))
12594 the frame is not raised with various window managers on
12595 FreeBSD, Linux and Solaris. It turns out that, for some
12596 unknown reason, the call to XtMapWidget is completely ignored.
12597 Mapping the widget a second time works. */
12599 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12604 /* Change from mapped state to withdrawn state. */
12606 /* Make the frame visible (mapped and not iconified). */
12609 x_make_frame_invisible (f
)
12614 #ifdef USE_X_TOOLKIT
12615 /* Use the frame's outermost window, not the one we normally draw on. */
12616 window
= XtWindow (f
->output_data
.x
->widget
);
12617 #else /* not USE_X_TOOLKIT */
12618 window
= FRAME_X_WINDOW (f
);
12619 #endif /* not USE_X_TOOLKIT */
12621 /* Don't keep the highlight on an invisible frame. */
12622 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12623 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12625 #if 0/* This might add unreliability; I don't trust it -- rms. */
12626 if (! f
->async_visible
&& ! f
->async_iconified
)
12632 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12633 that the current position of the window is user-specified, rather than
12634 program-specified, so that when the window is mapped again, it will be
12635 placed at the same location, without forcing the user to position it
12636 by hand again (they have already done that once for this window.) */
12637 x_wm_set_size_hint (f
, (long) 0, 1);
12641 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12642 DefaultScreen (FRAME_X_DISPLAY (f
))))
12644 UNBLOCK_INPUT_RESIGNAL
;
12645 error ("Can't notify window manager of window withdrawal");
12647 #else /* ! defined (HAVE_X11R4) */
12649 /* Tell the window manager what we're going to do. */
12650 if (! EQ (Vx_no_window_manager
, Qt
))
12654 unmap
.xunmap
.type
= UnmapNotify
;
12655 unmap
.xunmap
.window
= window
;
12656 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12657 unmap
.xunmap
.from_configure
= False
;
12658 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12659 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12661 SubstructureRedirectMaskSubstructureNotifyMask
,
12664 UNBLOCK_INPUT_RESIGNAL
;
12665 error ("Can't notify window manager of withdrawal");
12669 /* Unmap the window ourselves. Cheeky! */
12670 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12671 #endif /* ! defined (HAVE_X11R4) */
12673 /* We can't distinguish this from iconification
12674 just by the event that we get from the server.
12675 So we can't win using the usual strategy of letting
12676 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
12677 and synchronize with the server to make sure we agree. */
12679 FRAME_ICONIFIED_P (f
) = 0;
12680 f
->async_visible
= 0;
12681 f
->async_iconified
= 0;
12688 /* Change window state from mapped to iconified. */
12691 x_iconify_frame (f
)
12697 /* Don't keep the highlight on an invisible frame. */
12698 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12699 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12701 if (f
->async_iconified
)
12706 FRAME_SAMPLE_VISIBILITY (f
);
12708 type
= x_icon_type (f
);
12710 x_bitmap_icon (f
, type
);
12712 #ifdef USE_X_TOOLKIT
12714 if (! FRAME_VISIBLE_P (f
))
12716 if (! EQ (Vx_no_window_manager
, Qt
))
12717 x_wm_set_window_state (f
, IconicState
);
12718 /* This was XtPopup, but that did nothing for an iconified frame. */
12719 XtMapWidget (f
->output_data
.x
->widget
);
12720 /* The server won't give us any event to indicate
12721 that an invisible frame was changed to an icon,
12722 so we have to record it here. */
12725 f
->async_iconified
= 1;
12726 f
->async_visible
= 0;
12731 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
12732 XtWindow (f
->output_data
.x
->widget
),
12733 DefaultScreen (FRAME_X_DISPLAY (f
)));
12737 error ("Can't notify window manager of iconification");
12739 f
->async_iconified
= 1;
12740 f
->async_visible
= 0;
12744 XFlush (FRAME_X_DISPLAY (f
));
12746 #else /* not USE_X_TOOLKIT */
12748 /* Make sure the X server knows where the window should be positioned,
12749 in case the user deiconifies with the window manager. */
12750 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
12751 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12753 /* Since we don't know which revision of X we're running, we'll use both
12754 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
12756 /* X11R4: send a ClientMessage to the window manager using the
12757 WM_CHANGE_STATE type. */
12761 message
.xclient
.window
= FRAME_X_WINDOW (f
);
12762 message
.xclient
.type
= ClientMessage
;
12763 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
12764 message
.xclient
.format
= 32;
12765 message
.xclient
.data
.l
[0] = IconicState
;
12767 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12768 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12770 SubstructureRedirectMask
| SubstructureNotifyMask
,
12773 UNBLOCK_INPUT_RESIGNAL
;
12774 error ("Can't notify window manager of iconification");
12778 /* X11R3: set the initial_state field of the window manager hints to
12780 x_wm_set_window_state (f
, IconicState
);
12782 if (!FRAME_VISIBLE_P (f
))
12784 /* If the frame was withdrawn, before, we must map it. */
12785 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12788 f
->async_iconified
= 1;
12789 f
->async_visible
= 0;
12791 XFlush (FRAME_X_DISPLAY (f
));
12793 #endif /* not USE_X_TOOLKIT */
12797 /* Free X resources of frame F. */
12800 x_free_frame_resources (f
)
12803 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12807 /* If a display connection is dead, don't try sending more
12808 commands to the X server. */
12809 if (dpyinfo
->display
)
12811 if (f
->output_data
.x
->icon_desc
)
12812 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
12816 free_frame_xic (f
);
12819 if (FRAME_X_WINDOW (f
))
12820 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12822 #ifdef USE_X_TOOLKIT
12823 if (f
->output_data
.x
->widget
)
12824 XtDestroyWidget (f
->output_data
.x
->widget
);
12825 free_frame_menubar (f
);
12826 #endif /* USE_X_TOOLKIT */
12828 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
12829 unload_color (f
, f
->output_data
.x
->background_pixel
);
12830 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
12831 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
12832 unload_color (f
, f
->output_data
.x
->border_pixel
);
12833 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
12835 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
12836 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
12837 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
12838 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
12839 if (f
->output_data
.x
->white_relief
.allocated_p
)
12840 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
12841 if (f
->output_data
.x
->black_relief
.allocated_p
)
12842 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
12844 if (FRAME_FACE_CACHE (f
))
12845 free_frame_faces (f
);
12848 XFlush (FRAME_X_DISPLAY (f
));
12851 if (f
->output_data
.x
->saved_menu_event
)
12852 xfree (f
->output_data
.x
->saved_menu_event
);
12854 xfree (f
->output_data
.x
);
12855 f
->output_data
.x
= NULL
;
12857 if (f
== dpyinfo
->x_focus_frame
)
12858 dpyinfo
->x_focus_frame
= 0;
12859 if (f
== dpyinfo
->x_focus_event_frame
)
12860 dpyinfo
->x_focus_event_frame
= 0;
12861 if (f
== dpyinfo
->x_highlight_frame
)
12862 dpyinfo
->x_highlight_frame
= 0;
12864 if (f
== dpyinfo
->mouse_face_mouse_frame
)
12866 dpyinfo
->mouse_face_beg_row
12867 = dpyinfo
->mouse_face_beg_col
= -1;
12868 dpyinfo
->mouse_face_end_row
12869 = dpyinfo
->mouse_face_end_col
= -1;
12870 dpyinfo
->mouse_face_window
= Qnil
;
12871 dpyinfo
->mouse_face_deferred_gc
= 0;
12872 dpyinfo
->mouse_face_mouse_frame
= 0;
12879 /* Destroy the X window of frame F. */
12882 x_destroy_window (f
)
12885 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12887 /* If a display connection is dead, don't try sending more
12888 commands to the X server. */
12889 if (dpyinfo
->display
!= 0)
12890 x_free_frame_resources (f
);
12892 dpyinfo
->reference_count
--;
12896 /* Setting window manager hints. */
12898 /* Set the normal size hints for the window manager, for frame F.
12899 FLAGS is the flags word to use--or 0 meaning preserve the flags
12900 that the window now has.
12901 If USER_POSITION is nonzero, we set the USPosition
12902 flag (this is useful when FLAGS is 0). */
12905 x_wm_set_size_hint (f
, flags
, user_position
)
12910 XSizeHints size_hints
;
12912 #ifdef USE_X_TOOLKIT
12915 Dimension widget_width
, widget_height
;
12916 Window window
= XtWindow (f
->output_data
.x
->widget
);
12917 #else /* not USE_X_TOOLKIT */
12918 Window window
= FRAME_X_WINDOW (f
);
12919 #endif /* not USE_X_TOOLKIT */
12921 /* Setting PMaxSize caused various problems. */
12922 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
12924 size_hints
.x
= f
->output_data
.x
->left_pos
;
12925 size_hints
.y
= f
->output_data
.x
->top_pos
;
12927 #ifdef USE_X_TOOLKIT
12928 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
12929 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
12930 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
12931 size_hints
.height
= widget_height
;
12932 size_hints
.width
= widget_width
;
12933 #else /* not USE_X_TOOLKIT */
12934 size_hints
.height
= PIXEL_HEIGHT (f
);
12935 size_hints
.width
= PIXEL_WIDTH (f
);
12936 #endif /* not USE_X_TOOLKIT */
12938 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
12939 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
12940 size_hints
.max_width
12941 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
12942 size_hints
.max_height
12943 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
12945 /* Calculate the base and minimum sizes.
12947 (When we use the X toolkit, we don't do it here.
12948 Instead we copy the values that the widgets are using, below.) */
12949 #ifndef USE_X_TOOLKIT
12951 int base_width
, base_height
;
12952 int min_rows
= 0, min_cols
= 0;
12954 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
12955 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
12957 check_frame_size (f
, &min_rows
, &min_cols
);
12959 /* The window manager uses the base width hints to calculate the
12960 current number of rows and columns in the frame while
12961 resizing; min_width and min_height aren't useful for this
12962 purpose, since they might not give the dimensions for a
12963 zero-row, zero-column frame.
12965 We use the base_width and base_height members if we have
12966 them; otherwise, we set the min_width and min_height members
12967 to the size for a zero x zero frame. */
12970 size_hints
.flags
|= PBaseSize
;
12971 size_hints
.base_width
= base_width
;
12972 size_hints
.base_height
= base_height
;
12973 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
12974 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
12976 size_hints
.min_width
= base_width
;
12977 size_hints
.min_height
= base_height
;
12981 /* If we don't need the old flags, we don't need the old hint at all. */
12984 size_hints
.flags
|= flags
;
12987 #endif /* not USE_X_TOOLKIT */
12990 XSizeHints hints
; /* Sometimes I hate X Windows... */
12991 long supplied_return
;
12995 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
12998 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13001 #ifdef USE_X_TOOLKIT
13002 size_hints
.base_height
= hints
.base_height
;
13003 size_hints
.base_width
= hints
.base_width
;
13004 size_hints
.min_height
= hints
.min_height
;
13005 size_hints
.min_width
= hints
.min_width
;
13009 size_hints
.flags
|= flags
;
13014 if (hints
.flags
& PSize
)
13015 size_hints
.flags
|= PSize
;
13016 if (hints
.flags
& PPosition
)
13017 size_hints
.flags
|= PPosition
;
13018 if (hints
.flags
& USPosition
)
13019 size_hints
.flags
|= USPosition
;
13020 if (hints
.flags
& USSize
)
13021 size_hints
.flags
|= USSize
;
13025 #ifndef USE_X_TOOLKIT
13030 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
13031 size_hints
.flags
|= PWinGravity
;
13035 size_hints
.flags
&= ~ PPosition
;
13036 size_hints
.flags
|= USPosition
;
13038 #endif /* PWinGravity */
13041 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13043 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13047 /* Used for IconicState or NormalState */
13050 x_wm_set_window_state (f
, state
)
13054 #ifdef USE_X_TOOLKIT
13057 XtSetArg (al
[0], XtNinitialState
, state
);
13058 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13059 #else /* not USE_X_TOOLKIT */
13060 Window window
= FRAME_X_WINDOW (f
);
13062 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
13063 f
->output_data
.x
->wm_hints
.initial_state
= state
;
13065 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13066 #endif /* not USE_X_TOOLKIT */
13070 x_wm_set_icon_pixmap (f
, pixmap_id
)
13074 Pixmap icon_pixmap
;
13076 #ifndef USE_X_TOOLKIT
13077 Window window
= FRAME_X_WINDOW (f
);
13082 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
13083 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
13087 /* It seems there is no way to turn off use of an icon pixmap.
13088 The following line does it, only if no icon has yet been created,
13089 for some window managers. But with mwm it crashes.
13090 Some people say it should clear the IconPixmapHint bit in this case,
13091 but that doesn't work, and the X consortium said it isn't the
13092 right thing at all. Since there is no way to win,
13093 best to explicitly give up. */
13095 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
13101 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
13105 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
13106 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13109 #else /* not USE_X_TOOLKIT */
13111 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
13112 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13114 #endif /* not USE_X_TOOLKIT */
13118 x_wm_set_icon_position (f
, icon_x
, icon_y
)
13120 int icon_x
, icon_y
;
13122 #ifdef USE_X_TOOLKIT
13123 Window window
= XtWindow (f
->output_data
.x
->widget
);
13125 Window window
= FRAME_X_WINDOW (f
);
13128 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
13129 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13130 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13132 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13136 /***********************************************************************
13138 ***********************************************************************/
13140 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13143 x_get_font_info (f
, font_idx
)
13147 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13151 /* Return a list of names of available fonts matching PATTERN on frame F.
13153 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13156 SIZE < 0 means include scalable fonts.
13158 Frame F null means we have not yet created any frame on X, and
13159 consult the first display in x_display_list. MAXNAMES sets a limit
13160 on how many fonts to match. */
13163 x_list_fonts (f
, pattern
, size
, maxnames
)
13165 Lisp_Object pattern
;
13169 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13170 Lisp_Object tem
, second_best
;
13171 struct x_display_info
*dpyinfo
13172 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13173 Display
*dpy
= dpyinfo
->display
;
13174 int try_XLoadQueryFont
= 0;
13176 int allow_scalable_fonts_p
= 0;
13180 allow_scalable_fonts_p
= 1;
13184 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13185 if (NILP (patterns
))
13186 patterns
= Fcons (pattern
, Qnil
);
13188 if (maxnames
== 1 && !size
)
13189 /* We can return any single font matching PATTERN. */
13190 try_XLoadQueryFont
= 1;
13192 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13195 char **names
= NULL
;
13197 pattern
= XCAR (patterns
);
13198 /* See if we cached the result for this particular query.
13199 The cache is an alist of the form:
13200 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13201 tem
= XCDR (dpyinfo
->name_list_element
);
13202 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13203 allow_scalable_fonts_p
? Qt
: Qnil
);
13204 list
= Fassoc (key
, tem
);
13207 list
= Fcdr_safe (list
);
13208 /* We have a cashed list. Don't have to get the list again. */
13212 /* At first, put PATTERN in the cache. */
13215 count
= x_catch_errors (dpy
);
13217 if (try_XLoadQueryFont
)
13220 unsigned long value
;
13222 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13223 if (x_had_errors_p (dpy
))
13225 /* This error is perhaps due to insufficient memory on X
13226 server. Let's just ignore it. */
13228 x_clear_errors (dpy
);
13232 && XGetFontProperty (font
, XA_FONT
, &value
))
13234 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13235 int len
= strlen (name
);
13238 /* If DXPC (a Differential X Protocol Compressor)
13239 Ver.3.7 is running, XGetAtomName will return null
13240 string. We must avoid such a name. */
13242 try_XLoadQueryFont
= 0;
13246 names
= (char **) alloca (sizeof (char *));
13247 /* Some systems only allow alloca assigned to a
13249 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13250 bcopy (name
, names
[0], len
+ 1);
13255 try_XLoadQueryFont
= 0;
13258 XFreeFont (dpy
, font
);
13261 if (!try_XLoadQueryFont
)
13263 /* We try at least 10 fonts because XListFonts will return
13264 auto-scaled fonts at the head. */
13265 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13267 if (x_had_errors_p (dpy
))
13269 /* This error is perhaps due to insufficient memory on X
13270 server. Let's just ignore it. */
13272 x_clear_errors (dpy
);
13276 x_uncatch_errors (dpy
, count
);
13283 /* Make a list of all the fonts we got back.
13284 Store that in the font cache for the display. */
13285 for (i
= 0; i
< num_fonts
; i
++)
13288 char *p
= names
[i
];
13289 int average_width
= -1, dashes
= 0;
13291 /* Count the number of dashes in NAMES[I]. If there are
13292 14 dashes, and the field value following 12th dash
13293 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13294 is usually too ugly to be used for editing. Let's
13300 if (dashes
== 7) /* PIXEL_SIZE field */
13302 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13303 average_width
= atoi (p
);
13306 if (allow_scalable_fonts_p
13307 || dashes
< 14 || average_width
!= 0)
13309 tem
= build_string (names
[i
]);
13310 if (NILP (Fassoc (tem
, list
)))
13312 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13313 && ((fast_c_string_match_ignore_case
13314 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13316 /* We can set the value of PIXEL_SIZE to the
13317 width of this font. */
13318 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13320 /* For the moment, width is not known. */
13321 list
= Fcons (Fcons (tem
, Qnil
), list
);
13325 if (!try_XLoadQueryFont
)
13326 XFreeFontNames (names
);
13329 /* Now store the result in the cache. */
13330 XCDR (dpyinfo
->name_list_element
)
13331 = Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
));
13334 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13336 newlist
= second_best
= Qnil
;
13337 /* Make a list of the fonts that have the right width. */
13338 for (; CONSP (list
); list
= XCDR (list
))
13344 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13348 newlist
= Fcons (XCAR (tem
), newlist
);
13352 if (!INTEGERP (XCDR (tem
)))
13354 /* Since we have not yet known the size of this font, we
13355 must try slow function call XLoadQueryFont. */
13356 XFontStruct
*thisinfo
;
13359 count
= x_catch_errors (dpy
);
13360 thisinfo
= XLoadQueryFont (dpy
,
13361 XSTRING (XCAR (tem
))->data
);
13362 if (x_had_errors_p (dpy
))
13364 /* This error is perhaps due to insufficient memory on X
13365 server. Let's just ignore it. */
13367 x_clear_errors (dpy
);
13369 x_uncatch_errors (dpy
, count
);
13375 = (thisinfo
->min_bounds
.width
== 0
13377 : make_number (thisinfo
->max_bounds
.width
));
13378 XFreeFont (dpy
, thisinfo
);
13381 /* For unknown reason, the previous call of XListFont had
13382 returned a font which can't be opened. Record the size
13383 as 0 not to try to open it again. */
13384 XCDR (tem
) = make_number (0);
13387 found_size
= XINT (XCDR (tem
));
13388 if (found_size
== size
)
13389 newlist
= Fcons (XCAR (tem
), newlist
);
13390 else if (found_size
> 0)
13392 if (NILP (second_best
))
13394 else if (found_size
< size
)
13396 if (XINT (XCDR (second_best
)) > size
13397 || XINT (XCDR (second_best
)) < found_size
)
13402 if (XINT (XCDR (second_best
)) > size
13403 && XINT (XCDR (second_best
)) > found_size
)
13408 if (!NILP (newlist
))
13410 else if (!NILP (second_best
))
13412 newlist
= Fcons (XCAR (second_best
), Qnil
);
13423 /* Check that FONT is valid on frame F. It is if it can be found in F's
13427 x_check_font (f
, font
)
13432 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13434 xassert (font
!= NULL
);
13436 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13437 if (dpyinfo
->font_table
[i
].name
13438 && font
== dpyinfo
->font_table
[i
].font
)
13441 xassert (i
< dpyinfo
->n_fonts
);
13444 #endif /* GLYPH_DEBUG != 0 */
13446 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13447 Note: There are (broken) X fonts out there with invalid XFontStruct
13448 min_bounds contents. For example, handa@etl.go.jp reports that
13449 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13450 have font->min_bounds.width == 0. */
13453 x_font_min_bounds (font
, w
, h
)
13457 *h
= FONT_HEIGHT (font
);
13458 *w
= font
->min_bounds
.width
;
13460 /* Try to handle the case where FONT->min_bounds has invalid
13461 contents. Since the only font known to have invalid min_bounds
13462 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13464 *w
= font
->max_bounds
.width
;
13468 /* Compute the smallest character width and smallest font height over
13469 all fonts available on frame F. Set the members smallest_char_width
13470 and smallest_font_height in F's x_display_info structure to
13471 the values computed. Value is non-zero if smallest_font_height or
13472 smallest_char_width become smaller than they were before. */
13475 x_compute_min_glyph_bounds (f
)
13479 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13481 int old_width
= dpyinfo
->smallest_char_width
;
13482 int old_height
= dpyinfo
->smallest_font_height
;
13484 dpyinfo
->smallest_font_height
= 100000;
13485 dpyinfo
->smallest_char_width
= 100000;
13487 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13488 if (dpyinfo
->font_table
[i
].name
)
13490 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13493 font
= (XFontStruct
*) fontp
->font
;
13494 xassert (font
!= (XFontStruct
*) ~0);
13495 x_font_min_bounds (font
, &w
, &h
);
13497 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13498 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13501 xassert (dpyinfo
->smallest_char_width
> 0
13502 && dpyinfo
->smallest_font_height
> 0);
13504 return (dpyinfo
->n_fonts
== 1
13505 || dpyinfo
->smallest_char_width
< old_width
13506 || dpyinfo
->smallest_font_height
< old_height
);
13510 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13511 pointer to the structure font_info while allocating it dynamically.
13512 If SIZE is 0, load any size of font.
13513 If loading is failed, return NULL. */
13516 x_load_font (f
, fontname
, size
)
13518 register char *fontname
;
13521 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13522 Lisp_Object font_names
;
13525 /* Get a list of all the fonts that match this name. Once we
13526 have a list of matching fonts, we compare them against the fonts
13527 we already have by comparing names. */
13528 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13530 if (!NILP (font_names
))
13535 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13536 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13537 if (dpyinfo
->font_table
[i
].name
13538 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13539 XSTRING (XCAR (tail
))->data
)
13540 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13541 XSTRING (XCAR (tail
))->data
)))
13542 return (dpyinfo
->font_table
+ i
);
13545 /* Load the font and add it to the table. */
13549 struct font_info
*fontp
;
13550 unsigned long value
;
13553 /* If we have found fonts by x_list_font, load one of them. If
13554 not, we still try to load a font by the name given as FONTNAME
13555 because XListFonts (called in x_list_font) of some X server has
13556 a bug of not finding a font even if the font surely exists and
13557 is loadable by XLoadQueryFont. */
13558 if (size
> 0 && !NILP (font_names
))
13559 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13562 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13563 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13564 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13566 /* This error is perhaps due to insufficient memory on X
13567 server. Let's just ignore it. */
13569 x_clear_errors (FRAME_X_DISPLAY (f
));
13571 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13576 /* Find a free slot in the font table. */
13577 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13578 if (dpyinfo
->font_table
[i
].name
== NULL
)
13581 /* If no free slot found, maybe enlarge the font table. */
13582 if (i
== dpyinfo
->n_fonts
13583 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13586 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13587 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13588 dpyinfo
->font_table
13589 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13592 fontp
= dpyinfo
->font_table
+ i
;
13593 if (i
== dpyinfo
->n_fonts
)
13594 ++dpyinfo
->n_fonts
;
13596 /* Now fill in the slots of *FONTP. */
13598 fontp
->font
= font
;
13599 fontp
->font_idx
= i
;
13600 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13601 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13603 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13605 if (XGetFontProperty (font
, XA_FONT
, &value
))
13607 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13611 /* Count the number of dashes in the "full name".
13612 If it is too few, this isn't really the font's full name,
13614 In X11R4, the fonts did not come with their canonical names
13625 full_name
= (char *) xmalloc (p
- name
+ 1);
13626 bcopy (name
, full_name
, p
- name
+ 1);
13632 if (full_name
!= 0)
13633 fontp
->full_name
= full_name
;
13635 fontp
->full_name
= fontp
->name
;
13637 fontp
->size
= font
->max_bounds
.width
;
13638 fontp
->height
= FONT_HEIGHT (font
);
13640 if (NILP (font_names
))
13642 /* We come here because of a bug of XListFonts mentioned at
13643 the head of this block. Let's store this information in
13644 the cache for x_list_fonts. */
13645 Lisp_Object lispy_name
= build_string (fontname
);
13646 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13647 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
13650 XCDR (dpyinfo
->name_list_element
)
13651 = Fcons (Fcons (key
,
13652 Fcons (Fcons (lispy_full_name
,
13653 make_number (fontp
->size
)),
13655 XCDR (dpyinfo
->name_list_element
));
13658 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
13660 XCDR (dpyinfo
->name_list_element
)
13661 = Fcons (Fcons (key
,
13662 Fcons (Fcons (lispy_full_name
,
13663 make_number (fontp
->size
)),
13665 XCDR (dpyinfo
->name_list_element
));
13669 /* The slot `encoding' specifies how to map a character
13670 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
13671 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
13672 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
13673 2:0xA020..0xFF7F). For the moment, we don't know which charset
13674 uses this font. So, we set information in fontp->encoding[1]
13675 which is never used by any charset. If mapping can't be
13676 decided, set FONT_ENCODING_NOT_DECIDED. */
13678 = (font
->max_byte1
== 0
13680 ? (font
->min_char_or_byte2
< 0x80
13681 ? (font
->max_char_or_byte2
< 0x80
13682 ? 0 /* 0x20..0x7F */
13683 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
13684 : 1) /* 0xA0..0xFF */
13686 : (font
->min_byte1
< 0x80
13687 ? (font
->max_byte1
< 0x80
13688 ? (font
->min_char_or_byte2
< 0x80
13689 ? (font
->max_char_or_byte2
< 0x80
13690 ? 0 /* 0x2020..0x7F7F */
13691 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
13692 : 3) /* 0x20A0..0x7FFF */
13693 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
13694 : (font
->min_char_or_byte2
< 0x80
13695 ? (font
->max_char_or_byte2
< 0x80
13696 ? 2 /* 0xA020..0xFF7F */
13697 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
13698 : 1))); /* 0xA0A0..0xFFFF */
13700 fontp
->baseline_offset
13701 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
13702 ? (long) value
: 0);
13703 fontp
->relative_compose
13704 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
13705 ? (long) value
: 0);
13706 fontp
->default_ascent
13707 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
13708 ? (long) value
: 0);
13710 /* Set global flag fonts_changed_p to non-zero if the font loaded
13711 has a character with a smaller width than any other character
13712 before, or if the font loaded has a smalle>r height than any
13713 other font loaded before. If this happens, it will make a
13714 glyph matrix reallocation necessary. */
13715 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
13722 /* Return a pointer to struct font_info of a font named FONTNAME for
13723 frame F. If no such font is loaded, return NULL. */
13726 x_query_font (f
, fontname
)
13728 register char *fontname
;
13730 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13733 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13734 if (dpyinfo
->font_table
[i
].name
13735 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
13736 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
13737 return (dpyinfo
->font_table
+ i
);
13742 /* Find a CCL program for a font specified by FONTP, and set the member
13743 `encoder' of the structure. */
13746 x_find_ccl_program (fontp
)
13747 struct font_info
*fontp
;
13749 Lisp_Object list
, elt
;
13752 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
13756 && STRINGP (XCAR (elt
))
13757 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
13759 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
13766 struct ccl_program
*ccl
13767 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
13769 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
13772 fontp
->font_encoder
= ccl
;
13778 /***********************************************************************
13780 ***********************************************************************/
13782 #ifdef USE_X_TOOLKIT
13783 static XrmOptionDescRec emacs_options
[] = {
13784 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13785 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13787 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13788 XrmoptionSepArg
, NULL
},
13789 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13791 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13792 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13793 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13794 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13795 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13796 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13797 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13799 #endif /* USE_X_TOOLKIT */
13801 static int x_initialized
;
13803 #ifdef MULTI_KBOARD
13804 /* Test whether two display-name strings agree up to the dot that separates
13805 the screen number from the server number. */
13807 same_x_server (name1
, name2
)
13808 char *name1
, *name2
;
13810 int seen_colon
= 0;
13811 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
13812 int system_name_length
= strlen (system_name
);
13813 int length_until_period
= 0;
13815 while (system_name
[length_until_period
] != 0
13816 && system_name
[length_until_period
] != '.')
13817 length_until_period
++;
13819 /* Treat `unix' like an empty host name. */
13820 if (! strncmp (name1
, "unix:", 5))
13822 if (! strncmp (name2
, "unix:", 5))
13824 /* Treat this host's name like an empty host name. */
13825 if (! strncmp (name1
, system_name
, system_name_length
)
13826 && name1
[system_name_length
] == ':')
13827 name1
+= system_name_length
;
13828 if (! strncmp (name2
, system_name
, system_name_length
)
13829 && name2
[system_name_length
] == ':')
13830 name2
+= system_name_length
;
13831 /* Treat this host's domainless name like an empty host name. */
13832 if (! strncmp (name1
, system_name
, length_until_period
)
13833 && name1
[length_until_period
] == ':')
13834 name1
+= length_until_period
;
13835 if (! strncmp (name2
, system_name
, length_until_period
)
13836 && name2
[length_until_period
] == ':')
13837 name2
+= length_until_period
;
13839 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13843 if (seen_colon
&& *name1
== '.')
13847 && (*name1
== '.' || *name1
== '\0')
13848 && (*name2
== '.' || *name2
== '\0'));
13852 struct x_display_info
*
13853 x_term_init (display_name
, xrm_option
, resource_name
)
13854 Lisp_Object display_name
;
13856 char *resource_name
;
13860 struct x_display_info
*dpyinfo
;
13865 if (!x_initialized
)
13871 #ifdef USE_X_TOOLKIT
13872 /* weiner@footloose.sps.mot.com reports that this causes
13874 X protocol error: BadAtom (invalid Atom parameter)
13875 on protocol request 18skiloaf.
13876 So let's not use it until R6. */
13877 #ifdef HAVE_X11XTR6
13878 XtSetLanguageProc (NULL
, NULL
, NULL
);
13889 argv
[argc
++] = "-xrm";
13890 argv
[argc
++] = xrm_option
;
13892 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
13893 resource_name
, EMACS_CLASS
,
13894 emacs_options
, XtNumber (emacs_options
),
13897 #ifdef HAVE_X11XTR6
13898 /* I think this is to compensate for XtSetLanguageProc. */
13903 #else /* not USE_X_TOOLKIT */
13905 XSetLocaleModifiers ("");
13907 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
13908 #endif /* not USE_X_TOOLKIT */
13910 /* Detect failure. */
13917 /* We have definitely succeeded. Record the new connection. */
13919 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
13920 bzero (dpyinfo
, sizeof *dpyinfo
);
13922 #ifdef MULTI_KBOARD
13924 struct x_display_info
*share
;
13927 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
13928 share
= share
->next
, tail
= XCDR (tail
))
13929 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
13930 XSTRING (display_name
)->data
))
13933 dpyinfo
->kboard
= share
->kboard
;
13936 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
13937 init_kboard (dpyinfo
->kboard
);
13938 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
13940 char *vendor
= ServerVendor (dpy
);
13942 dpyinfo
->kboard
->Vsystem_key_alist
13943 = call1 (Qvendor_specific_keysyms
,
13944 build_string (vendor
? vendor
: ""));
13948 dpyinfo
->kboard
->next_kboard
= all_kboards
;
13949 all_kboards
= dpyinfo
->kboard
;
13950 /* Don't let the initial kboard remain current longer than necessary.
13951 That would cause problems if a file loaded on startup tries to
13952 prompt in the mini-buffer. */
13953 if (current_kboard
== initial_kboard
)
13954 current_kboard
= dpyinfo
->kboard
;
13956 dpyinfo
->kboard
->reference_count
++;
13960 /* Put this display on the chain. */
13961 dpyinfo
->next
= x_display_list
;
13962 x_display_list
= dpyinfo
;
13964 /* Put it on x_display_name_list as well, to keep them parallel. */
13965 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
13966 x_display_name_list
);
13967 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13969 dpyinfo
->display
= dpy
;
13972 XSetAfterFunction (x_current_display
, x_trace_wire
);
13976 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
13977 + STRING_BYTES (XSTRING (Vsystem_name
))
13979 sprintf (dpyinfo
->x_id_name
, "%s@%s",
13980 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
13982 /* Figure out which modifier bits mean what. */
13983 x_find_modifier_meanings (dpyinfo
);
13985 /* Get the scroll bar cursor. */
13986 dpyinfo
->vertical_scroll_bar_cursor
13987 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
13989 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
13990 resource_name
, EMACS_CLASS
);
13991 #ifdef HAVE_XRMSETDATABASE
13992 XrmSetDatabase (dpyinfo
->display
, xrdb
);
13994 dpyinfo
->display
->db
= xrdb
;
13996 /* Put the rdb where we can find it in a way that works on
13998 dpyinfo
->xrdb
= xrdb
;
14000 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14001 DefaultScreen (dpyinfo
->display
));
14002 select_visual (dpyinfo
);
14003 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
14004 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
14005 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
14006 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
14007 dpyinfo
->grabbed
= 0;
14008 dpyinfo
->reference_count
= 0;
14009 dpyinfo
->icon_bitmap_id
= -1;
14010 dpyinfo
->font_table
= NULL
;
14011 dpyinfo
->n_fonts
= 0;
14012 dpyinfo
->font_table_size
= 0;
14013 dpyinfo
->bitmaps
= 0;
14014 dpyinfo
->bitmaps_size
= 0;
14015 dpyinfo
->bitmaps_last
= 0;
14016 dpyinfo
->scratch_cursor_gc
= 0;
14017 dpyinfo
->mouse_face_mouse_frame
= 0;
14018 dpyinfo
->mouse_face_deferred_gc
= 0;
14019 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
14020 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
14021 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
14022 dpyinfo
->mouse_face_window
= Qnil
;
14023 dpyinfo
->mouse_face_overlay
= Qnil
;
14024 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
14025 dpyinfo
->mouse_face_defer
= 0;
14026 dpyinfo
->x_focus_frame
= 0;
14027 dpyinfo
->x_focus_event_frame
= 0;
14028 dpyinfo
->x_highlight_frame
= 0;
14029 dpyinfo
->image_cache
= make_image_cache ();
14031 /* See if a private colormap is requested. */
14032 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
14034 if (dpyinfo
->visual
->class == PseudoColor
)
14037 value
= display_x_get_resource (dpyinfo
,
14038 build_string ("privateColormap"),
14039 build_string ("PrivateColormap"),
14041 if (STRINGP (value
)
14042 && (!strcmp (XSTRING (value
)->data
, "true")
14043 || !strcmp (XSTRING (value
)->data
, "on")))
14044 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
14048 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
14049 dpyinfo
->visual
, AllocNone
);
14052 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
14053 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
14054 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
14055 dpyinfo
->resy
= pixels
* 25.4 / mm
;
14056 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
14057 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
14058 dpyinfo
->resx
= pixels
* 25.4 / mm
;
14061 dpyinfo
->Xatom_wm_protocols
14062 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
14063 dpyinfo
->Xatom_wm_take_focus
14064 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
14065 dpyinfo
->Xatom_wm_save_yourself
14066 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
14067 dpyinfo
->Xatom_wm_delete_window
14068 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
14069 dpyinfo
->Xatom_wm_change_state
14070 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
14071 dpyinfo
->Xatom_wm_configure_denied
14072 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
14073 dpyinfo
->Xatom_wm_window_moved
14074 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
14075 dpyinfo
->Xatom_editres
14076 = XInternAtom (dpyinfo
->display
, "Editres", False
);
14077 dpyinfo
->Xatom_CLIPBOARD
14078 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
14079 dpyinfo
->Xatom_TIMESTAMP
14080 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
14081 dpyinfo
->Xatom_TEXT
14082 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
14083 dpyinfo
->Xatom_COMPOUND_TEXT
14084 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
14085 dpyinfo
->Xatom_DELETE
14086 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
14087 dpyinfo
->Xatom_MULTIPLE
14088 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
14089 dpyinfo
->Xatom_INCR
14090 = XInternAtom (dpyinfo
->display
, "INCR", False
);
14091 dpyinfo
->Xatom_EMACS_TMP
14092 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
14093 dpyinfo
->Xatom_TARGETS
14094 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
14095 dpyinfo
->Xatom_NULL
14096 = XInternAtom (dpyinfo
->display
, "NULL", False
);
14097 dpyinfo
->Xatom_ATOM_PAIR
14098 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
14099 /* For properties of font. */
14100 dpyinfo
->Xatom_PIXEL_SIZE
14101 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
14102 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
14103 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
14104 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
14105 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
14106 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
14107 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
14109 /* Ghostscript support. */
14110 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
14111 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
14113 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
14116 dpyinfo
->cut_buffers_initialized
= 0;
14118 connection
= ConnectionNumber (dpyinfo
->display
);
14119 dpyinfo
->connection
= connection
;
14124 null_bits
[0] = 0x00;
14126 dpyinfo
->null_pixel
14127 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14128 null_bits
, 1, 1, (long) 0, (long) 0,
14133 extern int gray_bitmap_width
, gray_bitmap_height
;
14134 extern char *gray_bitmap_bits
;
14136 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14138 gray_bitmap_width
, gray_bitmap_height
,
14139 (unsigned long) 1, (unsigned long) 0, 1);
14143 xim_initialize (dpyinfo
, resource_name
);
14146 #ifdef subprocesses
14147 /* This is only needed for distinguishing keyboard and process input. */
14148 if (connection
!= 0)
14149 add_keyboard_wait_descriptor (connection
);
14152 #ifndef F_SETOWN_BUG
14154 #ifdef F_SETOWN_SOCK_NEG
14155 /* stdin is a socket here */
14156 fcntl (connection
, F_SETOWN
, -getpid ());
14157 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14158 fcntl (connection
, F_SETOWN
, getpid ());
14159 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14160 #endif /* ! defined (F_SETOWN) */
14161 #endif /* F_SETOWN_BUG */
14164 if (interrupt_input
)
14165 init_sigio (connection
);
14166 #endif /* ! defined (SIGIO) */
14169 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14170 /* Make sure that we have a valid font for dialog boxes
14171 so that Xt does not crash. */
14173 Display
*dpy
= dpyinfo
->display
;
14174 XrmValue d
, fr
, to
;
14178 d
.addr
= (XPointer
)&dpy
;
14179 d
.size
= sizeof (Display
*);
14180 fr
.addr
= XtDefaultFont
;
14181 fr
.size
= sizeof (XtDefaultFont
);
14182 to
.size
= sizeof (Font
*);
14183 to
.addr
= (XPointer
)&font
;
14184 count
= x_catch_errors (dpy
);
14185 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14187 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14188 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14189 x_uncatch_errors (dpy
, count
);
14194 /* See if we should run in synchronous mode. This is useful
14195 for debugging X code. */
14198 value
= display_x_get_resource (dpyinfo
,
14199 build_string ("synchronous"),
14200 build_string ("Synchronous"),
14202 if (STRINGP (value
)
14203 && (!strcmp (XSTRING (value
)->data
, "true")
14204 || !strcmp (XSTRING (value
)->data
, "on")))
14205 XSynchronize (dpyinfo
->display
, True
);
14213 /* Get rid of display DPYINFO, assuming all frames are already gone,
14214 and without sending any more commands to the X server. */
14217 x_delete_display (dpyinfo
)
14218 struct x_display_info
*dpyinfo
;
14220 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14222 /* Discard this display from x_display_name_list and x_display_list.
14223 We can't use Fdelq because that can quit. */
14224 if (! NILP (x_display_name_list
)
14225 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14226 x_display_name_list
= XCDR (x_display_name_list
);
14231 tail
= x_display_name_list
;
14232 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14234 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14236 XCDR (tail
) = XCDR (XCDR (tail
));
14239 tail
= XCDR (tail
);
14243 if (next_noop_dpyinfo
== dpyinfo
)
14244 next_noop_dpyinfo
= dpyinfo
->next
;
14246 if (x_display_list
== dpyinfo
)
14247 x_display_list
= dpyinfo
->next
;
14250 struct x_display_info
*tail
;
14252 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14253 if (tail
->next
== dpyinfo
)
14254 tail
->next
= tail
->next
->next
;
14257 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14258 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14259 XrmDestroyDatabase (dpyinfo
->xrdb
);
14262 #ifdef MULTI_KBOARD
14263 if (--dpyinfo
->kboard
->reference_count
== 0)
14264 delete_kboard (dpyinfo
->kboard
);
14268 xim_close_dpy (dpyinfo
);
14271 xfree (dpyinfo
->font_table
);
14272 xfree (dpyinfo
->x_id_name
);
14273 xfree (dpyinfo
->color_cells
);
14278 /* Set up use of X before we make the first connection. */
14280 static struct redisplay_interface x_redisplay_interface
=
14285 x_clear_end_of_line
,
14287 x_after_update_window_line
,
14288 x_update_window_begin
,
14289 x_update_window_end
,
14292 x_clear_mouse_face
,
14293 x_get_glyph_overhangs
,
14294 x_fix_overlapping_area
14300 rif
= &x_redisplay_interface
;
14302 clear_frame_hook
= x_clear_frame
;
14303 ins_del_lines_hook
= x_ins_del_lines
;
14304 change_line_highlight_hook
= x_change_line_highlight
;
14305 delete_glyphs_hook
= x_delete_glyphs
;
14306 ring_bell_hook
= XTring_bell
;
14307 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14308 set_terminal_modes_hook
= XTset_terminal_modes
;
14309 update_begin_hook
= x_update_begin
;
14310 update_end_hook
= x_update_end
;
14311 set_terminal_window_hook
= XTset_terminal_window
;
14312 read_socket_hook
= XTread_socket
;
14313 frame_up_to_date_hook
= XTframe_up_to_date
;
14314 reassert_line_highlight_hook
= XTreassert_line_highlight
;
14315 mouse_position_hook
= XTmouse_position
;
14316 frame_rehighlight_hook
= XTframe_rehighlight
;
14317 frame_raise_lower_hook
= XTframe_raise_lower
;
14318 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14319 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14320 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14321 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14322 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14324 scroll_region_ok
= 1; /* we'll scroll partial frames */
14325 char_ins_del_ok
= 1;
14326 line_ins_del_ok
= 1; /* we'll just blt 'em */
14327 fast_clear_end_of_line
= 1; /* X does this well */
14328 memory_below_frame
= 0; /* we don't remember what scrolls
14333 last_tool_bar_item
= -1;
14334 any_help_event_p
= 0;
14336 /* Try to use interrupt input; if we can't, then start polling. */
14337 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14339 #ifdef USE_X_TOOLKIT
14340 XtToolkitInitialize ();
14342 Xt_app_con
= XtCreateApplicationContext ();
14344 /* Register a converter from strings to pixels, which uses
14345 Emacs' color allocation infrastructure. */
14346 XtAppSetTypeConverter (Xt_app_con
,
14347 XtRString
, XtRPixel
, cvt_string_to_pixel
,
14348 cvt_string_to_pixel_args
,
14349 XtNumber (cvt_string_to_pixel_args
),
14350 XtCacheByDisplay
, cvt_pixel_dtor
);
14352 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14354 /* Install an asynchronous timer that processes Xt timeout events
14355 every 0.1s. This is necessary because some widget sets use
14356 timeouts internally, for example the LessTif menu bar, or the
14357 Xaw3d scroll bar. When Xt timouts aren't processed, these
14358 widgets don't behave normally. */
14360 EMACS_TIME interval
;
14361 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14362 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14366 #ifdef USE_TOOLKIT_SCROLL_BARS
14367 xaw3d_arrow_scroll
= False
;
14368 xaw3d_pick_top
= True
;
14371 /* Note that there is no real way portable across R3/R4 to get the
14372 original error handler. */
14373 XSetErrorHandler (x_error_handler
);
14374 XSetIOErrorHandler (x_io_error_quitter
);
14376 /* Disable Window Change signals; they are handled by X events. */
14378 signal (SIGWINCH
, SIG_DFL
);
14379 #endif /* ! defined (SIGWINCH) */
14381 signal (SIGPIPE
, x_connection_signal
);
14388 staticpro (&x_error_message_string
);
14389 x_error_message_string
= Qnil
;
14391 staticpro (&x_display_name_list
);
14392 x_display_name_list
= Qnil
;
14394 staticpro (&last_mouse_scroll_bar
);
14395 last_mouse_scroll_bar
= Qnil
;
14397 staticpro (&Qvendor_specific_keysyms
);
14398 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14400 staticpro (&last_mouse_press_frame
);
14401 last_mouse_press_frame
= Qnil
;
14404 staticpro (&help_echo
);
14405 help_echo_object
= Qnil
;
14406 staticpro (&help_echo_object
);
14407 help_echo_window
= Qnil
;
14408 staticpro (&help_echo_window
);
14409 previous_help_echo
= Qnil
;
14410 staticpro (&previous_help_echo
);
14411 help_echo_pos
= -1;
14413 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14414 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
14415 For example, if a block cursor is over a tab, it will be drawn as\n\
14416 wide as that tab on the display.");
14417 x_stretch_cursor_p
= 0;
14419 DEFVAR_BOOL ("x-use-underline-position-properties",
14420 &x_use_underline_position_properties
,
14421 "*Non-nil means make use of UNDERLINE_POSITION font properties.\n\
14422 Nil means ignore them. If you encounter fonts with bogus\n\
14423 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior\n\
14424 to 4.1, set this to nil.");
14425 x_use_underline_position_properties
= 1;
14427 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14428 "What X toolkit scroll bars Emacs uses.\n\
14429 A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
14430 Otherwise, value is a symbol describing the X toolkit.");
14431 #ifdef USE_TOOLKIT_SCROLL_BARS
14433 Vx_toolkit_scroll_bars
= intern ("motif");
14434 #elif defined HAVE_XAW3D
14435 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14437 Vx_toolkit_scroll_bars
= intern ("xaw");
14440 Vx_toolkit_scroll_bars
= Qnil
;
14443 staticpro (&last_mouse_motion_frame
);
14444 last_mouse_motion_frame
= Qnil
;
14447 #endif /* not HAVE_X_WINDOWS */