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 int 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
);
4411 else if (!s
->background_filled_p
)
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
);
5867 else if (expose_window (w
, r
) == 0)
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
);
6002 /* If window is not yet fully initialized, do nothing. This can
6003 happen when toolkit scroll bars are used and a window is split.
6004 Reconfiguring the scroll bar will generate an expose for a newly
6006 if (w
->current_matrix
== NULL
)
6009 /* When we're currently updating the window, display and current
6010 matrix usually don't agree. Arrange for a thorough display
6012 if (w
== updated_window
)
6014 SET_FRAME_GARBAGED (f
);
6018 /* Frame-relative pixel rectangle of W. */
6019 wr
.x
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6020 wr
.y
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6021 wr
.width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6022 wr
.height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6024 if (x_intersect_rectangles (fr
, &wr
, &r
))
6026 int yb
= window_text_bottom_y (w
);
6027 struct glyph_row
*row
;
6028 int cursor_cleared_p
;
6030 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6031 r
.x
, r
.y
, r
.width
, r
.height
));
6033 /* Convert to window coordinates. */
6034 r
.x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.x
);
6035 r
.y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.y
);
6037 /* Turn off the cursor. */
6038 if (!w
->pseudo_window_p
6039 && x_phys_cursor_in_rect_p (w
, &r
))
6042 cursor_cleared_p
= 1;
6045 cursor_cleared_p
= 0;
6047 /* Find the first row intersecting the rectangle R. */
6048 for (row
= w
->current_matrix
->rows
;
6053 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6055 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
6056 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
6057 || (r
.y
>= y0
&& r
.y
< y1
)
6058 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
6059 expose_line (w
, row
, &r
);
6065 /* Display the mode line if there is one. */
6066 if (WINDOW_WANTS_MODELINE_P (w
)
6067 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6069 && row
->y
< r
.y
+ r
.height
)
6070 expose_line (w
, row
, &r
);
6072 if (!w
->pseudo_window_p
)
6074 /* Draw border between windows. */
6075 x_draw_vertical_border (w
);
6077 /* Turn the cursor on again. */
6078 if (cursor_cleared_p
)
6079 x_update_window_cursor (w
, 1);
6087 /* Determine the intersection of two rectangles R1 and R2. Return
6088 the intersection in *RESULT. Value is non-zero if RESULT is not
6092 x_intersect_rectangles (r1
, r2
, result
)
6093 XRectangle
*r1
, *r2
, *result
;
6095 XRectangle
*left
, *right
;
6096 XRectangle
*upper
, *lower
;
6097 int intersection_p
= 0;
6099 /* Rearrange so that R1 is the left-most rectangle. */
6101 left
= r1
, right
= r2
;
6103 left
= r2
, right
= r1
;
6105 /* X0 of the intersection is right.x0, if this is inside R1,
6106 otherwise there is no intersection. */
6107 if (right
->x
<= left
->x
+ left
->width
)
6109 result
->x
= right
->x
;
6111 /* The right end of the intersection is the minimum of the
6112 the right ends of left and right. */
6113 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
6116 /* Same game for Y. */
6118 upper
= r1
, lower
= r2
;
6120 upper
= r2
, lower
= r1
;
6122 /* The upper end of the intersection is lower.y0, if this is inside
6123 of upper. Otherwise, there is no intersection. */
6124 if (lower
->y
<= upper
->y
+ upper
->height
)
6126 result
->y
= lower
->y
;
6128 /* The lower end of the intersection is the minimum of the lower
6129 ends of upper and lower. */
6130 result
->height
= (min (lower
->y
+ lower
->height
,
6131 upper
->y
+ upper
->height
)
6137 return intersection_p
;
6148 /* We used to only do this if Vx_no_window_manager was non-nil, but
6149 the ICCCM (section 4.1.6) says that the window's border pixmap
6150 and border pixel are window attributes which are "private to the
6151 client", so we can always change it to whatever we want. */
6153 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6154 f
->output_data
.x
->border_pixel
);
6156 x_update_cursor (f
, 1);
6160 frame_unhighlight (f
)
6163 /* We used to only do this if Vx_no_window_manager was non-nil, but
6164 the ICCCM (section 4.1.6) says that the window's border pixmap
6165 and border pixel are window attributes which are "private to the
6166 client", so we can always change it to whatever we want. */
6168 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6169 f
->output_data
.x
->border_tile
);
6171 x_update_cursor (f
, 1);
6174 /* The focus has changed. Update the frames as necessary to reflect
6175 the new situation. Note that we can't change the selected frame
6176 here, because the Lisp code we are interrupting might become confused.
6177 Each event gets marked with the frame in which it occurred, so the
6178 Lisp code can tell when the switch took place by examining the events. */
6181 x_new_focus_frame (dpyinfo
, frame
)
6182 struct x_display_info
*dpyinfo
;
6183 struct frame
*frame
;
6185 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6187 if (frame
!= dpyinfo
->x_focus_frame
)
6189 /* Set this before calling other routines, so that they see
6190 the correct value of x_focus_frame. */
6191 dpyinfo
->x_focus_frame
= frame
;
6193 if (old_focus
&& old_focus
->auto_lower
)
6194 x_lower_frame (old_focus
);
6197 selected_frame
= frame
;
6198 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6200 Fselect_window (selected_frame
->selected_window
);
6201 choose_minibuf_frame ();
6204 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6205 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6207 pending_autoraise_frame
= 0;
6210 x_frame_rehighlight (dpyinfo
);
6213 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6216 x_mouse_leave (dpyinfo
)
6217 struct x_display_info
*dpyinfo
;
6219 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6222 /* The focus has changed, or we have redirected a frame's focus to
6223 another frame (this happens when a frame uses a surrogate
6224 mini-buffer frame). Shift the highlight as appropriate.
6226 The FRAME argument doesn't necessarily have anything to do with which
6227 frame is being highlighted or un-highlighted; we only use it to find
6228 the appropriate X display info. */
6231 XTframe_rehighlight (frame
)
6232 struct frame
*frame
;
6234 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6238 x_frame_rehighlight (dpyinfo
)
6239 struct x_display_info
*dpyinfo
;
6241 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6243 if (dpyinfo
->x_focus_frame
)
6245 dpyinfo
->x_highlight_frame
6246 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6247 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6248 : dpyinfo
->x_focus_frame
);
6249 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6251 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6252 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6256 dpyinfo
->x_highlight_frame
= 0;
6258 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6261 frame_unhighlight (old_highlight
);
6262 if (dpyinfo
->x_highlight_frame
)
6263 frame_highlight (dpyinfo
->x_highlight_frame
);
6269 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6271 /* Initialize mode_switch_bit and modifier_meaning. */
6273 x_find_modifier_meanings (dpyinfo
)
6274 struct x_display_info
*dpyinfo
;
6276 int min_code
, max_code
;
6279 XModifierKeymap
*mods
;
6281 dpyinfo
->meta_mod_mask
= 0;
6282 dpyinfo
->shift_lock_mask
= 0;
6283 dpyinfo
->alt_mod_mask
= 0;
6284 dpyinfo
->super_mod_mask
= 0;
6285 dpyinfo
->hyper_mod_mask
= 0;
6288 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6290 min_code
= dpyinfo
->display
->min_keycode
;
6291 max_code
= dpyinfo
->display
->max_keycode
;
6294 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6295 min_code
, max_code
- min_code
+ 1,
6297 mods
= XGetModifierMapping (dpyinfo
->display
);
6299 /* Scan the modifier table to see which modifier bits the Meta and
6300 Alt keysyms are on. */
6302 int row
, col
; /* The row and column in the modifier table. */
6304 for (row
= 3; row
< 8; row
++)
6305 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6308 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6310 /* Zeroes are used for filler. Skip them. */
6314 /* Are any of this keycode's keysyms a meta key? */
6318 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6320 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6326 dpyinfo
->meta_mod_mask
|= (1 << row
);
6331 dpyinfo
->alt_mod_mask
|= (1 << row
);
6336 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6341 dpyinfo
->super_mod_mask
|= (1 << row
);
6345 /* Ignore this if it's not on the lock modifier. */
6346 if ((1 << row
) == LockMask
)
6347 dpyinfo
->shift_lock_mask
= LockMask
;
6355 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6356 if (! dpyinfo
->meta_mod_mask
)
6358 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6359 dpyinfo
->alt_mod_mask
= 0;
6362 /* If some keys are both alt and meta,
6363 make them just meta, not alt. */
6364 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6366 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6369 XFree ((char *) syms
);
6370 XFreeModifiermap (mods
);
6373 /* Convert between the modifier bits X uses and the modifier bits
6377 x_x_to_emacs_modifiers (dpyinfo
, state
)
6378 struct x_display_info
*dpyinfo
;
6381 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6382 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6383 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6384 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6385 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6386 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6390 x_emacs_to_x_modifiers (dpyinfo
, state
)
6391 struct x_display_info
*dpyinfo
;
6394 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6395 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6396 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6397 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6398 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6399 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6402 /* Convert a keysym to its name. */
6405 x_get_keysym_name (keysym
)
6411 value
= XKeysymToString (keysym
);
6419 /* Mouse clicks and mouse movement. Rah. */
6421 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6422 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6423 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6424 not force the value into range. */
6427 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6429 register int pix_x
, pix_y
;
6430 register int *x
, *y
;
6434 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6435 even for negative values. */
6437 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6439 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6441 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6442 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6446 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6447 bounds
->height
= f
->output_data
.x
->line_height
;
6448 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6449 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6456 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6457 pix_x
= FRAME_WINDOW_WIDTH (f
);
6461 else if (pix_y
> f
->height
)
6470 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6471 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6472 can't tell the positions because W's display is not up to date,
6476 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6479 int *frame_x
, *frame_y
;
6483 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6484 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6486 if (display_completed
)
6488 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6489 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6490 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6496 *frame_x
+= glyph
->pixel_width
;
6504 *frame_y
= *frame_x
= 0;
6508 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6509 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6514 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6516 If the event is a button press, then note that we have grabbed
6520 construct_mouse_click (result
, event
, f
)
6521 struct input_event
*result
;
6522 XButtonEvent
*event
;
6525 /* Make the event type no_event; we'll change that when we decide
6527 result
->kind
= mouse_click
;
6528 result
->code
= event
->button
- Button1
;
6529 result
->timestamp
= event
->time
;
6530 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6532 | (event
->type
== ButtonRelease
6536 XSETINT (result
->x
, event
->x
);
6537 XSETINT (result
->y
, event
->y
);
6538 XSETFRAME (result
->frame_or_window
, f
);
6544 /* Function to report a mouse movement to the mainstream Emacs code.
6545 The input handler calls this.
6547 We have received a mouse movement event, which is given in *event.
6548 If the mouse is over a different glyph than it was last time, tell
6549 the mainstream emacs code by setting mouse_moved. If not, ask for
6550 another motion event, so we can check again the next time it moves. */
6552 static XMotionEvent last_mouse_motion_event
;
6553 static Lisp_Object last_mouse_motion_frame
;
6556 note_mouse_movement (frame
, event
)
6558 XMotionEvent
*event
;
6560 last_mouse_movement_time
= event
->time
;
6561 last_mouse_motion_event
= *event
;
6562 XSETFRAME (last_mouse_motion_frame
, frame
);
6564 if (event
->window
!= FRAME_X_WINDOW (frame
))
6566 frame
->mouse_moved
= 1;
6567 last_mouse_scroll_bar
= Qnil
;
6568 note_mouse_highlight (frame
, -1, -1);
6571 /* Has the mouse moved off the glyph it was on at the last sighting? */
6572 else if (event
->x
< last_mouse_glyph
.x
6573 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6574 || event
->y
< last_mouse_glyph
.y
6575 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6577 frame
->mouse_moved
= 1;
6578 last_mouse_scroll_bar
= Qnil
;
6579 note_mouse_highlight (frame
, event
->x
, event
->y
);
6583 /* This is used for debugging, to turn off note_mouse_highlight. */
6585 int disable_mouse_highlight
;
6589 /************************************************************************
6591 ************************************************************************/
6593 /* Find the glyph under window-relative coordinates X/Y in window W.
6594 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6595 strings. Return in *HPOS and *VPOS the row and column number of
6596 the glyph found. Return in *AREA the glyph area containing X.
6597 Value is a pointer to the glyph found or null if X/Y is not on
6598 text, or we can't tell because W's current matrix is not up to
6601 static struct glyph
*
6602 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6605 int *hpos
, *vpos
, *area
;
6608 struct glyph
*glyph
, *end
;
6609 struct glyph_row
*row
= NULL
;
6610 int x0
, i
, left_area_width
;
6612 /* Find row containing Y. Give up if some row is not enabled. */
6613 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6615 row
= MATRIX_ROW (w
->current_matrix
, i
);
6616 if (!row
->enabled_p
)
6618 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6625 /* Give up if Y is not in the window. */
6626 if (i
== w
->current_matrix
->nrows
)
6629 /* Get the glyph area containing X. */
6630 if (w
->pseudo_window_p
)
6637 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6638 if (x
< left_area_width
)
6640 *area
= LEFT_MARGIN_AREA
;
6643 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6646 x0
= row
->x
+ left_area_width
;
6650 *area
= RIGHT_MARGIN_AREA
;
6651 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6655 /* Find glyph containing X. */
6656 glyph
= row
->glyphs
[*area
];
6657 end
= glyph
+ row
->used
[*area
];
6660 if (x
< x0
+ glyph
->pixel_width
)
6662 if (w
->pseudo_window_p
)
6664 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6668 x0
+= glyph
->pixel_width
;
6675 *hpos
= glyph
- row
->glyphs
[*area
];
6680 /* Convert frame-relative x/y to coordinates relative to window W.
6681 Takes pseudo-windows into account. */
6684 frame_to_window_pixel_xy (w
, x
, y
)
6688 if (w
->pseudo_window_p
)
6690 /* A pseudo-window is always full-width, and starts at the
6691 left edge of the frame, plus a frame border. */
6692 struct frame
*f
= XFRAME (w
->frame
);
6693 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6694 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6698 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6699 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6704 /* Take proper action when mouse has moved to the mode or header line of
6705 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6706 mode line. X is relative to the start of the text display area of
6707 W, so the width of bitmap areas and scroll bars must be subtracted
6708 to get a position relative to the start of the mode line. */
6711 note_mode_line_highlight (w
, x
, mode_line_p
)
6715 struct frame
*f
= XFRAME (w
->frame
);
6716 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6717 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6718 struct glyph_row
*row
;
6721 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6723 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6727 struct glyph
*glyph
, *end
;
6728 Lisp_Object help
, map
;
6731 /* Find the glyph under X. */
6732 glyph
= row
->glyphs
[TEXT_AREA
];
6733 end
= glyph
+ row
->used
[TEXT_AREA
];
6734 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6735 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6738 && x
>= x0
+ glyph
->pixel_width
)
6740 x0
+= glyph
->pixel_width
;
6745 && STRINGP (glyph
->object
)
6746 && XSTRING (glyph
->object
)->intervals
6747 && glyph
->charpos
>= 0
6748 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6750 /* If we're on a string with `help-echo' text property,
6751 arrange for the help to be displayed. This is done by
6752 setting the global variable help_echo to the help string. */
6753 help
= Fget_text_property (make_number (glyph
->charpos
),
6754 Qhelp_echo
, glyph
->object
);
6758 XSETWINDOW (help_echo_window
, w
);
6759 help_echo_object
= glyph
->object
;
6760 help_echo_pos
= glyph
->charpos
;
6763 /* Change the mouse pointer according to what is under X/Y. */
6764 map
= Fget_text_property (make_number (glyph
->charpos
),
6765 Qlocal_map
, glyph
->object
);
6767 cursor
= f
->output_data
.x
->nontext_cursor
;
6770 map
= Fget_text_property (make_number (glyph
->charpos
),
6771 Qkeymap
, glyph
->object
);
6773 cursor
= f
->output_data
.x
->nontext_cursor
;
6778 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6782 /* Take proper action when the mouse has moved to position X, Y on
6783 frame F as regards highlighting characters that have mouse-face
6784 properties. Also de-highlighting chars where the mouse was before.
6785 X and Y can be negative or out of range. */
6788 note_mouse_highlight (f
, x
, y
)
6792 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6796 Cursor cursor
= None
;
6799 /* When a menu is active, don't highlight because this looks odd. */
6800 #ifdef USE_X_TOOLKIT
6801 if (popup_activated ())
6805 if (disable_mouse_highlight
6806 || !f
->glyphs_initialized_p
)
6809 dpyinfo
->mouse_face_mouse_x
= x
;
6810 dpyinfo
->mouse_face_mouse_y
= y
;
6811 dpyinfo
->mouse_face_mouse_frame
= f
;
6813 if (dpyinfo
->mouse_face_defer
)
6818 dpyinfo
->mouse_face_deferred_gc
= 1;
6822 /* Which window is that in? */
6823 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6825 /* If we were displaying active text in another window, clear that. */
6826 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6827 clear_mouse_face (dpyinfo
);
6829 /* Not on a window -> return. */
6830 if (!WINDOWP (window
))
6833 /* Convert to window-relative pixel coordinates. */
6834 w
= XWINDOW (window
);
6835 frame_to_window_pixel_xy (w
, &x
, &y
);
6837 /* Handle tool-bar window differently since it doesn't display a
6839 if (EQ (window
, f
->tool_bar_window
))
6841 note_tool_bar_highlight (f
, x
, y
);
6845 /* Mouse is on the mode or header line? */
6846 if (portion
== 1 || portion
== 3)
6848 note_mode_line_highlight (w
, x
, portion
== 1);
6853 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6855 cursor
= f
->output_data
.x
->text_cursor
;
6857 /* Are we in a window whose display is up to date?
6858 And verify the buffer's text has not changed. */
6859 b
= XBUFFER (w
->buffer
);
6860 if (/* Within text portion of the window. */
6862 && EQ (w
->window_end_valid
, w
->buffer
)
6863 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6864 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6866 int hpos
, vpos
, pos
, i
, area
;
6867 struct glyph
*glyph
;
6869 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6870 Lisp_Object
*overlay_vec
= NULL
;
6872 struct buffer
*obuf
;
6873 int obegv
, ozv
, same_region
;
6875 /* Find the glyph under X/Y. */
6876 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6878 /* Clear mouse face if X/Y not over text. */
6880 || area
!= TEXT_AREA
6881 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6883 clear_mouse_face (dpyinfo
);
6887 pos
= glyph
->charpos
;
6888 object
= glyph
->object
;
6889 if (!STRINGP (object
) && !BUFFERP (object
))
6892 /* If we get an out-of-range value, return now; avoid an error. */
6893 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6896 /* Make the window's buffer temporarily current for
6897 overlays_at and compute_char_face. */
6898 obuf
= current_buffer
;
6905 /* Is this char mouse-active or does it have help-echo? */
6906 position
= make_number (pos
);
6908 if (BUFFERP (object
))
6910 /* Put all the overlays we want in a vector in overlay_vec.
6911 Store the length in len. If there are more than 10, make
6912 enough space for all, and try again. */
6914 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6915 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6916 if (noverlays
> len
)
6919 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6920 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6923 /* Sort overlays into increasing priority order. */
6924 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6929 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6930 && vpos
>= dpyinfo
->mouse_face_beg_row
6931 && vpos
<= dpyinfo
->mouse_face_end_row
6932 && (vpos
> dpyinfo
->mouse_face_beg_row
6933 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6934 && (vpos
< dpyinfo
->mouse_face_end_row
6935 || hpos
< dpyinfo
->mouse_face_end_col
6936 || dpyinfo
->mouse_face_past_end
));
6941 /* Check mouse-face highlighting. */
6943 /* If there exists an overlay with mouse-face overlapping
6944 the one we are currently highlighting, we have to
6945 check if we enter the overlapping overlay, and then
6946 highlight only that. */
6947 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6948 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6950 /* Clear the display of the old active region, if any. */
6951 clear_mouse_face (dpyinfo
);
6954 /* Find the highest priority overlay that has a mouse-face
6957 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6959 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6960 if (!NILP (mouse_face
))
6961 overlay
= overlay_vec
[i
];
6963 dpyinfo
->mouse_face_overlay
= overlay
;
6965 /* If no overlay applies, get a text property. */
6967 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6969 /* Handle the overlay case. */
6970 if (!NILP (overlay
))
6972 /* Find the range of text around this char that
6973 should be active. */
6974 Lisp_Object before
, after
;
6977 before
= Foverlay_start (overlay
);
6978 after
= Foverlay_end (overlay
);
6979 /* Record this as the current active region. */
6980 fast_find_position (w
, XFASTINT (before
),
6981 &dpyinfo
->mouse_face_beg_col
,
6982 &dpyinfo
->mouse_face_beg_row
,
6983 &dpyinfo
->mouse_face_beg_x
,
6984 &dpyinfo
->mouse_face_beg_y
);
6985 dpyinfo
->mouse_face_past_end
6986 = !fast_find_position (w
, XFASTINT (after
),
6987 &dpyinfo
->mouse_face_end_col
,
6988 &dpyinfo
->mouse_face_end_row
,
6989 &dpyinfo
->mouse_face_end_x
,
6990 &dpyinfo
->mouse_face_end_y
);
6991 dpyinfo
->mouse_face_window
= window
;
6992 dpyinfo
->mouse_face_face_id
6993 = face_at_buffer_position (w
, pos
, 0, 0,
6994 &ignore
, pos
+ 1, 1);
6996 /* Display it as active. */
6997 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6999 /* Handle the text property case. */
7000 else if (!NILP (mouse_face
) && BUFFERP (object
))
7002 /* Find the range of text around this char that
7003 should be active. */
7004 Lisp_Object before
, after
, beginning
, end
;
7007 beginning
= Fmarker_position (w
->start
);
7008 end
= make_number (BUF_Z (XBUFFER (object
))
7009 - XFASTINT (w
->window_end_pos
));
7011 = Fprevious_single_property_change (make_number (pos
+ 1),
7015 = Fnext_single_property_change (position
, Qmouse_face
,
7018 /* Record this as the current active region. */
7019 fast_find_position (w
, XFASTINT (before
),
7020 &dpyinfo
->mouse_face_beg_col
,
7021 &dpyinfo
->mouse_face_beg_row
,
7022 &dpyinfo
->mouse_face_beg_x
,
7023 &dpyinfo
->mouse_face_beg_y
);
7024 dpyinfo
->mouse_face_past_end
7025 = !fast_find_position (w
, XFASTINT (after
),
7026 &dpyinfo
->mouse_face_end_col
,
7027 &dpyinfo
->mouse_face_end_row
,
7028 &dpyinfo
->mouse_face_end_x
,
7029 &dpyinfo
->mouse_face_end_y
);
7030 dpyinfo
->mouse_face_window
= window
;
7032 if (BUFFERP (object
))
7033 dpyinfo
->mouse_face_face_id
7034 = face_at_buffer_position (w
, pos
, 0, 0,
7035 &ignore
, pos
+ 1, 1);
7037 /* Display it as active. */
7038 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7040 else if (!NILP (mouse_face
) && STRINGP (object
))
7045 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7048 e
= Fnext_single_property_change (position
, Qmouse_face
,
7051 b
= make_number (0);
7053 e
= make_number (XSTRING (object
)->size
- 1);
7054 fast_find_string_pos (w
, XINT (b
), object
,
7055 &dpyinfo
->mouse_face_beg_col
,
7056 &dpyinfo
->mouse_face_beg_row
,
7057 &dpyinfo
->mouse_face_beg_x
,
7058 &dpyinfo
->mouse_face_beg_y
, 0);
7059 fast_find_string_pos (w
, XINT (e
), object
,
7060 &dpyinfo
->mouse_face_end_col
,
7061 &dpyinfo
->mouse_face_end_row
,
7062 &dpyinfo
->mouse_face_end_x
,
7063 &dpyinfo
->mouse_face_end_y
, 1);
7064 dpyinfo
->mouse_face_past_end
= 0;
7065 dpyinfo
->mouse_face_window
= window
;
7066 dpyinfo
->mouse_face_face_id
7067 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7069 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7073 /* Look for a `help-echo' property. */
7075 Lisp_Object help
, overlay
;
7077 /* Check overlays first. */
7078 help
= overlay
= Qnil
;
7079 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7081 overlay
= overlay_vec
[i
];
7082 help
= Foverlay_get (overlay
, Qhelp_echo
);
7088 help_echo_window
= window
;
7089 help_echo_object
= overlay
;
7090 help_echo_pos
= pos
;
7094 Lisp_Object object
= glyph
->object
;
7095 int charpos
= glyph
->charpos
;
7097 /* Try text properties. */
7098 if (STRINGP (object
)
7100 && charpos
< XSTRING (object
)->size
)
7102 help
= Fget_text_property (make_number (charpos
),
7103 Qhelp_echo
, object
);
7106 /* If the string itself doesn't specify a help-echo,
7107 see if the buffer text ``under'' it does. */
7109 = MATRIX_ROW (w
->current_matrix
, vpos
);
7110 int start
= MATRIX_ROW_START_CHARPOS (r
);
7111 int pos
= string_buffer_position (w
, object
, start
);
7114 help
= Fget_text_property (make_number (pos
),
7115 Qhelp_echo
, w
->buffer
);
7124 else if (BUFFERP (object
)
7127 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7133 help_echo_window
= window
;
7134 help_echo_object
= object
;
7135 help_echo_pos
= charpos
;
7142 current_buffer
= obuf
;
7146 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7150 redo_mouse_highlight ()
7152 if (!NILP (last_mouse_motion_frame
)
7153 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7154 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7155 last_mouse_motion_event
.x
,
7156 last_mouse_motion_event
.y
);
7161 /***********************************************************************
7163 ***********************************************************************/
7165 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7166 struct glyph
**, int *, int *, int *));
7168 /* Tool-bar item index of the item on which a mouse button was pressed
7171 static int last_tool_bar_item
;
7174 /* Get information about the tool-bar item at position X/Y on frame F.
7175 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7176 the current matrix of the tool-bar window of F, or NULL if not
7177 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7178 item in F->tool_bar_items. Value is
7180 -1 if X/Y is not on a tool-bar item
7181 0 if X/Y is on the same item that was highlighted before.
7185 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7188 struct glyph
**glyph
;
7189 int *hpos
, *vpos
, *prop_idx
;
7191 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7192 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7195 /* Find the glyph under X/Y. */
7196 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7200 /* Get the start of this tool-bar item's properties in
7201 f->tool_bar_items. */
7202 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7205 /* Is mouse on the highlighted item? */
7206 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7207 && *vpos
>= dpyinfo
->mouse_face_beg_row
7208 && *vpos
<= dpyinfo
->mouse_face_end_row
7209 && (*vpos
> dpyinfo
->mouse_face_beg_row
7210 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7211 && (*vpos
< dpyinfo
->mouse_face_end_row
7212 || *hpos
< dpyinfo
->mouse_face_end_col
7213 || dpyinfo
->mouse_face_past_end
))
7220 /* Handle mouse button event on the tool-bar of frame F, at
7221 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7225 x_handle_tool_bar_click (f
, button_event
)
7227 XButtonEvent
*button_event
;
7229 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7230 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7231 int hpos
, vpos
, prop_idx
;
7232 struct glyph
*glyph
;
7233 Lisp_Object enabled_p
;
7234 int x
= button_event
->x
;
7235 int y
= button_event
->y
;
7237 /* If not on the highlighted tool-bar item, return. */
7238 frame_to_window_pixel_xy (w
, &x
, &y
);
7239 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7242 /* If item is disabled, do nothing. */
7243 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7244 if (NILP (enabled_p
))
7247 if (button_event
->type
== ButtonPress
)
7249 /* Show item in pressed state. */
7250 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7251 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7252 last_tool_bar_item
= prop_idx
;
7256 Lisp_Object key
, frame
;
7257 struct input_event event
;
7259 /* Show item in released state. */
7260 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7261 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7263 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7265 XSETFRAME (frame
, f
);
7266 event
.kind
= TOOL_BAR_EVENT
;
7267 event
.frame_or_window
= frame
;
7269 kbd_buffer_store_event (&event
);
7271 event
.kind
= TOOL_BAR_EVENT
;
7272 event
.frame_or_window
= frame
;
7274 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7275 button_event
->state
);
7276 kbd_buffer_store_event (&event
);
7277 last_tool_bar_item
= -1;
7282 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7283 tool-bar window-relative coordinates X/Y. Called from
7284 note_mouse_highlight. */
7287 note_tool_bar_highlight (f
, x
, y
)
7291 Lisp_Object window
= f
->tool_bar_window
;
7292 struct window
*w
= XWINDOW (window
);
7293 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7295 struct glyph
*glyph
;
7296 struct glyph_row
*row
;
7298 Lisp_Object enabled_p
;
7300 enum draw_glyphs_face draw
;
7301 int mouse_down_p
, rc
;
7303 /* Function note_mouse_highlight is called with negative x(y
7304 values when mouse moves outside of the frame. */
7305 if (x
<= 0 || y
<= 0)
7307 clear_mouse_face (dpyinfo
);
7311 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7314 /* Not on tool-bar item. */
7315 clear_mouse_face (dpyinfo
);
7321 clear_mouse_face (dpyinfo
);
7323 /* Mouse is down, but on different tool-bar item? */
7324 mouse_down_p
= (dpyinfo
->grabbed
7325 && f
== last_mouse_frame
7326 && FRAME_LIVE_P (f
));
7328 && last_tool_bar_item
!= prop_idx
)
7331 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7332 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7334 /* If tool-bar item is not enabled, don't highlight it. */
7335 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7336 if (!NILP (enabled_p
))
7338 /* Compute the x-position of the glyph. In front and past the
7339 image is a space. We include this is the highlighted area. */
7340 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7341 for (i
= x
= 0; i
< hpos
; ++i
)
7342 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7344 /* Record this as the current active region. */
7345 dpyinfo
->mouse_face_beg_col
= hpos
;
7346 dpyinfo
->mouse_face_beg_row
= vpos
;
7347 dpyinfo
->mouse_face_beg_x
= x
;
7348 dpyinfo
->mouse_face_beg_y
= row
->y
;
7349 dpyinfo
->mouse_face_past_end
= 0;
7351 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7352 dpyinfo
->mouse_face_end_row
= vpos
;
7353 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7354 dpyinfo
->mouse_face_end_y
= row
->y
;
7355 dpyinfo
->mouse_face_window
= window
;
7356 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7358 /* Display it as active. */
7359 show_mouse_face (dpyinfo
, draw
);
7360 dpyinfo
->mouse_face_image_state
= draw
;
7365 /* Set help_echo to a help string.to display for this tool-bar item.
7366 XTread_socket does the rest. */
7367 help_echo_object
= help_echo_window
= Qnil
;
7369 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7370 if (NILP (help_echo
))
7371 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7376 /* Find the glyph matrix position of buffer position POS in window W.
7377 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7378 current glyphs must be up to date. If POS is above window start
7379 return (0, 0, 0, 0). If POS is after end of W, return end of
7383 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
7386 int *hpos
, *vpos
, *x
, *y
;
7390 int maybe_next_line_p
= 0;
7391 int line_start_position
;
7392 int yb
= window_text_bottom_y (w
);
7393 struct glyph_row
*row
, *best_row
;
7394 int row_vpos
, best_row_vpos
;
7397 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7398 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7402 if (row
->used
[TEXT_AREA
])
7403 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7405 line_start_position
= 0;
7407 if (line_start_position
> pos
)
7409 /* If the position sought is the end of the buffer,
7410 don't include the blank lines at the bottom of the window. */
7411 else if (line_start_position
== pos
7412 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7414 maybe_next_line_p
= 1;
7417 else if (line_start_position
> 0)
7420 best_row_vpos
= row_vpos
;
7423 if (row
->y
+ row
->height
>= yb
)
7430 /* Find the right column within BEST_ROW. */
7432 current_x
= best_row
->x
;
7433 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7435 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7438 charpos
= glyph
->charpos
;
7442 *vpos
= best_row_vpos
;
7447 else if (charpos
> pos
)
7449 else if (charpos
> 0)
7452 current_x
+= glyph
->pixel_width
;
7455 /* If we're looking for the end of the buffer,
7456 and we didn't find it in the line we scanned,
7457 use the start of the following line. */
7458 if (maybe_next_line_p
)
7463 current_x
= best_row
->x
;
7466 *vpos
= best_row_vpos
;
7467 *hpos
= lastcol
+ 1;
7474 /* Find the position of the the glyph for position POS in OBJECT in
7475 window W's current matrix, and return in *X/*Y the pixel
7476 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7478 RIGHT_P non-zero means return the position of the right edge of the
7479 glyph, RIGHT_P zero means return the left edge position.
7481 If no glyph for POS exists in the matrix, return the position of
7482 the glyph with the next smaller position that is in the matrix, if
7483 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7484 exists in the matrix, return the position of the glyph with the
7485 next larger position in OBJECT.
7487 Value is non-zero if a glyph was found. */
7490 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7494 int *hpos
, *vpos
, *x
, *y
;
7497 int yb
= window_text_bottom_y (w
);
7498 struct glyph_row
*r
;
7499 struct glyph
*best_glyph
= NULL
;
7500 struct glyph_row
*best_row
= NULL
;
7503 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7504 r
->enabled_p
&& r
->y
< yb
;
7507 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7508 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7511 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7512 if (EQ (g
->object
, object
))
7514 if (g
->charpos
== pos
)
7521 else if (best_glyph
== NULL
7522 || ((abs (g
->charpos
- pos
)
7523 < abs (best_glyph
->charpos
- pos
))
7526 : g
->charpos
> pos
)))
7540 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7544 *x
+= best_glyph
->pixel_width
;
7549 *vpos
= best_row
- w
->current_matrix
->rows
;
7552 return best_glyph
!= NULL
;
7556 /* Display the active region described by mouse_face_*
7557 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7560 show_mouse_face (dpyinfo
, draw
)
7561 struct x_display_info
*dpyinfo
;
7562 enum draw_glyphs_face draw
;
7564 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7565 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7567 int cursor_off_p
= 0;
7568 struct cursor_pos saved_cursor
;
7570 saved_cursor
= output_cursor
;
7572 /* If window is in the process of being destroyed, don't bother
7574 if (w
->current_matrix
== NULL
)
7577 /* Recognize when we are called to operate on rows that don't exist
7578 anymore. This can happen when a window is split. */
7579 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7582 set_output_cursor (&w
->phys_cursor
);
7584 /* Note that mouse_face_beg_row etc. are window relative. */
7585 for (i
= dpyinfo
->mouse_face_beg_row
;
7586 i
<= dpyinfo
->mouse_face_end_row
;
7589 int start_hpos
, end_hpos
, start_x
;
7590 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7592 /* Don't do anything if row doesn't have valid contents. */
7593 if (!row
->enabled_p
)
7596 /* For all but the first row, the highlight starts at column 0. */
7597 if (i
== dpyinfo
->mouse_face_beg_row
)
7599 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7600 start_x
= dpyinfo
->mouse_face_beg_x
;
7608 if (i
== dpyinfo
->mouse_face_end_row
)
7609 end_hpos
= dpyinfo
->mouse_face_end_col
;
7611 end_hpos
= row
->used
[TEXT_AREA
];
7613 /* If the cursor's in the text we are about to rewrite, turn the
7615 if (!w
->pseudo_window_p
7616 && i
== output_cursor
.vpos
7617 && output_cursor
.hpos
>= start_hpos
- 1
7618 && output_cursor
.hpos
<= end_hpos
)
7620 x_update_window_cursor (w
, 0);
7624 if (end_hpos
> start_hpos
)
7626 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7627 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7628 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7632 /* If we turned the cursor off, turn it back on. */
7634 x_display_cursor (w
, 1,
7635 output_cursor
.hpos
, output_cursor
.vpos
,
7636 output_cursor
.x
, output_cursor
.y
);
7638 output_cursor
= saved_cursor
;
7642 /* Change the mouse cursor. */
7643 if (draw
== DRAW_NORMAL_TEXT
)
7644 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7645 f
->output_data
.x
->text_cursor
);
7646 else if (draw
== DRAW_MOUSE_FACE
)
7647 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7648 f
->output_data
.x
->cross_cursor
);
7650 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7651 f
->output_data
.x
->nontext_cursor
);
7654 /* Clear out the mouse-highlighted active region.
7655 Redraw it un-highlighted first. */
7658 clear_mouse_face (dpyinfo
)
7659 struct x_display_info
*dpyinfo
;
7661 #if 0 /* This prevents redrawing tool bar items when changing from one
7662 to another while a tooltip is open, so don't do it. */
7663 if (!NILP (tip_frame
))
7667 if (! NILP (dpyinfo
->mouse_face_window
))
7668 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7670 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7671 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7672 dpyinfo
->mouse_face_window
= Qnil
;
7676 /* Clear any mouse-face on window W. This function is part of the
7677 redisplay interface, and is called from try_window_id and similar
7678 functions to ensure the mouse-highlight is off. */
7681 x_clear_mouse_face (w
)
7684 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7688 XSETWINDOW (window
, w
);
7689 if (EQ (window
, dpyinfo
->mouse_face_window
))
7690 clear_mouse_face (dpyinfo
);
7695 /* Just discard the mouse face information for frame F, if any.
7696 This is used when the size of F is changed. */
7699 cancel_mouse_face (f
)
7703 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7705 window
= dpyinfo
->mouse_face_window
;
7706 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7708 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7709 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7710 dpyinfo
->mouse_face_window
= Qnil
;
7715 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
7718 /* Try to determine frame pixel position and size of the glyph under
7719 frame pixel coordinates X/Y on frame F . Return the position and
7720 size in *RECT. Value is non-zero if we could compute these
7724 glyph_rect (f
, x
, y
, rect
)
7730 int part
, found
= 0;
7732 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7735 struct window
*w
= XWINDOW (window
);
7736 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7737 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7740 frame_to_window_pixel_xy (w
, &x
, &y
);
7742 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7745 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7746 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7749 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7752 rect
->width
= g
->pixel_width
;
7753 rect
->height
= r
->height
;
7754 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7755 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7765 /* Return the current position of the mouse.
7766 *FP should be a frame which indicates which display to ask about.
7768 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
7769 and *PART to the frame, window, and scroll bar part that the mouse
7770 is over. Set *X and *Y to the portion and whole of the mouse's
7771 position on the scroll bar.
7773 If the mouse movement started elsewhere, set *FP to the frame the
7774 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
7777 Set *TIME to the server time-stamp for the time at which the mouse
7778 was at this position.
7780 Don't store anything if we don't have a valid set of values to report.
7782 This clears the mouse_moved flag, so we can wait for the next mouse
7786 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7789 Lisp_Object
*bar_window
;
7790 enum scroll_bar_part
*part
;
7792 unsigned long *time
;
7798 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7799 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7805 Window dummy_window
;
7808 Lisp_Object frame
, tail
;
7810 /* Clear the mouse-moved flag for every frame on this display. */
7811 FOR_EACH_FRAME (tail
, frame
)
7812 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7813 XFRAME (frame
)->mouse_moved
= 0;
7815 last_mouse_scroll_bar
= Qnil
;
7817 /* Figure out which root window we're on. */
7818 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7819 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7821 /* The root window which contains the pointer. */
7824 /* Trash which we can't trust if the pointer is on
7825 a different screen. */
7828 /* The position on that root window. */
7831 /* More trash we can't trust. */
7834 /* Modifier keys and pointer buttons, about which
7836 (unsigned int *) &dummy
);
7838 /* Now we have a position on the root; find the innermost window
7839 containing the pointer. */
7843 int parent_x
= 0, parent_y
= 0;
7848 /* XTranslateCoordinates can get errors if the window
7849 structure is changing at the same time this function
7850 is running. So at least we must not crash from them. */
7852 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
7854 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7855 && FRAME_LIVE_P (last_mouse_frame
))
7857 /* If mouse was grabbed on a frame, give coords for that frame
7858 even if the mouse is now outside it. */
7859 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7861 /* From-window, to-window. */
7862 root
, FRAME_X_WINDOW (last_mouse_frame
),
7864 /* From-position, to-position. */
7865 root_x
, root_y
, &win_x
, &win_y
,
7869 f1
= last_mouse_frame
;
7875 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
7877 /* From-window, to-window. */
7880 /* From-position, to-position. */
7881 root_x
, root_y
, &win_x
, &win_y
,
7886 if (child
== None
|| child
== win
)
7894 /* Now we know that:
7895 win is the innermost window containing the pointer
7896 (XTC says it has no child containing the pointer),
7897 win_x and win_y are the pointer's position in it
7898 (XTC did this the last time through), and
7899 parent_x and parent_y are the pointer's position in win's parent.
7900 (They are what win_x and win_y were when win was child.
7901 If win is the root window, it has no parent, and
7902 parent_{x,y} are invalid, but that's okay, because we'll
7903 never use them in that case.) */
7905 /* Is win one of our frames? */
7906 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
7908 #ifdef USE_X_TOOLKIT
7909 /* If we end up with the menu bar window, say it's not
7912 && f1
->output_data
.x
->menubar_widget
7913 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
7915 #endif /* USE_X_TOOLKIT */
7918 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
7921 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
7923 /* If not, is it one of our scroll bars? */
7926 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
7930 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7936 if (f1
== 0 && insist
> 0)
7937 f1
= SELECTED_FRAME ();
7941 /* Ok, we found a frame. Store all the values.
7942 last_mouse_glyph is a rectangle used to reduce the
7943 generation of mouse events. To not miss any motion
7944 events, we must divide the frame into rectangles of the
7945 size of the smallest character that could be displayed
7946 on it, i.e. into the same rectangles that matrices on
7947 the frame are divided into. */
7949 int width
, height
, gx
, gy
;
7952 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
7953 last_mouse_glyph
= rect
;
7956 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7957 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7961 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7962 round down even for negative values. */
7967 gx
= (gx
+ width
- 1) / width
* width
;
7968 gy
= (gy
+ height
- 1) / height
* height
;
7970 last_mouse_glyph
.width
= width
;
7971 last_mouse_glyph
.height
= height
;
7972 last_mouse_glyph
.x
= gx
;
7973 last_mouse_glyph
.y
= gy
;
7979 XSETINT (*x
, win_x
);
7980 XSETINT (*y
, win_y
);
7981 *time
= last_mouse_movement_time
;
7990 #ifdef USE_X_TOOLKIT
7992 /* Atimer callback function for TIMER. Called every 0.1s to process
7993 Xt timeouts, if needed. We must avoid calling XtAppPending as
7994 much as possible because that function does an implicit XFlush
7995 that slows us down. */
7998 x_process_timeouts (timer
)
7999 struct atimer
*timer
;
8001 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
8004 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
8005 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
8010 #endif /* USE_X_TOOLKIT */
8013 /* Scroll bar support. */
8015 /* Given an X window ID, find the struct scroll_bar which manages it.
8016 This can be called in GC, so we have to make sure to strip off mark
8019 static struct scroll_bar
*
8020 x_window_to_scroll_bar (window_id
)
8025 for (tail
= Vframe_list
;
8026 XGCTYPE (tail
) == Lisp_Cons
;
8029 Lisp_Object frame
, bar
, condemned
;
8031 frame
= XCAR (tail
);
8032 /* All elements of Vframe_list should be frames. */
8033 if (! GC_FRAMEP (frame
))
8036 /* Scan this frame's scroll bar list for a scroll bar with the
8038 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
8039 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
8040 /* This trick allows us to search both the ordinary and
8041 condemned scroll bar lists with one loop. */
8042 ! GC_NILP (bar
) || (bar
= condemned
,
8045 bar
= XSCROLL_BAR (bar
)->next
)
8046 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
8047 return XSCROLL_BAR (bar
);
8054 #if defined USE_X_TOOLKIT && defined USE_LUCID
8056 /* Return the Lucid menu bar WINDOW is part of. Return null
8057 if WINDOW is not part of a menu bar. */
8060 x_window_to_menu_bar (window
)
8065 for (tail
= Vframe_list
;
8066 XGCTYPE (tail
) == Lisp_Cons
;
8069 Lisp_Object frame
= XCAR (tail
);
8070 Widget menu_bar
= XFRAME (frame
)->output_data
.x
->menubar_widget
;
8072 if (menu_bar
&& xlwmenu_window_p (menu_bar
, window
))
8079 #endif /* USE_X_TOOLKIT && USE_LUCID */
8082 /************************************************************************
8084 ************************************************************************/
8086 #ifdef USE_TOOLKIT_SCROLL_BARS
8088 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
8089 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
8090 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
8091 struct scroll_bar
*));
8092 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
8096 /* Id of action hook installed for scroll bars. */
8098 static XtActionHookId action_hook_id
;
8100 /* Lisp window being scrolled. Set when starting to interact with
8101 a toolkit scroll bar, reset to nil when ending the interaction. */
8103 static Lisp_Object window_being_scrolled
;
8105 /* Last scroll bar part sent in xm_scroll_callback. */
8107 static int last_scroll_bar_part
;
8109 /* Whether this is an Xaw with arrow-scrollbars. This should imply
8110 that movements of 1/20 of the screen size are mapped to up/down. */
8112 static Boolean xaw3d_arrow_scroll
;
8114 /* Whether the drag scrolling maintains the mouse at the top of the
8115 thumb. If not, resizing the thumb needs to be done more carefully
8116 to avoid jerkyness. */
8118 static Boolean xaw3d_pick_top
;
8121 /* Action hook installed via XtAppAddActionHook when toolkit scroll
8122 bars are used.. The hook is responsible for detecting when
8123 the user ends an interaction with the scroll bar, and generates
8124 a `end-scroll' scroll_bar_click' event if so. */
8127 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
8130 XtPointer client_data
;
8134 Cardinal
*num_params
;
8140 scroll_bar_p
= XmIsScrollBar (widget
);
8141 end_action
= "Release";
8142 #else /* !USE_MOTIF i.e. use Xaw */
8143 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
8144 end_action
= "EndScroll";
8145 #endif /* USE_MOTIF */
8148 && strcmp (action_name
, end_action
) == 0
8149 && WINDOWP (window_being_scrolled
))
8153 x_send_scroll_bar_event (window_being_scrolled
,
8154 scroll_bar_end_scroll
, 0, 0);
8155 w
= XWINDOW (window_being_scrolled
);
8156 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
8157 window_being_scrolled
= Qnil
;
8158 last_scroll_bar_part
= -1;
8160 /* Xt timeouts no longer needed. */
8161 toolkit_scroll_bar_interaction
= 0;
8165 /* A vector of windows used for communication between
8166 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
8168 static struct window
**scroll_bar_windows
;
8169 static int scroll_bar_windows_size
;
8172 /* Send a client message with message type Xatom_Scrollbar for a
8173 scroll action to the frame of WINDOW. PART is a value identifying
8174 the part of the scroll bar that was clicked on. PORTION is the
8175 amount to scroll of a whole of WHOLE. */
8178 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8180 int part
, portion
, whole
;
8183 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8184 struct window
*w
= XWINDOW (window
);
8185 struct frame
*f
= XFRAME (w
->frame
);
8190 /* Construct a ClientMessage event to send to the frame. */
8191 ev
->type
= ClientMessage
;
8192 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8193 ev
->display
= FRAME_X_DISPLAY (f
);
8194 ev
->window
= FRAME_X_WINDOW (f
);
8197 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8198 not enough to store a pointer or Lisp_Object on a 64 bit system.
8199 So, store the window in scroll_bar_windows and pass the index
8200 into that array in the event. */
8201 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8202 if (scroll_bar_windows
[i
] == NULL
)
8205 if (i
== scroll_bar_windows_size
)
8207 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8208 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8209 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8211 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8213 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8214 scroll_bar_windows_size
= new_size
;
8217 scroll_bar_windows
[i
] = w
;
8218 ev
->data
.l
[0] = (long) i
;
8219 ev
->data
.l
[1] = (long) part
;
8220 ev
->data
.l
[2] = (long) 0;
8221 ev
->data
.l
[3] = (long) portion
;
8222 ev
->data
.l
[4] = (long) whole
;
8224 /* Make Xt timeouts work while the scroll bar is active. */
8225 toolkit_scroll_bar_interaction
= 1;
8227 /* Setting the event mask to zero means that the message will
8228 be sent to the client that created the window, and if that
8229 window no longer exists, no event will be sent. */
8230 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8235 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8239 x_scroll_bar_to_input_event (event
, ievent
)
8241 struct input_event
*ievent
;
8243 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8248 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8249 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8251 XSETWINDOW (window
, w
);
8252 f
= XFRAME (w
->frame
);
8254 ievent
->kind
= scroll_bar_click
;
8255 ievent
->frame_or_window
= window
;
8257 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8258 ievent
->part
= ev
->data
.l
[1];
8259 ievent
->code
= ev
->data
.l
[2];
8260 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8261 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8262 ievent
->modifiers
= 0;
8268 /* Minimum and maximum values used for Motif scroll bars. */
8271 #define XM_SB_MAX 10000000
8272 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8275 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8276 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8277 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
8280 xm_scroll_callback (widget
, client_data
, call_data
)
8282 XtPointer client_data
, call_data
;
8284 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8285 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8287 int part
= -1, whole
= 0, portion
= 0;
8291 case XmCR_DECREMENT
:
8292 bar
->dragging
= Qnil
;
8293 part
= scroll_bar_up_arrow
;
8296 case XmCR_INCREMENT
:
8297 bar
->dragging
= Qnil
;
8298 part
= scroll_bar_down_arrow
;
8301 case XmCR_PAGE_DECREMENT
:
8302 bar
->dragging
= Qnil
;
8303 part
= scroll_bar_above_handle
;
8306 case XmCR_PAGE_INCREMENT
:
8307 bar
->dragging
= Qnil
;
8308 part
= scroll_bar_below_handle
;
8312 bar
->dragging
= Qnil
;
8313 part
= scroll_bar_to_top
;
8316 case XmCR_TO_BOTTOM
:
8317 bar
->dragging
= Qnil
;
8318 part
= scroll_bar_to_bottom
;
8324 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8325 && XINT (bar
->dragging
) <= cs
->value
);
8327 /* Get the slider size. */
8329 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8332 /* At the max position of the scroll bar, do a line-wise
8333 movement. Without doing anything, we would be called with
8334 the same cs->value again and again. If we want to make
8335 sure that we can reach the end of the buffer, we have to do
8338 Implementation note: setting bar->dragging always to
8339 cs->value gives a smoother movement at the max position.
8340 Setting it to nil when doing line-wise movement gives
8341 a better slider behavior. */
8343 if (cs
->value
+ slider_size
== XM_SB_MAX
8345 && last_scroll_bar_part
== scroll_bar_down_arrow
))
8347 part
= scroll_bar_down_arrow
;
8348 bar
->dragging
= Qnil
;
8352 whole
= XM_SB_RANGE
;
8353 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
8354 part
= scroll_bar_handle
;
8355 bar
->dragging
= make_number (cs
->value
);
8360 case XmCR_VALUE_CHANGED
:
8366 window_being_scrolled
= bar
->window
;
8367 last_scroll_bar_part
= part
;
8368 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8373 #else /* !USE_MOTIF, i.e. Xaw. */
8376 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8377 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8378 scroll bar struct. CALL_DATA is a pointer to a float saying where
8382 xaw_jump_callback (widget
, client_data
, call_data
)
8384 XtPointer client_data
, call_data
;
8386 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8387 float top
= *(float *) call_data
;
8389 int whole
, portion
, height
;
8392 /* Get the size of the thumb, a value between 0 and 1. */
8394 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8398 portion
= shown
< 1 ? top
* whole
: 0;
8400 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8401 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8402 the bottom, so we force the scrolling whenever we see that we're
8403 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8404 we try to ensure that we always stay two pixels away from the
8406 part
= scroll_bar_down_arrow
;
8408 part
= scroll_bar_handle
;
8410 window_being_scrolled
= bar
->window
;
8411 bar
->dragging
= make_number (portion
);
8412 last_scroll_bar_part
= part
;
8413 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8417 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8418 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8419 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8420 the scroll bar. CALL_DATA is an integer specifying the action that
8421 has taken place. It's magnitude is in the range 0..height of the
8422 scroll bar. Negative values mean scroll towards buffer start.
8423 Values < height of scroll bar mean line-wise movement. */
8426 xaw_scroll_callback (widget
, client_data
, call_data
)
8428 XtPointer client_data
, call_data
;
8430 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8431 int position
= (int) call_data
;
8435 /* Get the height of the scroll bar. */
8437 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8440 if (abs (position
) >= height
)
8441 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8443 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8444 it maps line-movement to call_data = max(5, height/20). */
8445 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8446 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8448 part
= scroll_bar_move_ratio
;
8450 window_being_scrolled
= bar
->window
;
8451 bar
->dragging
= Qnil
;
8452 last_scroll_bar_part
= part
;
8453 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8457 #endif /* not USE_MOTIF */
8460 /* Create the widget for scroll bar BAR on frame F. Record the widget
8461 and X window of the scroll bar in BAR. */
8464 x_create_toolkit_scroll_bar (f
, bar
)
8466 struct scroll_bar
*bar
;
8472 char *scroll_bar_name
= "verticalScrollBar";
8473 unsigned long pixel
;
8478 /* Set resources. Create the widget. */
8479 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8480 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8481 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8482 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8483 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8484 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8485 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8487 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8490 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8494 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8497 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8501 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8502 scroll_bar_name
, av
, ac
);
8504 /* Add one callback for everything that can happen. */
8505 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8507 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8509 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8511 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8513 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8515 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8517 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8520 /* Realize the widget. Only after that is the X window created. */
8521 XtRealizeWidget (widget
);
8523 /* Set the cursor to an arrow. I didn't find a resource to do that.
8524 And I'm wondering why it hasn't an arrow cursor by default. */
8525 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8526 f
->output_data
.x
->nontext_cursor
);
8528 #else /* !USE_MOTIF i.e. use Xaw */
8530 /* Set resources. Create the widget. The background of the
8531 Xaw3d scroll bar widget is a little bit light for my taste.
8532 We don't alter it here to let users change it according
8533 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8534 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8535 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8536 /* For smoother scrolling with Xaw3d -sm */
8537 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8538 /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
8540 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8543 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8547 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8550 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8554 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8555 f
->output_data
.x
->edit_widget
, av
, ac
);
8559 char *val
= initial
;
8560 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8561 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8563 { /* ARROW_SCROLL */
8564 xaw3d_arrow_scroll
= True
;
8565 /* Isn't that just a personal preference ? -sm */
8566 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8570 /* Define callbacks. */
8571 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8572 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8575 /* Realize the widget. Only after that is the X window created. */
8576 XtRealizeWidget (widget
);
8578 #endif /* !USE_MOTIF */
8580 /* Install an action hook that let's us detect when the user
8581 finishes interacting with a scroll bar. */
8582 if (action_hook_id
== 0)
8583 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8585 /* Remember X window and widget in the scroll bar vector. */
8586 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8587 xwindow
= XtWindow (widget
);
8588 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8594 /* Set the thumb size and position of scroll bar BAR. We are currently
8595 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8598 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8599 struct scroll_bar
*bar
;
8600 int portion
, position
, whole
;
8602 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8603 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8610 top
= (float) position
/ whole
;
8611 shown
= (float) portion
/ whole
;
8619 XmScrollBarWidget sb
;
8621 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8622 is the scroll bar's maximum and MIN is the scroll bar's minimum
8624 size
= shown
* XM_SB_RANGE
;
8625 size
= min (size
, XM_SB_RANGE
);
8626 size
= max (size
, 1);
8628 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8629 value
= top
* XM_SB_RANGE
;
8630 value
= min (value
, XM_SB_MAX
- size
);
8631 value
= max (value
, XM_SB_MIN
);
8633 if (NILP (bar
->dragging
))
8634 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8635 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8636 /* This has the negative side effect that the slider value is
8637 not what it would be if we scrolled here using line-wise or
8638 page-wise movement. */
8639 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8642 /* If currently dragging, only update the slider size.
8643 This reduces flicker effects. */
8644 int old_value
, old_size
, increment
, page_increment
;
8646 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8647 &increment
, &page_increment
);
8648 XmScrollBarSetValues (widget
, old_value
,
8649 min (size
, XM_SB_RANGE
- old_value
),
8653 #else /* !USE_MOTIF i.e. use Xaw */
8655 float old_top
, old_shown
;
8657 XtVaGetValues (widget
,
8658 XtNtopOfThumb
, &old_top
,
8659 XtNshown
, &old_shown
,
8663 /* Massage the top+shown values. */
8664 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8665 top
= max (0, min (1, top
));
8668 /* Keep two pixels available for moving the thumb down. */
8669 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8671 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8672 check that your system's configuration file contains a define
8673 for `NARROWPROTO'. See s/freebsd.h for an example. */
8674 if (top
!= old_top
|| shown
!= old_shown
)
8676 if (NILP (bar
->dragging
))
8677 XawScrollbarSetThumb (widget
, top
, shown
);
8681 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8682 int scroll_mode
= 0;
8684 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8685 if (xaw3d_arrow_scroll
)
8687 /* Xaw3d stupidly ignores resize requests while dragging
8688 so we have to make it believe it's not in dragging mode. */
8689 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8690 if (scroll_mode
== 2)
8691 sb
->scrollbar
.scroll_mode
= 0;
8694 /* Try to make the scrolling a tad smoother. */
8695 if (!xaw3d_pick_top
)
8696 shown
= min (shown
, old_shown
);
8698 XawScrollbarSetThumb (widget
, top
, shown
);
8701 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8702 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8707 #endif /* !USE_MOTIF */
8712 #endif /* USE_TOOLKIT_SCROLL_BARS */
8716 /************************************************************************
8717 Scroll bars, general
8718 ************************************************************************/
8720 /* Create a scroll bar and return the scroll bar vector for it. W is
8721 the Emacs window on which to create the scroll bar. TOP, LEFT,
8722 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8725 static struct scroll_bar
*
8726 x_scroll_bar_create (w
, top
, left
, width
, height
)
8728 int top
, left
, width
, height
;
8730 struct frame
*f
= XFRAME (w
->frame
);
8731 struct scroll_bar
*bar
8732 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8736 #ifdef USE_TOOLKIT_SCROLL_BARS
8737 x_create_toolkit_scroll_bar (f
, bar
);
8738 #else /* not USE_TOOLKIT_SCROLL_BARS */
8740 XSetWindowAttributes a
;
8744 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8745 if (a
.background_pixel
== -1)
8746 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8748 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8749 | ButtonMotionMask
| PointerMotionHintMask
8751 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8753 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8755 /* Clear the area of W that will serve as a scroll bar. This is
8756 for the case that a window has been split horizontally. In
8757 this case, no clear_frame is generated to reduce flickering. */
8758 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8760 window_box_height (w
), False
);
8762 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8763 /* Position and size of scroll bar. */
8764 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8766 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8768 /* Border width, depth, class, and visual. */
8775 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8777 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8779 XSETWINDOW (bar
->window
, w
);
8780 XSETINT (bar
->top
, top
);
8781 XSETINT (bar
->left
, left
);
8782 XSETINT (bar
->width
, width
);
8783 XSETINT (bar
->height
, height
);
8784 XSETINT (bar
->start
, 0);
8785 XSETINT (bar
->end
, 0);
8786 bar
->dragging
= Qnil
;
8788 /* Add bar to its frame's list of scroll bars. */
8789 bar
->next
= FRAME_SCROLL_BARS (f
);
8791 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8792 if (!NILP (bar
->next
))
8793 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8795 /* Map the window/widget. */
8796 #ifdef USE_TOOLKIT_SCROLL_BARS
8798 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8799 XtConfigureWidget (scroll_bar
,
8800 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8802 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8803 max (height
, 1), 0);
8804 XtMapWidget (scroll_bar
);
8806 #else /* not USE_TOOLKIT_SCROLL_BARS */
8807 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8808 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8815 /* Draw BAR's handle in the proper position.
8817 If the handle is already drawn from START to END, don't bother
8818 redrawing it, unless REBUILD is non-zero; in that case, always
8819 redraw it. (REBUILD is handy for drawing the handle after expose
8822 Normally, we want to constrain the start and end of the handle to
8823 fit inside its rectangle, but if the user is dragging the scroll
8824 bar handle, we want to let them drag it down all the way, so that
8825 the bar's top is as far down as it goes; otherwise, there's no way
8826 to move to the very end of the buffer. */
8828 #ifndef USE_TOOLKIT_SCROLL_BARS
8831 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8832 struct scroll_bar
*bar
;
8836 int dragging
= ! NILP (bar
->dragging
);
8837 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8838 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8839 GC gc
= f
->output_data
.x
->normal_gc
;
8841 /* If the display is already accurate, do nothing. */
8843 && start
== XINT (bar
->start
)
8844 && end
== XINT (bar
->end
))
8850 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
8851 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8852 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8854 /* Make sure the values are reasonable, and try to preserve
8855 the distance between start and end. */
8857 int length
= end
- start
;
8861 else if (start
> top_range
)
8863 end
= start
+ length
;
8867 else if (end
> top_range
&& ! dragging
)
8871 /* Store the adjusted setting in the scroll bar. */
8872 XSETINT (bar
->start
, start
);
8873 XSETINT (bar
->end
, end
);
8875 /* Clip the end position, just for display. */
8876 if (end
> top_range
)
8879 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
8880 below top positions, to make sure the handle is always at least
8881 that many pixels tall. */
8882 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8884 /* Draw the empty space above the handle. Note that we can't clear
8885 zero-height areas; that means "clear to end of window." */
8887 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8888 /* x, y, width, height, and exposures. */
8889 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8890 VERTICAL_SCROLL_BAR_TOP_BORDER
,
8891 inside_width
, start
,
8894 /* Change to proper foreground color if one is specified. */
8895 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8896 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8897 f
->output_data
.x
->scroll_bar_foreground_pixel
);
8899 /* Draw the handle itself. */
8900 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8901 /* x, y, width, height */
8902 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8903 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
8904 inside_width
, end
- start
);
8906 /* Restore the foreground color of the GC if we changed it above. */
8907 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
8908 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
8909 f
->output_data
.x
->foreground_pixel
);
8911 /* Draw the empty space below the handle. Note that we can't
8912 clear zero-height areas; that means "clear to end of window." */
8913 if (end
< inside_height
)
8914 x_clear_area (FRAME_X_DISPLAY (f
), w
,
8915 /* x, y, width, height, and exposures. */
8916 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
8917 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
8918 inside_width
, inside_height
- end
,
8926 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8928 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8932 x_scroll_bar_remove (bar
)
8933 struct scroll_bar
*bar
;
8935 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8938 #ifdef USE_TOOLKIT_SCROLL_BARS
8939 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
8941 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
8944 /* Disassociate this scroll bar from its window. */
8945 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8951 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8952 that we are displaying PORTION characters out of a total of WHOLE
8953 characters, starting at POSITION. If WINDOW has no scroll bar,
8957 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8959 int portion
, whole
, position
;
8961 struct frame
*f
= XFRAME (w
->frame
);
8962 struct scroll_bar
*bar
;
8963 int top
, height
, left
, sb_left
, width
, sb_width
;
8964 int window_x
, window_y
, window_width
, window_height
;
8966 /* Get window dimensions. */
8967 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8969 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8970 height
= window_height
;
8972 /* Compute the left edge of the scroll bar area. */
8973 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8974 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8976 left
= XFASTINT (w
->left
);
8977 left
*= CANON_X_UNIT (f
);
8978 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8980 /* Compute the width of the scroll bar which might be less than
8981 the width of the area reserved for the scroll bar. */
8982 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8983 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8987 /* Compute the left edge of the scroll bar. */
8988 #ifdef USE_TOOLKIT_SCROLL_BARS
8989 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8990 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8992 sb_left
= left
+ (width
- sb_width
) / 2;
8994 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8995 sb_left
= left
+ width
- sb_width
;
9000 /* Does the scroll bar exist yet? */
9001 if (NILP (w
->vertical_scroll_bar
))
9004 if (width
&& height
)
9005 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9006 left
, top
, width
, height
, False
);
9008 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
9012 /* It may just need to be moved and resized. */
9013 unsigned int mask
= 0;
9015 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
9019 if (sb_left
!= XINT (bar
->left
))
9021 if (top
!= XINT (bar
->top
))
9023 if (sb_width
!= XINT (bar
->width
))
9025 if (height
!= XINT (bar
->height
))
9028 #ifdef USE_TOOLKIT_SCROLL_BARS
9030 /* Since toolkit scroll bars are smaller than the space reserved
9031 for them on the frame, we have to clear "under" them. */
9032 if (width
&& height
)
9033 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9034 left
, top
, width
, height
, False
);
9036 /* Move/size the scroll bar widget. */
9038 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
9039 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9041 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9042 max (height
, 1), 0);
9044 #else /* not USE_TOOLKIT_SCROLL_BARS */
9046 /* Clear areas not covered by the scroll bar because of
9047 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
9048 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
9050 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9051 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9053 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9054 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9055 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9059 /* Clear areas not covered by the scroll bar because it's not as
9060 wide as the area reserved for it . This makes sure a
9061 previous mode line display is cleared after C-x 2 C-x 1, for
9064 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9065 int rest
= area_width
- sb_width
;
9067 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9068 left
+ area_width
- rest
, 0,
9069 rest
, max (height
, 1), False
);
9072 /* Move/size the scroll bar window. */
9077 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9079 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
9081 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
9085 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9087 /* Remember new settings. */
9088 XSETINT (bar
->left
, sb_left
);
9089 XSETINT (bar
->top
, top
);
9090 XSETINT (bar
->width
, sb_width
);
9091 XSETINT (bar
->height
, height
);
9096 #ifdef USE_TOOLKIT_SCROLL_BARS
9097 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
9098 #else /* not USE_TOOLKIT_SCROLL_BARS */
9099 /* Set the scroll bar's current state, unless we're currently being
9101 if (NILP (bar
->dragging
))
9103 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
9106 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
9109 int start
= ((double) position
* top_range
) / whole
;
9110 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
9111 x_scroll_bar_set_handle (bar
, start
, end
, 0);
9114 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9116 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
9120 /* The following three hooks are used when we're doing a thorough
9121 redisplay of the frame. We don't explicitly know which scroll bars
9122 are going to be deleted, because keeping track of when windows go
9123 away is a real pain - "Can you say set-window-configuration, boys
9124 and girls?" Instead, we just assert at the beginning of redisplay
9125 that *all* scroll bars are to be removed, and then save a scroll bar
9126 from the fiery pit when we actually redisplay its window. */
9128 /* Arrange for all scroll bars on FRAME to be removed at the next call
9129 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
9130 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
9133 XTcondemn_scroll_bars (frame
)
9136 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
9137 while (! NILP (FRAME_SCROLL_BARS (frame
)))
9140 bar
= FRAME_SCROLL_BARS (frame
);
9141 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
9142 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
9143 XSCROLL_BAR (bar
)->prev
= Qnil
;
9144 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
9145 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
9146 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
9151 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
9152 Note that WINDOW isn't necessarily condemned at all. */
9155 XTredeem_scroll_bar (window
)
9156 struct window
*window
;
9158 struct scroll_bar
*bar
;
9161 /* We can't redeem this window's scroll bar if it doesn't have one. */
9162 if (NILP (window
->vertical_scroll_bar
))
9165 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
9167 /* Unlink it from the condemned list. */
9168 f
= XFRAME (WINDOW_FRAME (window
));
9169 if (NILP (bar
->prev
))
9171 /* If the prev pointer is nil, it must be the first in one of
9173 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9174 /* It's not condemned. Everything's fine. */
9176 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9177 window
->vertical_scroll_bar
))
9178 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9180 /* If its prev pointer is nil, it must be at the front of
9181 one or the other! */
9185 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9187 if (! NILP (bar
->next
))
9188 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9190 bar
->next
= FRAME_SCROLL_BARS (f
);
9192 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9193 if (! NILP (bar
->next
))
9194 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9197 /* Remove all scroll bars on FRAME that haven't been saved since the
9198 last call to `*condemn_scroll_bars_hook'. */
9201 XTjudge_scroll_bars (f
)
9204 Lisp_Object bar
, next
;
9206 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9208 /* Clear out the condemned list now so we won't try to process any
9209 more events on the hapless scroll bars. */
9210 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9212 for (; ! NILP (bar
); bar
= next
)
9214 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9216 x_scroll_bar_remove (b
);
9219 b
->next
= b
->prev
= Qnil
;
9222 /* Now there should be no references to the condemned scroll bars,
9223 and they should get garbage-collected. */
9227 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9228 is a no-op when using toolkit scroll bars.
9230 This may be called from a signal handler, so we have to ignore GC
9234 x_scroll_bar_expose (bar
, event
)
9235 struct scroll_bar
*bar
;
9238 #ifndef USE_TOOLKIT_SCROLL_BARS
9240 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9241 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9242 GC gc
= f
->output_data
.x
->normal_gc
;
9243 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9247 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9249 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9250 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9252 /* x, y, width, height */
9254 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9255 XINT (bar
->height
) - 1);
9259 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9262 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9263 is set to something other than no_event, it is enqueued.
9265 This may be called from a signal handler, so we have to ignore GC
9268 #ifndef USE_TOOLKIT_SCROLL_BARS
9271 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9272 struct scroll_bar
*bar
;
9274 struct input_event
*emacs_event
;
9276 if (! GC_WINDOWP (bar
->window
))
9279 emacs_event
->kind
= scroll_bar_click
;
9280 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9281 emacs_event
->modifiers
9282 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9283 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9284 event
->xbutton
.state
)
9285 | (event
->type
== ButtonRelease
9288 emacs_event
->frame_or_window
= bar
->window
;
9289 emacs_event
->arg
= Qnil
;
9290 emacs_event
->timestamp
= event
->xbutton
.time
;
9293 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9295 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9298 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9299 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9302 if (y
> top_range
) y
= top_range
;
9304 if (y
< XINT (bar
->start
))
9305 emacs_event
->part
= scroll_bar_above_handle
;
9306 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9307 emacs_event
->part
= scroll_bar_handle
;
9309 emacs_event
->part
= scroll_bar_below_handle
;
9311 /* Just because the user has clicked on the handle doesn't mean
9312 they want to drag it. Lisp code needs to be able to decide
9313 whether or not we're dragging. */
9315 /* If the user has just clicked on the handle, record where they're
9317 if (event
->type
== ButtonPress
9318 && emacs_event
->part
== scroll_bar_handle
)
9319 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9322 /* If the user has released the handle, set it to its final position. */
9323 if (event
->type
== ButtonRelease
9324 && ! NILP (bar
->dragging
))
9326 int new_start
= y
- XINT (bar
->dragging
);
9327 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9329 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9330 bar
->dragging
= Qnil
;
9333 /* Same deal here as the other #if 0. */
9335 /* Clicks on the handle are always reported as occurring at the top of
9337 if (emacs_event
->part
== scroll_bar_handle
)
9338 emacs_event
->x
= bar
->start
;
9340 XSETINT (emacs_event
->x
, y
);
9342 XSETINT (emacs_event
->x
, y
);
9345 XSETINT (emacs_event
->y
, top_range
);
9349 /* Handle some mouse motion while someone is dragging the scroll bar.
9351 This may be called from a signal handler, so we have to ignore GC
9355 x_scroll_bar_note_movement (bar
, event
)
9356 struct scroll_bar
*bar
;
9359 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9361 last_mouse_movement_time
= event
->xmotion
.time
;
9364 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9366 /* If we're dragging the bar, display it. */
9367 if (! GC_NILP (bar
->dragging
))
9369 /* Where should the handle be now? */
9370 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9372 if (new_start
!= XINT (bar
->start
))
9374 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9376 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9381 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9383 /* Return information to the user about the current position of the mouse
9384 on the scroll bar. */
9387 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9389 Lisp_Object
*bar_window
;
9390 enum scroll_bar_part
*part
;
9392 unsigned long *time
;
9394 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9395 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9396 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9398 Window dummy_window
;
9400 unsigned int dummy_mask
;
9404 /* Get the mouse's position relative to the scroll bar window, and
9406 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9408 /* Root, child, root x and root y. */
9409 &dummy_window
, &dummy_window
,
9410 &dummy_coord
, &dummy_coord
,
9412 /* Position relative to scroll bar. */
9415 /* Mouse buttons and modifier keys. */
9422 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9425 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9427 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9429 if (! NILP (bar
->dragging
))
9430 win_y
-= XINT (bar
->dragging
);
9434 if (win_y
> top_range
)
9438 *bar_window
= bar
->window
;
9440 if (! NILP (bar
->dragging
))
9441 *part
= scroll_bar_handle
;
9442 else if (win_y
< XINT (bar
->start
))
9443 *part
= scroll_bar_above_handle
;
9444 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9445 *part
= scroll_bar_handle
;
9447 *part
= scroll_bar_below_handle
;
9449 XSETINT (*x
, win_y
);
9450 XSETINT (*y
, top_range
);
9453 last_mouse_scroll_bar
= Qnil
;
9456 *time
= last_mouse_movement_time
;
9462 /* The screen has been cleared so we may have changed foreground or
9463 background colors, and the scroll bars may need to be redrawn.
9464 Clear out the scroll bars, and ask for expose events, so we can
9468 x_scroll_bar_clear (f
)
9471 #ifndef USE_TOOLKIT_SCROLL_BARS
9474 /* We can have scroll bars even if this is 0,
9475 if we just turned off scroll bar mode.
9476 But in that case we should not clear them. */
9477 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9478 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9479 bar
= XSCROLL_BAR (bar
)->next
)
9480 XClearArea (FRAME_X_DISPLAY (f
),
9481 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9483 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9486 /* This processes Expose events from the menu-bar specific X event
9487 loop in xmenu.c. This allows to redisplay the frame if necessary
9488 when handling menu-bar or pop-up items. */
9491 process_expose_from_menu (event
)
9495 struct x_display_info
*dpyinfo
;
9496 int frame_exposed_p
= 0;
9500 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
9501 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9504 if (f
->async_visible
== 0)
9506 f
->async_visible
= 1;
9507 f
->async_iconified
= 0;
9508 f
->output_data
.x
->has_been_visible
= 1;
9509 SET_FRAME_GARBAGED (f
);
9513 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9514 event
.xexpose
.x
, event
.xexpose
.y
,
9515 event
.xexpose
.width
, event
.xexpose
.height
);
9516 frame_exposed_p
= 1;
9521 struct scroll_bar
*bar
9522 = x_window_to_scroll_bar (event
.xexpose
.window
);
9525 x_scroll_bar_expose (bar
, &event
);
9529 return frame_exposed_p
;
9532 /* Define a queue to save up SelectionRequest events for later handling. */
9534 struct selection_event_queue
9537 struct selection_event_queue
*next
;
9540 static struct selection_event_queue
*queue
;
9542 /* Nonzero means queue up certain events--don't process them yet. */
9544 static int x_queue_selection_requests
;
9546 /* Queue up an X event *EVENT, to be processed later. */
9549 x_queue_event (f
, event
)
9553 struct selection_event_queue
*queue_tmp
9554 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9556 if (queue_tmp
!= NULL
)
9558 queue_tmp
->event
= *event
;
9559 queue_tmp
->next
= queue
;
9564 /* Take all the queued events and put them back
9565 so that they get processed afresh. */
9568 x_unqueue_events (display
)
9571 while (queue
!= NULL
)
9573 struct selection_event_queue
*queue_tmp
= queue
;
9574 XPutBackEvent (display
, &queue_tmp
->event
);
9575 queue
= queue_tmp
->next
;
9576 xfree ((char *)queue_tmp
);
9580 /* Start queuing SelectionRequest events. */
9583 x_start_queuing_selection_requests (display
)
9586 x_queue_selection_requests
++;
9589 /* Stop queuing SelectionRequest events. */
9592 x_stop_queuing_selection_requests (display
)
9595 x_queue_selection_requests
--;
9596 x_unqueue_events (display
);
9599 /* The main X event-reading loop - XTread_socket. */
9601 /* Time stamp of enter window event. This is only used by XTread_socket,
9602 but we have to put it out here, since static variables within functions
9603 sometimes don't work. */
9605 static Time enter_timestamp
;
9607 /* This holds the state XLookupString needs to implement dead keys
9608 and other tricks known as "compose processing". _X Window System_
9609 says that a portable program can't use this, but Stephen Gildea assures
9610 me that letting the compiler initialize it to zeros will work okay.
9612 This must be defined outside of XTread_socket, for the same reasons
9613 given for enter_time stamp, above. */
9615 static XComposeStatus compose_status
;
9617 /* Record the last 100 characters stored
9618 to help debug the loss-of-chars-during-GC problem. */
9620 static int temp_index
;
9621 static short temp_buffer
[100];
9623 /* Set this to nonzero to fake an "X I/O error"
9624 on a particular display. */
9626 struct x_display_info
*XTread_socket_fake_io_error
;
9628 /* When we find no input here, we occasionally do a no-op command
9629 to verify that the X server is still running and we can still talk with it.
9630 We try all the open displays, one by one.
9631 This variable is used for cycling thru the displays. */
9633 static struct x_display_info
*next_noop_dpyinfo
;
9635 #define SET_SAVED_MENU_EVENT(size) \
9638 if (f->output_data.x->saved_menu_event == 0) \
9639 f->output_data.x->saved_menu_event \
9640 = (XEvent *) xmalloc (sizeof (XEvent)); \
9641 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9642 if (numchars >= 1) \
9644 bufp->kind = menu_bar_activate_event; \
9645 XSETFRAME (bufp->frame_or_window, f); \
9654 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9655 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9657 /* Read events coming from the X server.
9658 This routine is called by the SIGIO handler.
9659 We return as soon as there are no more events to be read.
9661 Events representing keys are stored in buffer BUFP,
9662 which can hold up to NUMCHARS characters.
9663 We return the number of characters stored into the buffer,
9664 thus pretending to be `read'.
9666 EXPECTED is nonzero if the caller knows input is available. */
9669 XTread_socket (sd
, bufp
, numchars
, expected
)
9671 /* register */ struct input_event
*bufp
;
9672 /* register */ int numchars
;
9679 int event_found
= 0;
9680 struct x_display_info
*dpyinfo
;
9681 struct coding_system coding
;
9683 if (interrupt_input_blocked
)
9685 interrupt_input_pending
= 1;
9689 interrupt_input_pending
= 0;
9692 /* So people can tell when we have read the available input. */
9693 input_signal_count
++;
9696 abort (); /* Don't think this happens. */
9700 /* The input should be decoded if it is from XIM. Currently the
9701 locale of XIM is the same as that of the system. So, we can use
9702 Vlocale_coding_system which is initialized properly at Emacs
9704 setup_coding_system (Vlocale_coding_system
, &coding
);
9705 coding
.src_multibyte
= 0;
9706 coding
.dst_multibyte
= 1;
9707 /* The input is converted to events, thus we can't handle
9708 composition. Anyway, there's no XIM that gives us composition
9710 coding
.composing
= COMPOSITION_DISABLED
;
9712 /* Find the display we are supposed to read input for.
9713 It's the one communicating on descriptor SD. */
9714 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9716 #if 0 /* This ought to be unnecessary; let's verify it. */
9718 /* If available, Xlib uses FIOSNBIO to make the socket
9719 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9720 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9721 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9722 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9723 #endif /* ! defined (FIOSNBIO) */
9726 #if 0 /* This code can't be made to work, with multiple displays,
9727 and appears not to be used on any system any more.
9728 Also keyboard.c doesn't turn O_NDELAY on and off
9729 for X connections. */
9732 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9734 extern int read_alarm_should_throw
;
9735 read_alarm_should_throw
= 1;
9736 XPeekEvent (dpyinfo
->display
, &event
);
9737 read_alarm_should_throw
= 0;
9739 #endif /* HAVE_SELECT */
9743 /* For debugging, this gives a way to fake an I/O error. */
9744 if (dpyinfo
== XTread_socket_fake_io_error
)
9746 XTread_socket_fake_io_error
= 0;
9747 x_io_error_quitter (dpyinfo
->display
);
9750 while (XPending (dpyinfo
->display
))
9752 XNextEvent (dpyinfo
->display
, &event
);
9756 /* Filter events for the current X input method.
9757 XFilterEvent returns non-zero if the input method has
9758 consumed the event. We pass the frame's X window to
9759 XFilterEvent because that's the one for which the IC
9761 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9762 event
.xclient
.window
);
9763 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9773 if (event
.xclient
.message_type
9774 == dpyinfo
->Xatom_wm_protocols
9775 && event
.xclient
.format
== 32)
9777 if (event
.xclient
.data
.l
[0]
9778 == dpyinfo
->Xatom_wm_take_focus
)
9780 /* Use x_any_window_to_frame because this
9781 could be the shell widget window
9782 if the frame has no title bar. */
9783 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9785 /* Not quite sure this is needed -pd */
9786 if (f
&& FRAME_XIC (f
))
9787 XSetICFocus (FRAME_XIC (f
));
9789 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
9790 instructs the WM to set the input focus automatically for
9791 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
9792 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
9793 it has set the focus. So, XSetInputFocus below is not
9796 The call to XSetInputFocus below has also caused trouble. In
9797 cases where the XSetInputFocus done by the WM and the one
9798 below are temporally close (on a fast machine), the call
9799 below can generate additional FocusIn events which confuse
9802 /* Since we set WM_TAKE_FOCUS, we must call
9803 XSetInputFocus explicitly. But not if f is null,
9804 since that might be an event for a deleted frame. */
9807 Display
*d
= event
.xclient
.display
;
9808 /* Catch and ignore errors, in case window has been
9809 iconified by a window manager such as GWM. */
9810 int count
= x_catch_errors (d
);
9811 XSetInputFocus (d
, event
.xclient
.window
,
9812 /* The ICCCM says this is
9813 the only valid choice. */
9815 event
.xclient
.data
.l
[1]);
9816 /* This is needed to detect the error
9817 if there is an error. */
9819 x_uncatch_errors (d
, count
);
9821 /* Not certain about handling scroll bars here */
9824 else if (event
.xclient
.data
.l
[0]
9825 == dpyinfo
->Xatom_wm_save_yourself
)
9827 /* Save state modify the WM_COMMAND property to
9828 something which can reinstate us. This notifies
9829 the session manager, who's looking for such a
9830 PropertyNotify. Can restart processing when
9831 a keyboard or mouse event arrives. */
9834 f
= x_top_window_to_frame (dpyinfo
,
9835 event
.xclient
.window
);
9837 /* This is just so we only give real data once
9838 for a single Emacs process. */
9839 if (f
== SELECTED_FRAME ())
9840 XSetCommand (FRAME_X_DISPLAY (f
),
9841 event
.xclient
.window
,
9842 initial_argv
, initial_argc
);
9844 XSetCommand (FRAME_X_DISPLAY (f
),
9845 event
.xclient
.window
,
9849 else if (event
.xclient
.data
.l
[0]
9850 == dpyinfo
->Xatom_wm_delete_window
)
9853 = x_any_window_to_frame (dpyinfo
,
9854 event
.xclient
.window
);
9861 bufp
->kind
= delete_window_event
;
9862 XSETFRAME (bufp
->frame_or_window
, f
);
9871 else if (event
.xclient
.message_type
9872 == dpyinfo
->Xatom_wm_configure_denied
)
9875 else if (event
.xclient
.message_type
9876 == dpyinfo
->Xatom_wm_window_moved
)
9880 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9882 new_x
= event
.xclient
.data
.s
[0];
9883 new_y
= event
.xclient
.data
.s
[1];
9887 f
->output_data
.x
->left_pos
= new_x
;
9888 f
->output_data
.x
->top_pos
= new_y
;
9892 else if (event
.xclient
.message_type
9893 == dpyinfo
->Xatom_editres
)
9896 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9897 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
9900 #endif /* HACK_EDITRES */
9901 else if ((event
.xclient
.message_type
9902 == dpyinfo
->Xatom_DONE
)
9903 || (event
.xclient
.message_type
9904 == dpyinfo
->Xatom_PAGE
))
9906 /* Ghostview job completed. Kill it. We could
9907 reply with "Next" if we received "Page", but we
9908 currently never do because we are interested in
9909 images, only, which should have 1 page. */
9910 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
9912 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
9913 x_kill_gs_process (pixmap
, f
);
9914 expose_frame (f
, 0, 0, 0, 0);
9916 #ifdef USE_TOOLKIT_SCROLL_BARS
9917 /* Scroll bar callbacks send a ClientMessage from which
9918 we construct an input_event. */
9919 else if (event
.xclient
.message_type
9920 == dpyinfo
->Xatom_Scrollbar
)
9922 x_scroll_bar_to_input_event (&event
, bufp
);
9923 ++bufp
, ++count
, --numchars
;
9926 #endif /* USE_TOOLKIT_SCROLL_BARS */
9932 case SelectionNotify
:
9933 #ifdef USE_X_TOOLKIT
9934 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
9936 #endif /* not USE_X_TOOLKIT */
9937 x_handle_selection_notify (&event
.xselection
);
9940 case SelectionClear
: /* Someone has grabbed ownership. */
9941 #ifdef USE_X_TOOLKIT
9942 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
9944 #endif /* USE_X_TOOLKIT */
9946 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
9951 bufp
->kind
= selection_clear_event
;
9952 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9953 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9954 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9955 bufp
->frame_or_window
= Qnil
;
9964 case SelectionRequest
: /* Someone wants our selection. */
9965 #ifdef USE_X_TOOLKIT
9966 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
9968 #endif /* USE_X_TOOLKIT */
9969 if (x_queue_selection_requests
)
9970 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
9974 XSelectionRequestEvent
*eventp
= (XSelectionRequestEvent
*) &event
;
9979 bufp
->kind
= selection_request_event
;
9980 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
9981 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
9982 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
9983 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
9984 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
9985 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
9986 bufp
->frame_or_window
= Qnil
;
9995 case PropertyNotify
:
9996 #ifdef USE_X_TOOLKIT
9997 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
9999 #endif /* not USE_X_TOOLKIT */
10000 x_handle_property_notify (&event
.xproperty
);
10003 case ReparentNotify
:
10004 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
10008 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
10009 x_real_positions (f
, &x
, &y
);
10010 f
->output_data
.x
->left_pos
= x
;
10011 f
->output_data
.x
->top_pos
= y
;
10016 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
10019 if (f
->async_visible
== 0)
10021 f
->async_visible
= 1;
10022 f
->async_iconified
= 0;
10023 f
->output_data
.x
->has_been_visible
= 1;
10024 SET_FRAME_GARBAGED (f
);
10027 expose_frame (x_window_to_frame (dpyinfo
,
10028 event
.xexpose
.window
),
10029 event
.xexpose
.x
, event
.xexpose
.y
,
10030 event
.xexpose
.width
, event
.xexpose
.height
);
10034 #ifndef USE_TOOLKIT_SCROLL_BARS
10035 struct scroll_bar
*bar
;
10037 #if defined USE_X_TOOLKIT && defined USE_LUCID
10038 /* Submenus of the Lucid menu bar aren't widgets
10039 themselves, so there's no way to dispatch events
10040 to them. Recognize this case separately. */
10043 = x_window_to_menu_bar (event
.xexpose
.window
);
10045 xlwmenu_redisplay (widget
);
10047 #endif /* USE_X_TOOLKIT && USE_LUCID */
10049 #ifdef USE_TOOLKIT_SCROLL_BARS
10050 /* Dispatch event to the widget. */
10052 #else /* not USE_TOOLKIT_SCROLL_BARS */
10053 bar
= x_window_to_scroll_bar (event
.xexpose
.window
);
10056 x_scroll_bar_expose (bar
, &event
);
10057 #ifdef USE_X_TOOLKIT
10060 #endif /* USE_X_TOOLKIT */
10061 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10065 case GraphicsExpose
: /* This occurs when an XCopyArea's
10066 source area was obscured or not
10068 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
10072 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
10073 event
.xgraphicsexpose
.width
,
10074 event
.xgraphicsexpose
.height
);
10076 #ifdef USE_X_TOOLKIT
10079 #endif /* USE_X_TOOLKIT */
10082 case NoExpose
: /* This occurs when an XCopyArea's
10083 source area was completely
10088 /* Redo the mouse-highlight after the tooltip has gone. */
10089 if (event
.xmap
.window
== tip_window
)
10092 redo_mouse_highlight ();
10095 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
10096 if (f
) /* F may no longer exist if
10097 the frame was deleted. */
10099 /* While a frame is unmapped, display generation is
10100 disabled; you don't want to spend time updating a
10101 display that won't ever be seen. */
10102 f
->async_visible
= 0;
10103 /* We can't distinguish, from the event, whether the window
10104 has become iconified or invisible. So assume, if it
10105 was previously visible, than now it is iconified.
10106 But x_make_frame_invisible clears both
10107 the visible flag and the iconified flag;
10108 and that way, we know the window is not iconified now. */
10109 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
10111 f
->async_iconified
= 1;
10113 bufp
->kind
= iconify_event
;
10114 XSETFRAME (bufp
->frame_or_window
, f
);
10124 if (event
.xmap
.window
== tip_window
)
10125 /* The tooltip has been drawn already. Avoid
10126 the SET_FRAME_GARBAGED below. */
10129 /* We use x_top_window_to_frame because map events can
10130 come for sub-windows and they don't mean that the
10131 frame is visible. */
10132 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
10135 f
->async_visible
= 1;
10136 f
->async_iconified
= 0;
10137 f
->output_data
.x
->has_been_visible
= 1;
10139 /* wait_reading_process_input will notice this and update
10140 the frame's display structures. */
10141 SET_FRAME_GARBAGED (f
);
10145 bufp
->kind
= deiconify_event
;
10146 XSETFRAME (bufp
->frame_or_window
, f
);
10152 else if (! NILP (Vframe_list
)
10153 && ! NILP (XCDR (Vframe_list
)))
10154 /* Force a redisplay sooner or later
10155 to update the frame titles
10156 in case this is the second frame. */
10157 record_asynch_buffer_change ();
10162 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
10164 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10167 /* Scroll bars consume key events, but we want
10168 the keys to go to the scroll bar's frame. */
10169 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
10170 event
.xkey
.window
);
10171 if (widget
&& XmIsScrollBar (widget
))
10173 widget
= XtParent (widget
);
10174 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
10177 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10181 KeySym keysym
, orig_keysym
;
10182 /* al%imercury@uunet.uu.net says that making this 81
10183 instead of 80 fixed a bug whereby meta chars made
10186 It seems that some version of XmbLookupString has
10187 a bug of not returning XBufferOverflow in
10188 status_return even if the input is too long to
10189 fit in 81 bytes. So, we must prepare sufficient
10190 bytes for copy_buffer. 513 bytes (256 chars for
10191 two-byte character set) seems to be a faily good
10192 approximation. -- 2000.8.10 handa@etl.go.jp */
10193 unsigned char copy_buffer
[513];
10194 unsigned char *copy_bufptr
= copy_buffer
;
10195 int copy_bufsiz
= sizeof (copy_buffer
);
10199 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10200 extra_keyboard_modifiers
);
10201 modifiers
= event
.xkey
.state
;
10203 /* This will have to go some day... */
10205 /* make_lispy_event turns chars into control chars.
10206 Don't do it here because XLookupString is too eager. */
10207 event
.xkey
.state
&= ~ControlMask
;
10208 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10209 | dpyinfo
->super_mod_mask
10210 | dpyinfo
->hyper_mod_mask
10211 | dpyinfo
->alt_mod_mask
);
10213 /* In case Meta is ComposeCharacter,
10214 clear its status. According to Markus Ehrnsperger
10215 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10216 this enables ComposeCharacter to work whether or
10217 not it is combined with Meta. */
10218 if (modifiers
& dpyinfo
->meta_mod_mask
)
10219 bzero (&compose_status
, sizeof (compose_status
));
10224 Status status_return
;
10226 nbytes
= XmbLookupString (FRAME_XIC (f
),
10227 &event
.xkey
, copy_bufptr
,
10228 copy_bufsiz
, &keysym
,
10230 if (status_return
== XBufferOverflow
)
10232 copy_bufsiz
= nbytes
+ 1;
10233 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10234 nbytes
= XmbLookupString (FRAME_XIC (f
),
10235 &event
.xkey
, copy_bufptr
,
10236 copy_bufsiz
, &keysym
,
10240 if (status_return
== XLookupNone
)
10242 else if (status_return
== XLookupChars
)
10247 else if (status_return
!= XLookupKeySym
10248 && status_return
!= XLookupBoth
)
10252 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10253 copy_bufsiz
, &keysym
,
10256 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10257 copy_bufsiz
, &keysym
,
10261 orig_keysym
= keysym
;
10265 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10266 || keysym
== XK_Delete
10267 #ifdef XK_ISO_Left_Tab
10268 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
10270 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
10271 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10272 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10274 /* This recognizes the "extended function keys".
10275 It seems there's no cleaner way.
10276 Test IsModifierKey to avoid handling mode_switch
10278 || ((unsigned) (keysym
) >= XK_Select
10279 && (unsigned)(keysym
) < XK_KP_Space
)
10281 #ifdef XK_dead_circumflex
10282 || orig_keysym
== XK_dead_circumflex
10284 #ifdef XK_dead_grave
10285 || orig_keysym
== XK_dead_grave
10287 #ifdef XK_dead_tilde
10288 || orig_keysym
== XK_dead_tilde
10290 #ifdef XK_dead_diaeresis
10291 || orig_keysym
== XK_dead_diaeresis
10293 #ifdef XK_dead_macron
10294 || orig_keysym
== XK_dead_macron
10296 #ifdef XK_dead_degree
10297 || orig_keysym
== XK_dead_degree
10299 #ifdef XK_dead_acute
10300 || orig_keysym
== XK_dead_acute
10302 #ifdef XK_dead_cedilla
10303 || orig_keysym
== XK_dead_cedilla
10305 #ifdef XK_dead_breve
10306 || orig_keysym
== XK_dead_breve
10308 #ifdef XK_dead_ogonek
10309 || orig_keysym
== XK_dead_ogonek
10311 #ifdef XK_dead_caron
10312 || orig_keysym
== XK_dead_caron
10314 #ifdef XK_dead_doubleacute
10315 || orig_keysym
== XK_dead_doubleacute
10317 #ifdef XK_dead_abovedot
10318 || orig_keysym
== XK_dead_abovedot
10320 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10321 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10322 /* Any "vendor-specific" key is ok. */
10323 || (orig_keysym
& (1 << 28)))
10324 && ! (IsModifierKey (orig_keysym
)
10326 #ifdef XK_Mode_switch
10327 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10330 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10332 #endif /* not HAVE_X11R5 */
10335 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10337 temp_buffer
[temp_index
++] = keysym
;
10338 bufp
->kind
= non_ascii_keystroke
;
10339 bufp
->code
= keysym
;
10340 XSETFRAME (bufp
->frame_or_window
, f
);
10343 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10345 bufp
->timestamp
= event
.xkey
.time
;
10350 else if (numchars
> nbytes
)
10356 for (i
= 0; i
< nbytes
; i
++)
10358 if (temp_index
== (sizeof temp_buffer
10361 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10364 if (/* If the event is not from XIM, */
10365 event
.xkey
.keycode
!= 0
10366 /* or the current locale doesn't request
10367 decoding of the intup data, ... */
10368 || coding
.type
== coding_type_raw_text
10369 || coding
.type
== coding_type_no_conversion
)
10371 /* ... we can use the input data as is. */
10376 /* We have to decode the input data. */
10380 require
= decoding_buffer_size (&coding
, nbytes
);
10381 p
= (unsigned char *) alloca (require
);
10382 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10383 decode_coding (&coding
, copy_bufptr
, p
,
10385 nbytes
= coding
.produced
;
10386 nchars
= coding
.produced_char
;
10390 /* Convert the input data to a sequence of
10391 character events. */
10392 for (i
= 0; i
< nbytes
; i
+= len
)
10394 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10396 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10398 : multibyte_char_keystroke
);
10400 XSETFRAME (bufp
->frame_or_window
, f
);
10403 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10405 bufp
->timestamp
= event
.xkey
.time
;
10410 numchars
-= nchars
;
10412 if (keysym
== NoSymbol
)
10422 /* Don't dispatch this event since XtDispatchEvent calls
10423 XFilterEvent, and two calls in a row may freeze the
10432 /* Don't dispatch this event since XtDispatchEvent calls
10433 XFilterEvent, and two calls in a row may freeze the
10440 /* Here's a possible interpretation of the whole
10441 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10442 you get a FocusIn event, you have to get a FocusOut
10443 event before you relinquish the focus. If you
10444 haven't received a FocusIn event, then a mere
10445 LeaveNotify is enough to free you. */
10449 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10451 if (event
.xcrossing
.focus
)
10453 /* Avoid nasty pop/raise loops. */
10454 if (f
&& (!(f
->auto_raise
)
10455 || !(f
->auto_lower
)
10456 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10458 x_new_focus_frame (dpyinfo
, f
);
10459 enter_timestamp
= event
.xcrossing
.time
;
10462 else if (f
== dpyinfo
->x_focus_frame
)
10463 x_new_focus_frame (dpyinfo
, 0);
10465 /* EnterNotify counts as mouse movement,
10466 so update things that depend on mouse position. */
10467 if (f
&& !f
->output_data
.x
->hourglass_p
)
10468 note_mouse_movement (f
, &event
.xmotion
);
10473 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10474 if (event
.xfocus
.detail
!= NotifyPointer
)
10475 dpyinfo
->x_focus_event_frame
= f
;
10478 x_new_focus_frame (dpyinfo
, f
);
10480 /* Don't stop displaying the initial startup message
10481 for a switch-frame event we don't need. */
10482 if (GC_NILP (Vterminal_frame
)
10483 && GC_CONSP (Vframe_list
)
10484 && !GC_NILP (XCDR (Vframe_list
)))
10486 bufp
->kind
= FOCUS_IN_EVENT
;
10487 XSETFRAME (bufp
->frame_or_window
, f
);
10489 ++bufp
, ++count
, --numchars
;
10494 if (f
&& FRAME_XIC (f
))
10495 XSetICFocus (FRAME_XIC (f
));
10501 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10504 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10506 /* If we move outside the frame, then we're
10507 certainly no longer on any text in the frame. */
10508 clear_mouse_face (dpyinfo
);
10509 dpyinfo
->mouse_face_mouse_frame
= 0;
10512 /* Generate a nil HELP_EVENT to cancel a help-echo.
10513 Do it only if there's something to cancel.
10514 Otherwise, the startup message is cleared when
10515 the mouse leaves the frame. */
10516 if (any_help_event_p
)
10521 XSETFRAME (frame
, f
);
10523 n
= gen_help_event (bufp
, numchars
,
10524 Qnil
, frame
, Qnil
, Qnil
, 0);
10525 bufp
+= n
, count
+= n
, numchars
-= n
;
10528 if (event
.xcrossing
.focus
)
10529 x_mouse_leave (dpyinfo
);
10532 if (f
== dpyinfo
->x_focus_event_frame
)
10533 dpyinfo
->x_focus_event_frame
= 0;
10534 if (f
== dpyinfo
->x_focus_frame
)
10535 x_new_focus_frame (dpyinfo
, 0);
10541 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10542 if (event
.xfocus
.detail
!= NotifyPointer
10543 && f
== dpyinfo
->x_focus_event_frame
)
10544 dpyinfo
->x_focus_event_frame
= 0;
10545 if (f
&& f
== dpyinfo
->x_focus_frame
)
10546 x_new_focus_frame (dpyinfo
, 0);
10549 if (f
&& FRAME_XIC (f
))
10550 XUnsetICFocus (FRAME_XIC (f
));
10557 previous_help_echo
= help_echo
;
10558 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10559 help_echo_pos
= -1;
10561 if (dpyinfo
->grabbed
&& last_mouse_frame
10562 && FRAME_LIVE_P (last_mouse_frame
))
10563 f
= last_mouse_frame
;
10565 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10568 note_mouse_movement (f
, &event
.xmotion
);
10571 #ifndef USE_TOOLKIT_SCROLL_BARS
10572 struct scroll_bar
*bar
10573 = x_window_to_scroll_bar (event
.xmotion
.window
);
10576 x_scroll_bar_note_movement (bar
, &event
);
10577 #endif /* USE_TOOLKIT_SCROLL_BARS */
10579 /* If we move outside the frame, then we're
10580 certainly no longer on any text in the frame. */
10581 clear_mouse_face (dpyinfo
);
10584 /* If the contents of the global variable help_echo
10585 has changed, generate a HELP_EVENT. */
10586 if (!NILP (help_echo
)
10587 || !NILP (previous_help_echo
))
10593 XSETFRAME (frame
, f
);
10597 any_help_event_p
= 1;
10598 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10599 help_echo_window
, help_echo_object
,
10601 bufp
+= n
, count
+= n
, numchars
-= n
;
10607 case ConfigureNotify
:
10608 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10611 #ifndef USE_X_TOOLKIT
10612 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10613 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10615 /* In the toolkit version, change_frame_size
10616 is called by the code that handles resizing
10617 of the EmacsFrame widget. */
10619 /* Even if the number of character rows and columns has
10620 not changed, the font size may have changed, so we need
10621 to check the pixel dimensions as well. */
10622 if (columns
!= f
->width
10623 || rows
!= f
->height
10624 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10625 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10627 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10628 SET_FRAME_GARBAGED (f
);
10629 cancel_mouse_face (f
);
10633 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10634 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10636 /* What we have now is the position of Emacs's own window.
10637 Convert that to the position of the window manager window. */
10638 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10639 &f
->output_data
.x
->top_pos
);
10642 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10643 xic_set_statusarea (f
);
10646 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10648 /* Since the WM decorations come below top_pos now,
10649 we must put them below top_pos in the future. */
10650 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10651 x_wm_set_size_hint (f
, (long) 0, 0);
10654 /* Some window managers pass (0,0) as the location of
10655 the window, and the Motif event handler stores it
10656 in the emacs widget, which messes up Motif menus. */
10657 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10659 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10660 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10662 #endif /* USE_MOTIF */
10667 case ButtonRelease
:
10669 /* If we decide we want to generate an event to be seen
10670 by the rest of Emacs, we put it here. */
10671 struct input_event emacs_event
;
10672 int tool_bar_p
= 0;
10674 emacs_event
.kind
= no_event
;
10675 bzero (&compose_status
, sizeof (compose_status
));
10677 if (dpyinfo
->grabbed
10678 && last_mouse_frame
10679 && FRAME_LIVE_P (last_mouse_frame
))
10680 f
= last_mouse_frame
;
10682 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10686 /* Is this in the tool-bar? */
10687 if (WINDOWP (f
->tool_bar_window
)
10688 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10690 Lisp_Object window
;
10693 x
= event
.xbutton
.x
;
10694 y
= event
.xbutton
.y
;
10697 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10698 if (EQ (window
, f
->tool_bar_window
))
10700 x_handle_tool_bar_click (f
, &event
.xbutton
);
10706 if (!dpyinfo
->x_focus_frame
10707 || f
== dpyinfo
->x_focus_frame
)
10708 construct_mouse_click (&emacs_event
, &event
, f
);
10712 #ifndef USE_TOOLKIT_SCROLL_BARS
10713 struct scroll_bar
*bar
10714 = x_window_to_scroll_bar (event
.xbutton
.window
);
10717 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10718 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10721 if (event
.type
== ButtonPress
)
10723 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10724 last_mouse_frame
= f
;
10725 /* Ignore any mouse motion that happened
10726 before this event; any subsequent mouse-movement
10727 Emacs events should reflect only motion after
10728 the ButtonPress. */
10730 f
->mouse_moved
= 0;
10733 last_tool_bar_item
= -1;
10737 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10740 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10742 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10748 #ifdef USE_X_TOOLKIT
10749 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10750 /* For a down-event in the menu bar,
10751 don't pass it to Xt right now.
10752 Instead, save it away
10753 and we will pass it to Xt from kbd_buffer_get_event.
10754 That way, we can run some Lisp code first. */
10755 if (f
&& event
.type
== ButtonPress
10756 /* Verify the event is really within the menu bar
10757 and not just sent to it due to grabbing. */
10758 && event
.xbutton
.x
>= 0
10759 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10760 && event
.xbutton
.y
>= 0
10761 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10762 && event
.xbutton
.same_screen
)
10764 SET_SAVED_BUTTON_EVENT
;
10765 XSETFRAME (last_mouse_press_frame
, f
);
10767 else if (event
.type
== ButtonPress
)
10769 last_mouse_press_frame
= Qnil
;
10773 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10774 but I am trying to be cautious. */
10775 else if (event
.type
== ButtonRelease
)
10777 if (!NILP (last_mouse_press_frame
))
10779 f
= XFRAME (last_mouse_press_frame
);
10780 if (f
->output_data
.x
)
10781 SET_SAVED_BUTTON_EVENT
;
10786 #endif /* USE_MOTIF */
10789 #endif /* USE_X_TOOLKIT */
10793 case CirculateNotify
:
10796 case CirculateRequest
:
10799 case VisibilityNotify
:
10802 case MappingNotify
:
10803 /* Someone has changed the keyboard mapping - update the
10805 switch (event
.xmapping
.request
)
10807 case MappingModifier
:
10808 x_find_modifier_meanings (dpyinfo
);
10809 /* This is meant to fall through. */
10810 case MappingKeyboard
:
10811 XRefreshKeyboardMapping (&event
.xmapping
);
10817 #ifdef USE_X_TOOLKIT
10819 XtDispatchEvent (&event
);
10821 #endif /* USE_X_TOOLKIT */
10829 /* On some systems, an X bug causes Emacs to get no more events
10830 when the window is destroyed. Detect that. (1994.) */
10833 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
10834 One XNOOP in 100 loops will make Emacs terminate.
10835 B. Bretthauer, 1994 */
10837 if (x_noop_count
>= 100)
10841 if (next_noop_dpyinfo
== 0)
10842 next_noop_dpyinfo
= x_display_list
;
10844 XNoOp (next_noop_dpyinfo
->display
);
10846 /* Each time we get here, cycle through the displays now open. */
10847 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
10851 /* If the focus was just given to an auto-raising frame,
10853 /* ??? This ought to be able to handle more than one such frame. */
10854 if (pending_autoraise_frame
)
10856 x_raise_frame (pending_autoraise_frame
);
10857 pending_autoraise_frame
= 0;
10868 /***********************************************************************
10870 ***********************************************************************/
10872 /* Note if the text cursor of window W has been overwritten by a
10873 drawing operation that outputs N glyphs starting at HPOS in the
10874 line given by output_cursor.vpos. N < 0 means all the rest of the
10875 line after HPOS has been written. */
10878 note_overwritten_text_cursor (w
, hpos
, n
)
10882 if (updated_area
== TEXT_AREA
10883 && output_cursor
.vpos
== w
->phys_cursor
.vpos
10884 && hpos
<= w
->phys_cursor
.hpos
10886 || hpos
+ n
> w
->phys_cursor
.hpos
))
10887 w
->phys_cursor_on_p
= 0;
10891 /* Set clipping for output in glyph row ROW. W is the window in which
10892 we operate. GC is the graphics context to set clipping in.
10893 WHOLE_LINE_P non-zero means include the areas used for truncation
10894 mark display and alike in the clipping rectangle.
10896 ROW may be a text row or, e.g., a mode line. Text rows must be
10897 clipped to the interior of the window dedicated to text display,
10898 mode lines must be clipped to the whole window. */
10901 x_clip_to_row (w
, row
, gc
, whole_line_p
)
10903 struct glyph_row
*row
;
10907 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10908 XRectangle clip_rect
;
10909 int window_x
, window_y
, window_width
, window_height
;
10911 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
10913 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
10914 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
10915 clip_rect
.y
= max (clip_rect
.y
, window_y
);
10916 clip_rect
.width
= window_width
;
10917 clip_rect
.height
= row
->visible_height
;
10919 /* If clipping to the whole line, including trunc marks, extend
10920 the rectangle to the left and increase its width. */
10923 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
10924 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
10927 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
10931 /* Draw a hollow box cursor on window W in glyph row ROW. */
10934 x_draw_hollow_cursor (w
, row
)
10936 struct glyph_row
*row
;
10938 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
10939 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10940 Display
*dpy
= FRAME_X_DISPLAY (f
);
10943 struct glyph
*cursor_glyph
;
10946 /* Compute frame-relative coordinates from window-relative
10948 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
10949 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
10950 + row
->ascent
- w
->phys_cursor_ascent
);
10951 h
= row
->height
- 1;
10953 /* Get the glyph the cursor is on. If we can't tell because
10954 the current matrix is invalid or such, give up. */
10955 cursor_glyph
= get_phys_cursor_glyph (w
);
10956 if (cursor_glyph
== NULL
)
10959 /* Compute the width of the rectangle to draw. If on a stretch
10960 glyph, and `x-stretch-block-cursor' is nil, don't draw a
10961 rectangle as wide as the glyph, but use a canonical character
10963 wd
= cursor_glyph
->pixel_width
- 1;
10964 if (cursor_glyph
->type
== STRETCH_GLYPH
10965 && !x_stretch_cursor_p
)
10966 wd
= min (CANON_X_UNIT (f
), wd
);
10968 /* The foreground of cursor_gc is typically the same as the normal
10969 background color, which can cause the cursor box to be invisible. */
10970 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
10971 if (dpyinfo
->scratch_cursor_gc
)
10972 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
10974 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
10975 GCForeground
, &xgcv
);
10976 gc
= dpyinfo
->scratch_cursor_gc
;
10978 /* Set clipping, draw the rectangle, and reset clipping again. */
10979 x_clip_to_row (w
, row
, gc
, 0);
10980 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
10981 XSetClipMask (dpy
, gc
, None
);
10985 /* Draw a bar cursor on window W in glyph row ROW.
10987 Implementation note: One would like to draw a bar cursor with an
10988 angle equal to the one given by the font property XA_ITALIC_ANGLE.
10989 Unfortunately, I didn't find a font yet that has this property set.
10993 x_draw_bar_cursor (w
, row
, width
)
10995 struct glyph_row
*row
;
10998 struct frame
*f
= XFRAME (w
->frame
);
10999 struct glyph
*cursor_glyph
;
11002 unsigned long mask
;
11007 /* If cursor is out of bounds, don't draw garbage. This can happen
11008 in mini-buffer windows when switching between echo area glyphs
11009 and mini-buffer. */
11010 cursor_glyph
= get_phys_cursor_glyph (w
);
11011 if (cursor_glyph
== NULL
)
11014 /* If on an image, draw like a normal cursor. That's usually better
11015 visible than drawing a bar, esp. if the image is large so that
11016 the bar might not be in the window. */
11017 if (cursor_glyph
->type
== IMAGE_GLYPH
)
11019 struct glyph_row
*row
;
11020 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
11021 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
11025 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
11026 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11027 xgcv
.graphics_exposures
= 0;
11028 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
11029 dpy
= FRAME_X_DISPLAY (f
);
11030 window
= FRAME_X_WINDOW (f
);
11031 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
11034 XChangeGC (dpy
, gc
, mask
, &xgcv
);
11037 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
11038 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
11042 width
= f
->output_data
.x
->cursor_width
;
11044 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11045 x_clip_to_row (w
, row
, gc
, 0);
11046 XFillRectangle (dpy
, window
, gc
,
11048 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
11049 min (cursor_glyph
->pixel_width
, width
),
11051 XSetClipMask (dpy
, gc
, None
);
11056 /* Clear the cursor of window W to background color, and mark the
11057 cursor as not shown. This is used when the text where the cursor
11058 is is about to be rewritten. */
11064 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11065 x_update_window_cursor (w
, 0);
11069 /* Draw the cursor glyph of window W in glyph row ROW. See the
11070 comment of x_draw_glyphs for the meaning of HL. */
11073 x_draw_phys_cursor_glyph (w
, row
, hl
)
11075 struct glyph_row
*row
;
11076 enum draw_glyphs_face hl
;
11078 /* If cursor hpos is out of bounds, don't draw garbage. This can
11079 happen in mini-buffer windows when switching between echo area
11080 glyphs and mini-buffer. */
11081 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11083 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11084 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11087 /* When we erase the cursor, and ROW is overlapped by other
11088 rows, make sure that these overlapping parts of other rows
11090 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11092 if (row
> w
->current_matrix
->rows
11093 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11094 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11096 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11097 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11098 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11104 /* Erase the image of a cursor of window W from the screen. */
11107 x_erase_phys_cursor (w
)
11110 struct frame
*f
= XFRAME (w
->frame
);
11111 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11112 int hpos
= w
->phys_cursor
.hpos
;
11113 int vpos
= w
->phys_cursor
.vpos
;
11114 int mouse_face_here_p
= 0;
11115 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11116 struct glyph_row
*cursor_row
;
11117 struct glyph
*cursor_glyph
;
11118 enum draw_glyphs_face hl
;
11120 /* No cursor displayed or row invalidated => nothing to do on the
11122 if (w
->phys_cursor_type
== NO_CURSOR
)
11123 goto mark_cursor_off
;
11125 /* VPOS >= active_glyphs->nrows means that window has been resized.
11126 Don't bother to erase the cursor. */
11127 if (vpos
>= active_glyphs
->nrows
)
11128 goto mark_cursor_off
;
11130 /* If row containing cursor is marked invalid, there is nothing we
11132 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11133 if (!cursor_row
->enabled_p
)
11134 goto mark_cursor_off
;
11136 /* This can happen when the new row is shorter than the old one.
11137 In this case, either x_draw_glyphs or clear_end_of_line
11138 should have cleared the cursor. Note that we wouldn't be
11139 able to erase the cursor in this case because we don't have a
11140 cursor glyph at hand. */
11141 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11142 goto mark_cursor_off
;
11144 /* If the cursor is in the mouse face area, redisplay that when
11145 we clear the cursor. */
11146 if (! NILP (dpyinfo
->mouse_face_window
)
11147 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11148 && (vpos
> dpyinfo
->mouse_face_beg_row
11149 || (vpos
== dpyinfo
->mouse_face_beg_row
11150 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11151 && (vpos
< dpyinfo
->mouse_face_end_row
11152 || (vpos
== dpyinfo
->mouse_face_end_row
11153 && hpos
< dpyinfo
->mouse_face_end_col
))
11154 /* Don't redraw the cursor's spot in mouse face if it is at the
11155 end of a line (on a newline). The cursor appears there, but
11156 mouse highlighting does not. */
11157 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11158 mouse_face_here_p
= 1;
11160 /* Maybe clear the display under the cursor. */
11161 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11164 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11166 cursor_glyph
= get_phys_cursor_glyph (w
);
11167 if (cursor_glyph
== NULL
)
11168 goto mark_cursor_off
;
11170 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11172 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11174 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11176 cursor_glyph
->pixel_width
,
11177 cursor_row
->visible_height
,
11181 /* Erase the cursor by redrawing the character underneath it. */
11182 if (mouse_face_here_p
)
11183 hl
= DRAW_MOUSE_FACE
;
11184 else if (cursor_row
->inverse_p
)
11185 hl
= DRAW_INVERSE_VIDEO
;
11187 hl
= DRAW_NORMAL_TEXT
;
11188 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11191 w
->phys_cursor_on_p
= 0;
11192 w
->phys_cursor_type
= NO_CURSOR
;
11196 /* Display or clear cursor of window W. If ON is zero, clear the
11197 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11198 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11201 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11203 int on
, hpos
, vpos
, x
, y
;
11205 struct frame
*f
= XFRAME (w
->frame
);
11206 int new_cursor_type
;
11207 int new_cursor_width
;
11208 struct glyph_matrix
*current_glyphs
;
11209 struct glyph_row
*glyph_row
;
11210 struct glyph
*glyph
;
11212 /* This is pointless on invisible frames, and dangerous on garbaged
11213 windows and frames; in the latter case, the frame or window may
11214 be in the midst of changing its size, and x and y may be off the
11216 if (! FRAME_VISIBLE_P (f
)
11217 || FRAME_GARBAGED_P (f
)
11218 || vpos
>= w
->current_matrix
->nrows
11219 || hpos
>= w
->current_matrix
->matrix_w
)
11222 /* If cursor is off and we want it off, return quickly. */
11223 if (!on
&& !w
->phys_cursor_on_p
)
11226 current_glyphs
= w
->current_matrix
;
11227 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11228 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11230 /* If cursor row is not enabled, we don't really know where to
11231 display the cursor. */
11232 if (!glyph_row
->enabled_p
)
11234 w
->phys_cursor_on_p
= 0;
11238 xassert (interrupt_input_blocked
);
11240 /* Set new_cursor_type to the cursor we want to be displayed. In a
11241 mini-buffer window, we want the cursor only to appear if we are
11242 reading input from this window. For the selected window, we want
11243 the cursor type given by the frame parameter. If explicitly
11244 marked off, draw no cursor. In all other cases, we want a hollow
11246 new_cursor_width
= -1;
11247 if (cursor_in_echo_area
11248 && FRAME_HAS_MINIBUF_P (f
)
11249 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11251 if (w
== XWINDOW (echo_area_window
))
11252 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11254 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11258 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11259 || w
!= XWINDOW (f
->selected_window
))
11261 extern int cursor_in_non_selected_windows
;
11263 if (MINI_WINDOW_P (w
)
11264 || !cursor_in_non_selected_windows
11265 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11266 new_cursor_type
= NO_CURSOR
;
11268 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11270 else if (w
->cursor_off_p
)
11271 new_cursor_type
= NO_CURSOR
;
11274 struct buffer
*b
= XBUFFER (w
->buffer
);
11276 if (EQ (b
->cursor_type
, Qt
))
11277 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11279 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11280 &new_cursor_width
);
11284 /* If cursor is currently being shown and we don't want it to be or
11285 it is in the wrong place, or the cursor type is not what we want,
11287 if (w
->phys_cursor_on_p
11289 || w
->phys_cursor
.x
!= x
11290 || w
->phys_cursor
.y
!= y
11291 || new_cursor_type
!= w
->phys_cursor_type
))
11292 x_erase_phys_cursor (w
);
11294 /* If the cursor is now invisible and we want it to be visible,
11296 if (on
&& !w
->phys_cursor_on_p
)
11298 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11299 w
->phys_cursor_height
= glyph_row
->height
;
11301 /* Set phys_cursor_.* before x_draw_.* is called because some
11302 of them may need the information. */
11303 w
->phys_cursor
.x
= x
;
11304 w
->phys_cursor
.y
= glyph_row
->y
;
11305 w
->phys_cursor
.hpos
= hpos
;
11306 w
->phys_cursor
.vpos
= vpos
;
11307 w
->phys_cursor_type
= new_cursor_type
;
11308 w
->phys_cursor_on_p
= 1;
11310 switch (new_cursor_type
)
11312 case HOLLOW_BOX_CURSOR
:
11313 x_draw_hollow_cursor (w
, glyph_row
);
11316 case FILLED_BOX_CURSOR
:
11317 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11321 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11332 if (w
== XWINDOW (f
->selected_window
))
11333 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11334 xic_set_preeditarea (w
, x
, y
);
11339 if (updating_frame
!= f
)
11340 XFlush (FRAME_X_DISPLAY (f
));
11345 /* Display the cursor on window W, or clear it. X and Y are window
11346 relative pixel coordinates. HPOS and VPOS are glyph matrix
11347 positions. If W is not the selected window, display a hollow
11348 cursor. ON non-zero means display the cursor at X, Y which
11349 correspond to HPOS, VPOS, otherwise it is cleared. */
11352 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11354 int on
, hpos
, vpos
, x
, y
;
11357 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11362 /* Display the cursor on window W, or clear it, according to ON_P.
11363 Don't change the cursor's position. */
11366 x_update_cursor (f
, on_p
)
11369 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11373 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11374 in the window tree rooted at W. */
11377 x_update_cursor_in_window_tree (w
, on_p
)
11383 if (!NILP (w
->hchild
))
11384 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11385 else if (!NILP (w
->vchild
))
11386 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11388 x_update_window_cursor (w
, on_p
);
11390 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11395 /* Switch the display of W's cursor on or off, according to the value
11399 x_update_window_cursor (w
, on
)
11403 /* Don't update cursor in windows whose frame is in the process
11404 of being deleted. */
11405 if (w
->current_matrix
)
11408 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11409 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11419 /* Refresh bitmap kitchen sink icon for frame F
11420 when we get an expose event for it. */
11426 /* Normally, the window manager handles this function. */
11429 /* Make the x-window of frame F use the gnu icon bitmap. */
11432 x_bitmap_icon (f
, file
)
11438 if (FRAME_X_WINDOW (f
) == 0)
11441 /* Free up our existing icon bitmap if any. */
11442 if (f
->output_data
.x
->icon_bitmap
> 0)
11443 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11444 f
->output_data
.x
->icon_bitmap
= 0;
11446 if (STRINGP (file
))
11447 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11450 /* Create the GNU bitmap if necessary. */
11451 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11452 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11453 = x_create_bitmap_from_data (f
, gnu_bits
,
11454 gnu_width
, gnu_height
);
11456 /* The first time we create the GNU bitmap,
11457 this increments the ref-count one extra time.
11458 As a result, the GNU bitmap is never freed.
11459 That way, we don't have to worry about allocating it again. */
11460 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11462 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11465 x_wm_set_icon_pixmap (f
, bitmap_id
);
11466 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11472 /* Make the x-window of frame F use a rectangle with text.
11473 Use ICON_NAME as the text. */
11476 x_text_icon (f
, icon_name
)
11480 if (FRAME_X_WINDOW (f
) == 0)
11485 XTextProperty text
;
11486 text
.value
= (unsigned char *) icon_name
;
11487 text
.encoding
= XA_STRING
;
11489 text
.nitems
= strlen (icon_name
);
11490 #ifdef USE_X_TOOLKIT
11491 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11493 #else /* not USE_X_TOOLKIT */
11494 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11495 #endif /* not USE_X_TOOLKIT */
11497 #else /* not HAVE_X11R4 */
11498 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11499 #endif /* not HAVE_X11R4 */
11501 if (f
->output_data
.x
->icon_bitmap
> 0)
11502 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11503 f
->output_data
.x
->icon_bitmap
= 0;
11504 x_wm_set_icon_pixmap (f
, 0);
11509 #define X_ERROR_MESSAGE_SIZE 200
11511 /* If non-nil, this should be a string.
11512 It means catch X errors and store the error message in this string. */
11514 static Lisp_Object x_error_message_string
;
11516 /* An X error handler which stores the error message in
11517 x_error_message_string. This is called from x_error_handler if
11518 x_catch_errors is in effect. */
11521 x_error_catcher (display
, error
)
11523 XErrorEvent
*error
;
11525 XGetErrorText (display
, error
->error_code
,
11526 XSTRING (x_error_message_string
)->data
,
11527 X_ERROR_MESSAGE_SIZE
);
11530 /* Begin trapping X errors for display DPY. Actually we trap X errors
11531 for all displays, but DPY should be the display you are actually
11534 After calling this function, X protocol errors no longer cause
11535 Emacs to exit; instead, they are recorded in the string
11536 stored in x_error_message_string.
11538 Calling x_check_errors signals an Emacs error if an X error has
11539 occurred since the last call to x_catch_errors or x_check_errors.
11541 Calling x_uncatch_errors resumes the normal error handling. */
11543 void x_check_errors ();
11544 static Lisp_Object
x_catch_errors_unwind ();
11547 x_catch_errors (dpy
)
11550 int count
= specpdl_ptr
- specpdl
;
11552 /* Make sure any errors from previous requests have been dealt with. */
11553 XSync (dpy
, False
);
11555 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11557 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11558 XSTRING (x_error_message_string
)->data
[0] = 0;
11563 /* Unbind the binding that we made to check for X errors. */
11566 x_catch_errors_unwind (old_val
)
11567 Lisp_Object old_val
;
11569 x_error_message_string
= old_val
;
11573 /* If any X protocol errors have arrived since the last call to
11574 x_catch_errors or x_check_errors, signal an Emacs error using
11575 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11578 x_check_errors (dpy
, format
)
11582 /* Make sure to catch any errors incurred so far. */
11583 XSync (dpy
, False
);
11585 if (XSTRING (x_error_message_string
)->data
[0])
11586 error (format
, XSTRING (x_error_message_string
)->data
);
11589 /* Nonzero if we had any X protocol errors
11590 since we did x_catch_errors on DPY. */
11593 x_had_errors_p (dpy
)
11596 /* Make sure to catch any errors incurred so far. */
11597 XSync (dpy
, False
);
11599 return XSTRING (x_error_message_string
)->data
[0] != 0;
11602 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11605 x_clear_errors (dpy
)
11608 XSTRING (x_error_message_string
)->data
[0] = 0;
11611 /* Stop catching X protocol errors and let them make Emacs die.
11612 DPY should be the display that was passed to x_catch_errors.
11613 COUNT should be the value that was returned by
11614 the corresponding call to x_catch_errors. */
11617 x_uncatch_errors (dpy
, count
)
11621 unbind_to (count
, Qnil
);
11625 static unsigned int x_wire_count
;
11628 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11633 /* Handle SIGPIPE, which can happen when the connection to a server
11634 simply goes away. SIGPIPE is handled by x_connection_signal.
11635 Don't need to do anything, because the write which caused the
11636 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11637 which will do the appropriate cleanup for us. */
11640 x_connection_signal (signalnum
) /* If we don't have an argument, */
11641 int signalnum
; /* some compilers complain in signal calls. */
11644 /* USG systems forget handlers when they are used;
11645 must reestablish each time */
11646 signal (signalnum
, x_connection_signal
);
11651 /************************************************************************
11653 ************************************************************************/
11655 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11656 the text of an error message that lead to the connection loss. */
11659 x_connection_closed (dpy
, error_message
)
11661 char *error_message
;
11663 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11664 Lisp_Object frame
, tail
;
11668 msg
= (char *) alloca (strlen (error_message
) + 1);
11669 strcpy (msg
, error_message
);
11670 handling_signal
= 0;
11672 /* Prevent being called recursively because of an error condition
11673 below. Otherwise, we might end up with printing ``can't find per
11674 display information'' in the recursive call instead of printing
11675 the original message here. */
11676 count
= x_catch_errors (dpy
);
11678 /* We have to close the display to inform Xt that it doesn't
11679 exist anymore. If we don't, Xt will continue to wait for
11680 events from the display. As a consequence, a sequence of
11682 M-x make-frame-on-display RET :1 RET
11683 ...kill the new frame, so that we get an IO error...
11684 M-x make-frame-on-display RET :1 RET
11686 will indefinitely wait in Xt for events for display `:1', opened
11687 in the first class to make-frame-on-display.
11689 Closing the display is reported to lead to a bus error on
11690 OpenWindows in certain situations. I suspect that is a bug
11691 in OpenWindows. I don't know how to cicumvent it here. */
11693 #ifdef USE_X_TOOLKIT
11694 /* If DPYINFO is null, this means we didn't open the display
11695 in the first place, so don't try to close it. */
11697 XtCloseDisplay (dpy
);
11700 /* Indicate that this display is dead. */
11702 dpyinfo
->display
= 0;
11704 /* First delete frames whose mini-buffers are on frames
11705 that are on the dead display. */
11706 FOR_EACH_FRAME (tail
, frame
)
11708 Lisp_Object minibuf_frame
;
11710 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11711 if (FRAME_X_P (XFRAME (frame
))
11712 && FRAME_X_P (XFRAME (minibuf_frame
))
11713 && ! EQ (frame
, minibuf_frame
)
11714 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11715 Fdelete_frame (frame
, Qt
);
11718 /* Now delete all remaining frames on the dead display.
11719 We are now sure none of these is used as the mini-buffer
11720 for another frame that we need to delete. */
11721 FOR_EACH_FRAME (tail
, frame
)
11722 if (FRAME_X_P (XFRAME (frame
))
11723 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11725 /* Set this to t so that Fdelete_frame won't get confused
11726 trying to find a replacement. */
11727 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
11728 Fdelete_frame (frame
, Qt
);
11732 x_delete_display (dpyinfo
);
11734 x_uncatch_errors (dpy
, count
);
11736 if (x_display_list
== 0)
11738 fprintf (stderr
, "%s\n", msg
);
11739 shut_down_emacs (0, 0, Qnil
);
11743 /* Ordinary stack unwind doesn't deal with these. */
11745 sigunblock (sigmask (SIGIO
));
11747 sigunblock (sigmask (SIGALRM
));
11748 TOTALLY_UNBLOCK_INPUT
;
11750 clear_waiting_for_input ();
11755 /* This is the usual handler for X protocol errors.
11756 It kills all frames on the display that we got the error for.
11757 If that was the only one, it prints an error message and kills Emacs. */
11760 x_error_quitter (display
, error
)
11762 XErrorEvent
*error
;
11764 char buf
[256], buf1
[356];
11766 /* Note that there is no real way portable across R3/R4 to get the
11767 original error handler. */
11769 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
11770 sprintf (buf1
, "X protocol error: %s on protocol request %d",
11771 buf
, error
->request_code
);
11772 x_connection_closed (display
, buf1
);
11776 /* This is the first-level handler for X protocol errors.
11777 It calls x_error_quitter or x_error_catcher. */
11780 x_error_handler (display
, error
)
11782 XErrorEvent
*error
;
11784 if (! NILP (x_error_message_string
))
11785 x_error_catcher (display
, error
);
11787 x_error_quitter (display
, error
);
11791 /* This is the handler for X IO errors, always.
11792 It kills all frames on the display that we lost touch with.
11793 If that was the only one, it prints an error message and kills Emacs. */
11796 x_io_error_quitter (display
)
11801 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
11802 x_connection_closed (display
, buf
);
11806 /* Changing the font of the frame. */
11808 /* Give frame F the font named FONTNAME as its default font, and
11809 return the full name of that font. FONTNAME may be a wildcard
11810 pattern; in that case, we choose some font that fits the pattern.
11811 The return value shows which font we chose. */
11814 x_new_font (f
, fontname
)
11816 register char *fontname
;
11818 struct font_info
*fontp
11819 = FS_LOAD_FONT (f
, 0, fontname
, -1);
11824 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
11825 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
11826 f
->output_data
.x
->fontset
= -1;
11828 /* Compute the scroll bar width in character columns. */
11829 if (f
->scroll_bar_pixel_width
> 0)
11831 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11832 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
11836 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
11837 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
11840 /* Now make the frame display the given font. */
11841 if (FRAME_X_WINDOW (f
) != 0)
11843 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
11844 f
->output_data
.x
->font
->fid
);
11845 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
11846 f
->output_data
.x
->font
->fid
);
11847 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
11848 f
->output_data
.x
->font
->fid
);
11850 frame_update_line_height (f
);
11852 /* Don't change the size of a tip frame; there's no point in
11853 doing it because it's done in Fx_show_tip, and it leads to
11854 problems because the tip frame has no widget. */
11855 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
11856 x_set_window_size (f
, 0, f
->width
, f
->height
);
11859 /* If we are setting a new frame's font for the first time,
11860 there are no faces yet, so this font's height is the line height. */
11861 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
11863 return build_string (fontp
->full_name
);
11866 /* Give frame F the fontset named FONTSETNAME as its default font, and
11867 return the full name of that fontset. FONTSETNAME may be a wildcard
11868 pattern; in that case, we choose some fontset that fits the pattern.
11869 The return value shows which fontset we chose. */
11872 x_new_fontset (f
, fontsetname
)
11876 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
11877 Lisp_Object result
;
11882 if (f
->output_data
.x
->fontset
== fontset
)
11883 /* This fontset is already set in frame F. There's nothing more
11885 return fontset_name (fontset
);
11887 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
11889 if (!STRINGP (result
))
11890 /* Can't load ASCII font. */
11893 /* Since x_new_font doesn't update any fontset information, do it now. */
11894 f
->output_data
.x
->fontset
= fontset
;
11898 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
11899 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
11902 return build_string (fontsetname
);
11906 /***********************************************************************
11908 ***********************************************************************/
11914 /* XIM destroy callback function, which is called whenever the
11915 connection to input method XIM dies. CLIENT_DATA contains a
11916 pointer to the x_display_info structure corresponding to XIM. */
11919 xim_destroy_callback (xim
, client_data
, call_data
)
11921 XPointer client_data
;
11922 XPointer call_data
;
11924 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
11925 Lisp_Object frame
, tail
;
11929 /* No need to call XDestroyIC.. */
11930 FOR_EACH_FRAME (tail
, frame
)
11932 struct frame
*f
= XFRAME (frame
);
11933 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
11935 FRAME_XIC (f
) = NULL
;
11936 if (FRAME_XIC_FONTSET (f
))
11938 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
11939 FRAME_XIC_FONTSET (f
) = NULL
;
11944 /* No need to call XCloseIM. */
11945 dpyinfo
->xim
= NULL
;
11946 XFree (dpyinfo
->xim_styles
);
11950 #endif /* HAVE_X11R6 */
11952 /* Open the connection to the XIM server on display DPYINFO.
11953 RESOURCE_NAME is the resource name Emacs uses. */
11956 xim_open_dpy (dpyinfo
, resource_name
)
11957 struct x_display_info
*dpyinfo
;
11958 char *resource_name
;
11963 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
11964 dpyinfo
->xim
= xim
;
11969 XIMCallback destroy
;
11972 /* Get supported styles and XIM values. */
11973 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
11976 destroy
.callback
= xim_destroy_callback
;
11977 destroy
.client_data
= (XPointer
)dpyinfo
;
11978 /* This isn't prptotyped in OSF 5.0. */
11979 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
11983 #else /* not USE_XIM */
11984 dpyinfo
->xim
= NULL
;
11985 #endif /* not USE_XIM */
11989 #ifdef HAVE_X11R6_XIM
11993 struct x_display_info
*dpyinfo
;
11994 char *resource_name
;
11997 /* XIM instantiate callback function, which is called whenever an XIM
11998 server is available. DISPLAY is teh display of the XIM.
11999 CLIENT_DATA contains a pointer to an xim_inst_t structure created
12000 when the callback was registered. */
12003 xim_instantiate_callback (display
, client_data
, call_data
)
12005 XPointer client_data
;
12006 XPointer call_data
;
12008 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
12009 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
12011 /* We don't support multiple XIM connections. */
12015 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
12017 /* Create XIC for the existing frames on the same display, as long
12018 as they have no XIC. */
12019 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
12021 Lisp_Object tail
, frame
;
12024 FOR_EACH_FRAME (tail
, frame
)
12026 struct frame
*f
= XFRAME (frame
);
12028 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
12029 if (FRAME_XIC (f
) == NULL
)
12031 create_frame_xic (f
);
12032 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
12033 xic_set_statusarea (f
);
12034 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
12036 struct window
*w
= XWINDOW (f
->selected_window
);
12037 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
12046 #endif /* HAVE_X11R6_XIM */
12049 /* Open a connection to the XIM server on display DPYINFO.
12050 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
12051 connection only at the first time. On X11R6, open the connection
12052 in the XIM instantiate callback function. */
12055 xim_initialize (dpyinfo
, resource_name
)
12056 struct x_display_info
*dpyinfo
;
12057 char *resource_name
;
12060 #ifdef HAVE_X11R6_XIM
12061 struct xim_inst_t
*xim_inst
;
12064 dpyinfo
->xim
= NULL
;
12065 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12066 xim_inst
->dpyinfo
= dpyinfo
;
12067 len
= strlen (resource_name
);
12068 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12069 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12070 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12071 resource_name
, EMACS_CLASS
,
12072 xim_instantiate_callback
,
12073 /* Fixme: This is XPointer in
12074 XFree86 but (XPointer *) on
12075 Tru64, at least. */
12076 (XPointer
) xim_inst
);
12077 #else /* not HAVE_X11R6_XIM */
12078 dpyinfo
->xim
= NULL
;
12079 xim_open_dpy (dpyinfo
, resource_name
);
12080 #endif /* not HAVE_X11R6_XIM */
12082 #else /* not USE_XIM */
12083 dpyinfo
->xim
= NULL
;
12084 #endif /* not USE_XIM */
12088 /* Close the connection to the XIM server on display DPYINFO. */
12091 xim_close_dpy (dpyinfo
)
12092 struct x_display_info
*dpyinfo
;
12095 #ifdef HAVE_X11R6_XIM
12096 if (dpyinfo
->display
)
12097 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12099 xim_instantiate_callback
, NULL
);
12100 #endif /* not HAVE_X11R6_XIM */
12101 if (dpyinfo
->display
)
12102 XCloseIM (dpyinfo
->xim
);
12103 dpyinfo
->xim
= NULL
;
12104 XFree (dpyinfo
->xim_styles
);
12105 #endif /* USE_XIM */
12108 #endif /* not HAVE_X11R6_XIM */
12112 /* Calculate the absolute position in frame F
12113 from its current recorded position values and gravity. */
12116 x_calc_absolute_position (f
)
12120 int win_x
= 0, win_y
= 0;
12121 int flags
= f
->output_data
.x
->size_hint_flags
;
12124 /* We have nothing to do if the current position
12125 is already for the top-left corner. */
12126 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12129 #ifdef USE_X_TOOLKIT
12130 this_window
= XtWindow (f
->output_data
.x
->widget
);
12132 this_window
= FRAME_X_WINDOW (f
);
12135 /* Find the position of the outside upper-left corner of
12136 the inner window, with respect to the outer window.
12137 But do this only if we will need the results. */
12138 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12143 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12146 x_clear_errors (FRAME_X_DISPLAY (f
));
12147 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12149 /* From-window, to-window. */
12151 f
->output_data
.x
->parent_desc
,
12153 /* From-position, to-position. */
12154 0, 0, &win_x
, &win_y
,
12156 /* Child of win. */
12158 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12160 Window newroot
, newparent
= 0xdeadbeef;
12161 Window
*newchildren
;
12162 unsigned int nchildren
;
12164 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12165 &newparent
, &newchildren
, &nchildren
))
12168 XFree ((char *) newchildren
);
12170 f
->output_data
.x
->parent_desc
= newparent
;
12176 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12180 /* Treat negative positions as relative to the leftmost bottommost
12181 position that fits on the screen. */
12182 if (flags
& XNegative
)
12183 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12184 - 2 * f
->output_data
.x
->border_width
- win_x
12186 + f
->output_data
.x
->left_pos
);
12189 int height
= PIXEL_HEIGHT (f
);
12191 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12192 /* Something is fishy here. When using Motif, starting Emacs with
12193 `-g -0-0', the frame appears too low by a few pixels.
12195 This seems to be so because initially, while Emacs is starting,
12196 the column widget's height and the frame's pixel height are
12197 different. The column widget's height is the right one. In
12198 later invocations, when Emacs is up, the frame's pixel height
12201 It's not obvious where the initial small difference comes from.
12202 2000-12-01, gerd. */
12204 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12207 if (flags
& YNegative
)
12208 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12209 - 2 * f
->output_data
.x
->border_width
12212 + f
->output_data
.x
->top_pos
);
12215 /* The left_pos and top_pos
12216 are now relative to the top and left screen edges,
12217 so the flags should correspond. */
12218 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12221 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12222 to really change the position, and 0 when calling from
12223 x_make_frame_visible (in that case, XOFF and YOFF are the current
12224 position values). It is -1 when calling from x_set_frame_parameters,
12225 which means, do adjust for borders but don't change the gravity. */
12228 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12230 register int xoff
, yoff
;
12231 int change_gravity
;
12233 int modified_top
, modified_left
;
12235 if (change_gravity
> 0)
12237 f
->output_data
.x
->top_pos
= yoff
;
12238 f
->output_data
.x
->left_pos
= xoff
;
12239 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12241 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12243 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12244 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12246 x_calc_absolute_position (f
);
12249 x_wm_set_size_hint (f
, (long) 0, 0);
12251 modified_left
= f
->output_data
.x
->left_pos
;
12252 modified_top
= f
->output_data
.x
->top_pos
;
12253 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12254 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12255 /* It is a mystery why we need to add the border_width here
12256 when the frame is already visible, but experiment says we do. */
12257 if (change_gravity
!= 0)
12259 modified_left
+= f
->output_data
.x
->border_width
;
12260 modified_top
+= f
->output_data
.x
->border_width
;
12264 #ifdef USE_X_TOOLKIT
12265 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12266 modified_left
, modified_top
);
12267 #else /* not USE_X_TOOLKIT */
12268 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12269 modified_left
, modified_top
);
12270 #endif /* not USE_X_TOOLKIT */
12275 /* Change the size of frame F's X window to COLS/ROWS in the case F
12276 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12277 top-left-corner window gravity for this size change and subsequent
12278 size changes. Otherwise we leave the window gravity unchanged. */
12281 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12283 int change_gravity
;
12286 int pixelwidth
, pixelheight
;
12288 check_frame_size (f
, &rows
, &cols
);
12289 f
->output_data
.x
->vertical_scroll_bar_extra
12290 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12292 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12293 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12294 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12295 f
->output_data
.x
->flags_areas_extra
12296 = FRAME_FLAGS_AREA_WIDTH (f
);
12297 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12298 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12300 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12301 x_wm_set_size_hint (f
, (long) 0, 0);
12303 XSync (FRAME_X_DISPLAY (f
), False
);
12304 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12305 pixelwidth
, pixelheight
);
12307 /* Now, strictly speaking, we can't be sure that this is accurate,
12308 but the window manager will get around to dealing with the size
12309 change request eventually, and we'll hear how it went when the
12310 ConfigureNotify event gets here.
12312 We could just not bother storing any of this information here,
12313 and let the ConfigureNotify event set everything up, but that
12314 might be kind of confusing to the Lisp code, since size changes
12315 wouldn't be reported in the frame parameters until some random
12316 point in the future when the ConfigureNotify event arrives.
12318 We pass 1 for DELAY since we can't run Lisp code inside of
12320 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12321 PIXEL_WIDTH (f
) = pixelwidth
;
12322 PIXEL_HEIGHT (f
) = pixelheight
;
12324 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12325 receive in the ConfigureNotify event; if we get what we asked
12326 for, then the event won't cause the screen to become garbaged, so
12327 we have to make sure to do it here. */
12328 SET_FRAME_GARBAGED (f
);
12330 XFlush (FRAME_X_DISPLAY (f
));
12334 /* Call this to change the size of frame F's x-window.
12335 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12336 for this size change and subsequent size changes.
12337 Otherwise we leave the window gravity unchanged. */
12340 x_set_window_size (f
, change_gravity
, cols
, rows
)
12342 int change_gravity
;
12347 #ifdef USE_X_TOOLKIT
12349 if (f
->output_data
.x
->widget
!= NULL
)
12351 /* The x and y position of the widget is clobbered by the
12352 call to XtSetValues within EmacsFrameSetCharSize.
12353 This is a real kludge, but I don't understand Xt so I can't
12354 figure out a correct fix. Can anyone else tell me? -- rms. */
12355 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12356 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12357 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12358 f
->output_data
.x
->widget
->core
.x
= xpos
;
12359 f
->output_data
.x
->widget
->core
.y
= ypos
;
12362 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12364 #else /* not USE_X_TOOLKIT */
12366 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12368 #endif /* not USE_X_TOOLKIT */
12370 /* If cursor was outside the new size, mark it as off. */
12371 mark_window_cursors_off (XWINDOW (f
->root_window
));
12373 /* Clear out any recollection of where the mouse highlighting was,
12374 since it might be in a place that's outside the new frame size.
12375 Actually checking whether it is outside is a pain in the neck,
12376 so don't try--just let the highlighting be done afresh with new size. */
12377 cancel_mouse_face (f
);
12382 /* Mouse warping. */
12385 x_set_mouse_position (f
, x
, y
)
12391 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12392 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12394 if (pix_x
< 0) pix_x
= 0;
12395 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12397 if (pix_y
< 0) pix_y
= 0;
12398 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12402 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12403 0, 0, 0, 0, pix_x
, pix_y
);
12407 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12410 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12416 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12417 0, 0, 0, 0, pix_x
, pix_y
);
12421 /* focus shifting, raising and lowering. */
12424 x_focus_on_frame (f
)
12427 #if 0 /* This proves to be unpleasant. */
12431 /* I don't think that the ICCCM allows programs to do things like this
12432 without the interaction of the window manager. Whatever you end up
12433 doing with this code, do it to x_unfocus_frame too. */
12434 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12435 RevertToPointerRoot
, CurrentTime
);
12440 x_unfocus_frame (f
)
12444 /* Look at the remarks in x_focus_on_frame. */
12445 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12446 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12447 RevertToPointerRoot
, CurrentTime
);
12451 /* Raise frame F. */
12457 if (f
->async_visible
)
12460 #ifdef USE_X_TOOLKIT
12461 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12462 #else /* not USE_X_TOOLKIT */
12463 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12464 #endif /* not USE_X_TOOLKIT */
12465 XFlush (FRAME_X_DISPLAY (f
));
12470 /* Lower frame F. */
12476 if (f
->async_visible
)
12479 #ifdef USE_X_TOOLKIT
12480 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12481 #else /* not USE_X_TOOLKIT */
12482 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12483 #endif /* not USE_X_TOOLKIT */
12484 XFlush (FRAME_X_DISPLAY (f
));
12490 XTframe_raise_lower (f
, raise_flag
)
12500 /* Change of visibility. */
12502 /* This tries to wait until the frame is really visible.
12503 However, if the window manager asks the user where to position
12504 the frame, this will return before the user finishes doing that.
12505 The frame will not actually be visible at that time,
12506 but it will become visible later when the window manager
12507 finishes with it. */
12510 x_make_frame_visible (f
)
12514 int original_top
, original_left
;
12515 int retry_count
= 2;
12521 type
= x_icon_type (f
);
12523 x_bitmap_icon (f
, type
);
12525 if (! FRAME_VISIBLE_P (f
))
12527 /* We test FRAME_GARBAGED_P here to make sure we don't
12528 call x_set_offset a second time
12529 if we get to x_make_frame_visible a second time
12530 before the window gets really visible. */
12531 if (! FRAME_ICONIFIED_P (f
)
12532 && ! f
->output_data
.x
->asked_for_visible
)
12533 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12535 f
->output_data
.x
->asked_for_visible
= 1;
12537 if (! EQ (Vx_no_window_manager
, Qt
))
12538 x_wm_set_window_state (f
, NormalState
);
12539 #ifdef USE_X_TOOLKIT
12540 /* This was XtPopup, but that did nothing for an iconified frame. */
12541 XtMapWidget (f
->output_data
.x
->widget
);
12542 #else /* not USE_X_TOOLKIT */
12543 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12544 #endif /* not USE_X_TOOLKIT */
12545 #if 0 /* This seems to bring back scroll bars in the wrong places
12546 if the window configuration has changed. They seem
12547 to come back ok without this. */
12548 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12549 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12553 XFlush (FRAME_X_DISPLAY (f
));
12555 /* Synchronize to ensure Emacs knows the frame is visible
12556 before we do anything else. We do this loop with input not blocked
12557 so that incoming events are handled. */
12561 /* This must be before UNBLOCK_INPUT
12562 since events that arrive in response to the actions above
12563 will set it when they are handled. */
12564 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12566 original_left
= f
->output_data
.x
->left_pos
;
12567 original_top
= f
->output_data
.x
->top_pos
;
12569 /* This must come after we set COUNT. */
12572 /* We unblock here so that arriving X events are processed. */
12574 /* Now move the window back to where it was "supposed to be".
12575 But don't do it if the gravity is negative.
12576 When the gravity is negative, this uses a position
12577 that is 3 pixels too low. Perhaps that's really the border width.
12579 Don't do this if the window has never been visible before,
12580 because the window manager may choose the position
12581 and we don't want to override it. */
12583 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12584 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12585 && previously_visible
)
12589 unsigned int width
, height
, border
, depth
;
12593 /* On some window managers (such as FVWM) moving an existing
12594 window, even to the same place, causes the window manager
12595 to introduce an offset. This can cause the window to move
12596 to an unexpected location. Check the geometry (a little
12597 slow here) and then verify that the window is in the right
12598 place. If the window is not in the right place, move it
12599 there, and take the potential window manager hit. */
12600 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12601 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12603 if (original_left
!= x
|| original_top
!= y
)
12604 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12605 original_left
, original_top
);
12610 XSETFRAME (frame
, f
);
12612 /* Wait until the frame is visible. Process X events until a
12613 MapNotify event has been seen, or until we think we won't get a
12614 MapNotify at all.. */
12615 for (count
= input_signal_count
+ 10;
12616 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12618 /* Force processing of queued events. */
12621 /* Machines that do polling rather than SIGIO have been
12622 observed to go into a busy-wait here. So we'll fake an
12623 alarm signal to let the handler know that there's something
12624 to be read. We used to raise a real alarm, but it seems
12625 that the handler isn't always enabled here. This is
12627 if (input_polling_used ())
12629 /* It could be confusing if a real alarm arrives while
12630 processing the fake one. Turn it off and let the
12631 handler reset it. */
12632 extern void poll_for_input_1
P_ ((void));
12633 int old_poll_suppress_count
= poll_suppress_count
;
12634 poll_suppress_count
= 1;
12635 poll_for_input_1 ();
12636 poll_suppress_count
= old_poll_suppress_count
;
12639 /* See if a MapNotify event has been processed. */
12640 FRAME_SAMPLE_VISIBILITY (f
);
12645 (let ((f (selected-frame)))
12649 the frame is not raised with various window managers on
12650 FreeBSD, Linux and Solaris. It turns out that, for some
12651 unknown reason, the call to XtMapWidget is completely ignored.
12652 Mapping the widget a second time works. */
12654 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12659 /* Change from mapped state to withdrawn state. */
12661 /* Make the frame visible (mapped and not iconified). */
12664 x_make_frame_invisible (f
)
12669 #ifdef USE_X_TOOLKIT
12670 /* Use the frame's outermost window, not the one we normally draw on. */
12671 window
= XtWindow (f
->output_data
.x
->widget
);
12672 #else /* not USE_X_TOOLKIT */
12673 window
= FRAME_X_WINDOW (f
);
12674 #endif /* not USE_X_TOOLKIT */
12676 /* Don't keep the highlight on an invisible frame. */
12677 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12678 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12680 #if 0/* This might add unreliability; I don't trust it -- rms. */
12681 if (! f
->async_visible
&& ! f
->async_iconified
)
12687 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12688 that the current position of the window is user-specified, rather than
12689 program-specified, so that when the window is mapped again, it will be
12690 placed at the same location, without forcing the user to position it
12691 by hand again (they have already done that once for this window.) */
12692 x_wm_set_size_hint (f
, (long) 0, 1);
12696 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12697 DefaultScreen (FRAME_X_DISPLAY (f
))))
12699 UNBLOCK_INPUT_RESIGNAL
;
12700 error ("Can't notify window manager of window withdrawal");
12702 #else /* ! defined (HAVE_X11R4) */
12704 /* Tell the window manager what we're going to do. */
12705 if (! EQ (Vx_no_window_manager
, Qt
))
12709 unmap
.xunmap
.type
= UnmapNotify
;
12710 unmap
.xunmap
.window
= window
;
12711 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12712 unmap
.xunmap
.from_configure
= False
;
12713 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12714 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12716 SubstructureRedirectMaskSubstructureNotifyMask
,
12719 UNBLOCK_INPUT_RESIGNAL
;
12720 error ("Can't notify window manager of withdrawal");
12724 /* Unmap the window ourselves. Cheeky! */
12725 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12726 #endif /* ! defined (HAVE_X11R4) */
12728 /* We can't distinguish this from iconification
12729 just by the event that we get from the server.
12730 So we can't win using the usual strategy of letting
12731 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
12732 and synchronize with the server to make sure we agree. */
12734 FRAME_ICONIFIED_P (f
) = 0;
12735 f
->async_visible
= 0;
12736 f
->async_iconified
= 0;
12743 /* Change window state from mapped to iconified. */
12746 x_iconify_frame (f
)
12752 /* Don't keep the highlight on an invisible frame. */
12753 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12754 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12756 if (f
->async_iconified
)
12761 FRAME_SAMPLE_VISIBILITY (f
);
12763 type
= x_icon_type (f
);
12765 x_bitmap_icon (f
, type
);
12767 #ifdef USE_X_TOOLKIT
12769 if (! FRAME_VISIBLE_P (f
))
12771 if (! EQ (Vx_no_window_manager
, Qt
))
12772 x_wm_set_window_state (f
, IconicState
);
12773 /* This was XtPopup, but that did nothing for an iconified frame. */
12774 XtMapWidget (f
->output_data
.x
->widget
);
12775 /* The server won't give us any event to indicate
12776 that an invisible frame was changed to an icon,
12777 so we have to record it here. */
12780 f
->async_iconified
= 1;
12781 f
->async_visible
= 0;
12786 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
12787 XtWindow (f
->output_data
.x
->widget
),
12788 DefaultScreen (FRAME_X_DISPLAY (f
)));
12792 error ("Can't notify window manager of iconification");
12794 f
->async_iconified
= 1;
12795 f
->async_visible
= 0;
12799 XFlush (FRAME_X_DISPLAY (f
));
12801 #else /* not USE_X_TOOLKIT */
12803 /* Make sure the X server knows where the window should be positioned,
12804 in case the user deiconifies with the window manager. */
12805 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
12806 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12808 /* Since we don't know which revision of X we're running, we'll use both
12809 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
12811 /* X11R4: send a ClientMessage to the window manager using the
12812 WM_CHANGE_STATE type. */
12816 message
.xclient
.window
= FRAME_X_WINDOW (f
);
12817 message
.xclient
.type
= ClientMessage
;
12818 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
12819 message
.xclient
.format
= 32;
12820 message
.xclient
.data
.l
[0] = IconicState
;
12822 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12823 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12825 SubstructureRedirectMask
| SubstructureNotifyMask
,
12828 UNBLOCK_INPUT_RESIGNAL
;
12829 error ("Can't notify window manager of iconification");
12833 /* X11R3: set the initial_state field of the window manager hints to
12835 x_wm_set_window_state (f
, IconicState
);
12837 if (!FRAME_VISIBLE_P (f
))
12839 /* If the frame was withdrawn, before, we must map it. */
12840 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12843 f
->async_iconified
= 1;
12844 f
->async_visible
= 0;
12846 XFlush (FRAME_X_DISPLAY (f
));
12848 #endif /* not USE_X_TOOLKIT */
12852 /* Free X resources of frame F. */
12855 x_free_frame_resources (f
)
12858 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12862 /* If a display connection is dead, don't try sending more
12863 commands to the X server. */
12864 if (dpyinfo
->display
)
12866 if (f
->output_data
.x
->icon_desc
)
12867 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
12871 free_frame_xic (f
);
12874 if (FRAME_X_WINDOW (f
))
12875 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12877 #ifdef USE_X_TOOLKIT
12878 if (f
->output_data
.x
->widget
)
12880 XtDestroyWidget (f
->output_data
.x
->widget
);
12881 f
->output_data
.x
->widget
= NULL
;
12883 free_frame_menubar (f
);
12884 #endif /* USE_X_TOOLKIT */
12886 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
12887 unload_color (f
, f
->output_data
.x
->background_pixel
);
12888 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
12889 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
12890 unload_color (f
, f
->output_data
.x
->border_pixel
);
12891 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
12893 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
12894 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
12895 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
12896 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
12897 if (f
->output_data
.x
->white_relief
.allocated_p
)
12898 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
12899 if (f
->output_data
.x
->black_relief
.allocated_p
)
12900 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
12902 if (FRAME_FACE_CACHE (f
))
12903 free_frame_faces (f
);
12906 XFlush (FRAME_X_DISPLAY (f
));
12909 if (f
->output_data
.x
->saved_menu_event
)
12910 xfree (f
->output_data
.x
->saved_menu_event
);
12912 xfree (f
->output_data
.x
);
12913 f
->output_data
.x
= NULL
;
12915 if (f
== dpyinfo
->x_focus_frame
)
12916 dpyinfo
->x_focus_frame
= 0;
12917 if (f
== dpyinfo
->x_focus_event_frame
)
12918 dpyinfo
->x_focus_event_frame
= 0;
12919 if (f
== dpyinfo
->x_highlight_frame
)
12920 dpyinfo
->x_highlight_frame
= 0;
12922 if (f
== dpyinfo
->mouse_face_mouse_frame
)
12924 dpyinfo
->mouse_face_beg_row
12925 = dpyinfo
->mouse_face_beg_col
= -1;
12926 dpyinfo
->mouse_face_end_row
12927 = dpyinfo
->mouse_face_end_col
= -1;
12928 dpyinfo
->mouse_face_window
= Qnil
;
12929 dpyinfo
->mouse_face_deferred_gc
= 0;
12930 dpyinfo
->mouse_face_mouse_frame
= 0;
12937 /* Destroy the X window of frame F. */
12940 x_destroy_window (f
)
12943 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12945 /* If a display connection is dead, don't try sending more
12946 commands to the X server. */
12947 if (dpyinfo
->display
!= 0)
12948 x_free_frame_resources (f
);
12950 dpyinfo
->reference_count
--;
12954 /* Setting window manager hints. */
12956 /* Set the normal size hints for the window manager, for frame F.
12957 FLAGS is the flags word to use--or 0 meaning preserve the flags
12958 that the window now has.
12959 If USER_POSITION is nonzero, we set the USPosition
12960 flag (this is useful when FLAGS is 0). */
12963 x_wm_set_size_hint (f
, flags
, user_position
)
12968 XSizeHints size_hints
;
12970 #ifdef USE_X_TOOLKIT
12973 Dimension widget_width
, widget_height
;
12974 Window window
= XtWindow (f
->output_data
.x
->widget
);
12975 #else /* not USE_X_TOOLKIT */
12976 Window window
= FRAME_X_WINDOW (f
);
12977 #endif /* not USE_X_TOOLKIT */
12979 /* Setting PMaxSize caused various problems. */
12980 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
12982 size_hints
.x
= f
->output_data
.x
->left_pos
;
12983 size_hints
.y
= f
->output_data
.x
->top_pos
;
12985 #ifdef USE_X_TOOLKIT
12986 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
12987 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
12988 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
12989 size_hints
.height
= widget_height
;
12990 size_hints
.width
= widget_width
;
12991 #else /* not USE_X_TOOLKIT */
12992 size_hints
.height
= PIXEL_HEIGHT (f
);
12993 size_hints
.width
= PIXEL_WIDTH (f
);
12994 #endif /* not USE_X_TOOLKIT */
12996 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
12997 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
12998 size_hints
.max_width
12999 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
13000 size_hints
.max_height
13001 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
13003 /* Calculate the base and minimum sizes.
13005 (When we use the X toolkit, we don't do it here.
13006 Instead we copy the values that the widgets are using, below.) */
13007 #ifndef USE_X_TOOLKIT
13009 int base_width
, base_height
;
13010 int min_rows
= 0, min_cols
= 0;
13012 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
13013 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
13015 check_frame_size (f
, &min_rows
, &min_cols
);
13017 /* The window manager uses the base width hints to calculate the
13018 current number of rows and columns in the frame while
13019 resizing; min_width and min_height aren't useful for this
13020 purpose, since they might not give the dimensions for a
13021 zero-row, zero-column frame.
13023 We use the base_width and base_height members if we have
13024 them; otherwise, we set the min_width and min_height members
13025 to the size for a zero x zero frame. */
13028 size_hints
.flags
|= PBaseSize
;
13029 size_hints
.base_width
= base_width
;
13030 size_hints
.base_height
= base_height
;
13031 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
13032 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
13034 size_hints
.min_width
= base_width
;
13035 size_hints
.min_height
= base_height
;
13039 /* If we don't need the old flags, we don't need the old hint at all. */
13042 size_hints
.flags
|= flags
;
13045 #endif /* not USE_X_TOOLKIT */
13048 XSizeHints hints
; /* Sometimes I hate X Windows... */
13049 long supplied_return
;
13053 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
13056 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13059 #ifdef USE_X_TOOLKIT
13060 size_hints
.base_height
= hints
.base_height
;
13061 size_hints
.base_width
= hints
.base_width
;
13062 size_hints
.min_height
= hints
.min_height
;
13063 size_hints
.min_width
= hints
.min_width
;
13067 size_hints
.flags
|= flags
;
13072 if (hints
.flags
& PSize
)
13073 size_hints
.flags
|= PSize
;
13074 if (hints
.flags
& PPosition
)
13075 size_hints
.flags
|= PPosition
;
13076 if (hints
.flags
& USPosition
)
13077 size_hints
.flags
|= USPosition
;
13078 if (hints
.flags
& USSize
)
13079 size_hints
.flags
|= USSize
;
13083 #ifndef USE_X_TOOLKIT
13088 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
13089 size_hints
.flags
|= PWinGravity
;
13093 size_hints
.flags
&= ~ PPosition
;
13094 size_hints
.flags
|= USPosition
;
13096 #endif /* PWinGravity */
13099 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13101 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13105 /* Used for IconicState or NormalState */
13108 x_wm_set_window_state (f
, state
)
13112 #ifdef USE_X_TOOLKIT
13115 XtSetArg (al
[0], XtNinitialState
, state
);
13116 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13117 #else /* not USE_X_TOOLKIT */
13118 Window window
= FRAME_X_WINDOW (f
);
13120 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
13121 f
->output_data
.x
->wm_hints
.initial_state
= state
;
13123 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13124 #endif /* not USE_X_TOOLKIT */
13128 x_wm_set_icon_pixmap (f
, pixmap_id
)
13132 Pixmap icon_pixmap
;
13134 #ifndef USE_X_TOOLKIT
13135 Window window
= FRAME_X_WINDOW (f
);
13140 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
13141 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
13145 /* It seems there is no way to turn off use of an icon pixmap.
13146 The following line does it, only if no icon has yet been created,
13147 for some window managers. But with mwm it crashes.
13148 Some people say it should clear the IconPixmapHint bit in this case,
13149 but that doesn't work, and the X consortium said it isn't the
13150 right thing at all. Since there is no way to win,
13151 best to explicitly give up. */
13153 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
13159 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
13163 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
13164 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13167 #else /* not USE_X_TOOLKIT */
13169 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
13170 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13172 #endif /* not USE_X_TOOLKIT */
13176 x_wm_set_icon_position (f
, icon_x
, icon_y
)
13178 int icon_x
, icon_y
;
13180 #ifdef USE_X_TOOLKIT
13181 Window window
= XtWindow (f
->output_data
.x
->widget
);
13183 Window window
= FRAME_X_WINDOW (f
);
13186 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
13187 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13188 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13190 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13194 /***********************************************************************
13196 ***********************************************************************/
13198 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13201 x_get_font_info (f
, font_idx
)
13205 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13209 /* Return a list of names of available fonts matching PATTERN on frame F.
13211 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13214 SIZE < 0 means include scalable fonts.
13216 Frame F null means we have not yet created any frame on X, and
13217 consult the first display in x_display_list. MAXNAMES sets a limit
13218 on how many fonts to match. */
13221 x_list_fonts (f
, pattern
, size
, maxnames
)
13223 Lisp_Object pattern
;
13227 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13228 Lisp_Object tem
, second_best
;
13229 struct x_display_info
*dpyinfo
13230 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13231 Display
*dpy
= dpyinfo
->display
;
13232 int try_XLoadQueryFont
= 0;
13234 int allow_scalable_fonts_p
= 0;
13238 allow_scalable_fonts_p
= 1;
13242 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13243 if (NILP (patterns
))
13244 patterns
= Fcons (pattern
, Qnil
);
13246 if (maxnames
== 1 && !size
)
13247 /* We can return any single font matching PATTERN. */
13248 try_XLoadQueryFont
= 1;
13250 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13253 char **names
= NULL
;
13255 pattern
= XCAR (patterns
);
13256 /* See if we cached the result for this particular query.
13257 The cache is an alist of the form:
13258 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13259 tem
= XCDR (dpyinfo
->name_list_element
);
13260 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13261 allow_scalable_fonts_p
? Qt
: Qnil
);
13262 list
= Fassoc (key
, tem
);
13265 list
= Fcdr_safe (list
);
13266 /* We have a cashed list. Don't have to get the list again. */
13270 /* At first, put PATTERN in the cache. */
13273 count
= x_catch_errors (dpy
);
13275 if (try_XLoadQueryFont
)
13278 unsigned long value
;
13280 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13281 if (x_had_errors_p (dpy
))
13283 /* This error is perhaps due to insufficient memory on X
13284 server. Let's just ignore it. */
13286 x_clear_errors (dpy
);
13290 && XGetFontProperty (font
, XA_FONT
, &value
))
13292 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13293 int len
= strlen (name
);
13296 /* If DXPC (a Differential X Protocol Compressor)
13297 Ver.3.7 is running, XGetAtomName will return null
13298 string. We must avoid such a name. */
13300 try_XLoadQueryFont
= 0;
13304 names
= (char **) alloca (sizeof (char *));
13305 /* Some systems only allow alloca assigned to a
13307 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13308 bcopy (name
, names
[0], len
+ 1);
13313 try_XLoadQueryFont
= 0;
13316 XFreeFont (dpy
, font
);
13319 if (!try_XLoadQueryFont
)
13321 /* We try at least 10 fonts because XListFonts will return
13322 auto-scaled fonts at the head. */
13323 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13325 if (x_had_errors_p (dpy
))
13327 /* This error is perhaps due to insufficient memory on X
13328 server. Let's just ignore it. */
13330 x_clear_errors (dpy
);
13334 x_uncatch_errors (dpy
, count
);
13341 /* Make a list of all the fonts we got back.
13342 Store that in the font cache for the display. */
13343 for (i
= 0; i
< num_fonts
; i
++)
13346 char *p
= names
[i
];
13347 int average_width
= -1, dashes
= 0;
13349 /* Count the number of dashes in NAMES[I]. If there are
13350 14 dashes, and the field value following 12th dash
13351 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13352 is usually too ugly to be used for editing. Let's
13358 if (dashes
== 7) /* PIXEL_SIZE field */
13360 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13361 average_width
= atoi (p
);
13364 if (allow_scalable_fonts_p
13365 || dashes
< 14 || average_width
!= 0)
13367 tem
= build_string (names
[i
]);
13368 if (NILP (Fassoc (tem
, list
)))
13370 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13371 && ((fast_c_string_match_ignore_case
13372 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13374 /* We can set the value of PIXEL_SIZE to the
13375 width of this font. */
13376 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13378 /* For the moment, width is not known. */
13379 list
= Fcons (Fcons (tem
, Qnil
), list
);
13383 if (!try_XLoadQueryFont
)
13384 XFreeFontNames (names
);
13387 /* Now store the result in the cache. */
13388 XCDR (dpyinfo
->name_list_element
)
13389 = Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
));
13392 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13394 newlist
= second_best
= Qnil
;
13395 /* Make a list of the fonts that have the right width. */
13396 for (; CONSP (list
); list
= XCDR (list
))
13402 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13406 newlist
= Fcons (XCAR (tem
), newlist
);
13410 if (!INTEGERP (XCDR (tem
)))
13412 /* Since we have not yet known the size of this font, we
13413 must try slow function call XLoadQueryFont. */
13414 XFontStruct
*thisinfo
;
13417 count
= x_catch_errors (dpy
);
13418 thisinfo
= XLoadQueryFont (dpy
,
13419 XSTRING (XCAR (tem
))->data
);
13420 if (x_had_errors_p (dpy
))
13422 /* This error is perhaps due to insufficient memory on X
13423 server. Let's just ignore it. */
13425 x_clear_errors (dpy
);
13427 x_uncatch_errors (dpy
, count
);
13433 = (thisinfo
->min_bounds
.width
== 0
13435 : make_number (thisinfo
->max_bounds
.width
));
13436 XFreeFont (dpy
, thisinfo
);
13439 /* For unknown reason, the previous call of XListFont had
13440 returned a font which can't be opened. Record the size
13441 as 0 not to try to open it again. */
13442 XCDR (tem
) = make_number (0);
13445 found_size
= XINT (XCDR (tem
));
13446 if (found_size
== size
)
13447 newlist
= Fcons (XCAR (tem
), newlist
);
13448 else if (found_size
> 0)
13450 if (NILP (second_best
))
13452 else if (found_size
< size
)
13454 if (XINT (XCDR (second_best
)) > size
13455 || XINT (XCDR (second_best
)) < found_size
)
13460 if (XINT (XCDR (second_best
)) > size
13461 && XINT (XCDR (second_best
)) > found_size
)
13466 if (!NILP (newlist
))
13468 else if (!NILP (second_best
))
13470 newlist
= Fcons (XCAR (second_best
), Qnil
);
13481 /* Check that FONT is valid on frame F. It is if it can be found in F's
13485 x_check_font (f
, font
)
13490 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13492 xassert (font
!= NULL
);
13494 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13495 if (dpyinfo
->font_table
[i
].name
13496 && font
== dpyinfo
->font_table
[i
].font
)
13499 xassert (i
< dpyinfo
->n_fonts
);
13502 #endif /* GLYPH_DEBUG != 0 */
13504 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13505 Note: There are (broken) X fonts out there with invalid XFontStruct
13506 min_bounds contents. For example, handa@etl.go.jp reports that
13507 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13508 have font->min_bounds.width == 0. */
13511 x_font_min_bounds (font
, w
, h
)
13515 *h
= FONT_HEIGHT (font
);
13516 *w
= font
->min_bounds
.width
;
13518 /* Try to handle the case where FONT->min_bounds has invalid
13519 contents. Since the only font known to have invalid min_bounds
13520 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13522 *w
= font
->max_bounds
.width
;
13526 /* Compute the smallest character width and smallest font height over
13527 all fonts available on frame F. Set the members smallest_char_width
13528 and smallest_font_height in F's x_display_info structure to
13529 the values computed. Value is non-zero if smallest_font_height or
13530 smallest_char_width become smaller than they were before. */
13533 x_compute_min_glyph_bounds (f
)
13537 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13539 int old_width
= dpyinfo
->smallest_char_width
;
13540 int old_height
= dpyinfo
->smallest_font_height
;
13542 dpyinfo
->smallest_font_height
= 100000;
13543 dpyinfo
->smallest_char_width
= 100000;
13545 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13546 if (dpyinfo
->font_table
[i
].name
)
13548 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13551 font
= (XFontStruct
*) fontp
->font
;
13552 xassert (font
!= (XFontStruct
*) ~0);
13553 x_font_min_bounds (font
, &w
, &h
);
13555 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13556 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13559 xassert (dpyinfo
->smallest_char_width
> 0
13560 && dpyinfo
->smallest_font_height
> 0);
13562 return (dpyinfo
->n_fonts
== 1
13563 || dpyinfo
->smallest_char_width
< old_width
13564 || dpyinfo
->smallest_font_height
< old_height
);
13568 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13569 pointer to the structure font_info while allocating it dynamically.
13570 If SIZE is 0, load any size of font.
13571 If loading is failed, return NULL. */
13574 x_load_font (f
, fontname
, size
)
13576 register char *fontname
;
13579 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13580 Lisp_Object font_names
;
13583 /* Get a list of all the fonts that match this name. Once we
13584 have a list of matching fonts, we compare them against the fonts
13585 we already have by comparing names. */
13586 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13588 if (!NILP (font_names
))
13593 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13594 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13595 if (dpyinfo
->font_table
[i
].name
13596 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13597 XSTRING (XCAR (tail
))->data
)
13598 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13599 XSTRING (XCAR (tail
))->data
)))
13600 return (dpyinfo
->font_table
+ i
);
13603 /* Load the font and add it to the table. */
13607 struct font_info
*fontp
;
13608 unsigned long value
;
13611 /* If we have found fonts by x_list_font, load one of them. If
13612 not, we still try to load a font by the name given as FONTNAME
13613 because XListFonts (called in x_list_font) of some X server has
13614 a bug of not finding a font even if the font surely exists and
13615 is loadable by XLoadQueryFont. */
13616 if (size
> 0 && !NILP (font_names
))
13617 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13620 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13621 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13622 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13624 /* This error is perhaps due to insufficient memory on X
13625 server. Let's just ignore it. */
13627 x_clear_errors (FRAME_X_DISPLAY (f
));
13629 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13634 /* Find a free slot in the font table. */
13635 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13636 if (dpyinfo
->font_table
[i
].name
== NULL
)
13639 /* If no free slot found, maybe enlarge the font table. */
13640 if (i
== dpyinfo
->n_fonts
13641 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13644 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13645 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13646 dpyinfo
->font_table
13647 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13650 fontp
= dpyinfo
->font_table
+ i
;
13651 if (i
== dpyinfo
->n_fonts
)
13652 ++dpyinfo
->n_fonts
;
13654 /* Now fill in the slots of *FONTP. */
13656 fontp
->font
= font
;
13657 fontp
->font_idx
= i
;
13658 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13659 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13661 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13663 if (XGetFontProperty (font
, XA_FONT
, &value
))
13665 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13669 /* Count the number of dashes in the "full name".
13670 If it is too few, this isn't really the font's full name,
13672 In X11R4, the fonts did not come with their canonical names
13683 full_name
= (char *) xmalloc (p
- name
+ 1);
13684 bcopy (name
, full_name
, p
- name
+ 1);
13690 if (full_name
!= 0)
13691 fontp
->full_name
= full_name
;
13693 fontp
->full_name
= fontp
->name
;
13695 fontp
->size
= font
->max_bounds
.width
;
13696 fontp
->height
= FONT_HEIGHT (font
);
13698 if (NILP (font_names
))
13700 /* We come here because of a bug of XListFonts mentioned at
13701 the head of this block. Let's store this information in
13702 the cache for x_list_fonts. */
13703 Lisp_Object lispy_name
= build_string (fontname
);
13704 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13705 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
13708 XCDR (dpyinfo
->name_list_element
)
13709 = Fcons (Fcons (key
,
13710 Fcons (Fcons (lispy_full_name
,
13711 make_number (fontp
->size
)),
13713 XCDR (dpyinfo
->name_list_element
));
13716 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
13718 XCDR (dpyinfo
->name_list_element
)
13719 = Fcons (Fcons (key
,
13720 Fcons (Fcons (lispy_full_name
,
13721 make_number (fontp
->size
)),
13723 XCDR (dpyinfo
->name_list_element
));
13727 /* The slot `encoding' specifies how to map a character
13728 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
13729 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
13730 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
13731 2:0xA020..0xFF7F). For the moment, we don't know which charset
13732 uses this font. So, we set information in fontp->encoding[1]
13733 which is never used by any charset. If mapping can't be
13734 decided, set FONT_ENCODING_NOT_DECIDED. */
13736 = (font
->max_byte1
== 0
13738 ? (font
->min_char_or_byte2
< 0x80
13739 ? (font
->max_char_or_byte2
< 0x80
13740 ? 0 /* 0x20..0x7F */
13741 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
13742 : 1) /* 0xA0..0xFF */
13744 : (font
->min_byte1
< 0x80
13745 ? (font
->max_byte1
< 0x80
13746 ? (font
->min_char_or_byte2
< 0x80
13747 ? (font
->max_char_or_byte2
< 0x80
13748 ? 0 /* 0x2020..0x7F7F */
13749 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
13750 : 3) /* 0x20A0..0x7FFF */
13751 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
13752 : (font
->min_char_or_byte2
< 0x80
13753 ? (font
->max_char_or_byte2
< 0x80
13754 ? 2 /* 0xA020..0xFF7F */
13755 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
13756 : 1))); /* 0xA0A0..0xFFFF */
13758 fontp
->baseline_offset
13759 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
13760 ? (long) value
: 0);
13761 fontp
->relative_compose
13762 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
13763 ? (long) value
: 0);
13764 fontp
->default_ascent
13765 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
13766 ? (long) value
: 0);
13768 /* Set global flag fonts_changed_p to non-zero if the font loaded
13769 has a character with a smaller width than any other character
13770 before, or if the font loaded has a smalle>r height than any
13771 other font loaded before. If this happens, it will make a
13772 glyph matrix reallocation necessary. */
13773 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
13780 /* Return a pointer to struct font_info of a font named FONTNAME for
13781 frame F. If no such font is loaded, return NULL. */
13784 x_query_font (f
, fontname
)
13786 register char *fontname
;
13788 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13791 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13792 if (dpyinfo
->font_table
[i
].name
13793 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
13794 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
13795 return (dpyinfo
->font_table
+ i
);
13800 /* Find a CCL program for a font specified by FONTP, and set the member
13801 `encoder' of the structure. */
13804 x_find_ccl_program (fontp
)
13805 struct font_info
*fontp
;
13807 Lisp_Object list
, elt
;
13810 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
13814 && STRINGP (XCAR (elt
))
13815 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
13817 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
13824 struct ccl_program
*ccl
13825 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
13827 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
13830 fontp
->font_encoder
= ccl
;
13836 /***********************************************************************
13838 ***********************************************************************/
13840 #ifdef USE_X_TOOLKIT
13841 static XrmOptionDescRec emacs_options
[] = {
13842 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13843 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13845 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13846 XrmoptionSepArg
, NULL
},
13847 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13849 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13850 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13851 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13852 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13853 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13854 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13855 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13857 #endif /* USE_X_TOOLKIT */
13859 static int x_initialized
;
13861 #ifdef MULTI_KBOARD
13862 /* Test whether two display-name strings agree up to the dot that separates
13863 the screen number from the server number. */
13865 same_x_server (name1
, name2
)
13866 char *name1
, *name2
;
13868 int seen_colon
= 0;
13869 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
13870 int system_name_length
= strlen (system_name
);
13871 int length_until_period
= 0;
13873 while (system_name
[length_until_period
] != 0
13874 && system_name
[length_until_period
] != '.')
13875 length_until_period
++;
13877 /* Treat `unix' like an empty host name. */
13878 if (! strncmp (name1
, "unix:", 5))
13880 if (! strncmp (name2
, "unix:", 5))
13882 /* Treat this host's name like an empty host name. */
13883 if (! strncmp (name1
, system_name
, system_name_length
)
13884 && name1
[system_name_length
] == ':')
13885 name1
+= system_name_length
;
13886 if (! strncmp (name2
, system_name
, system_name_length
)
13887 && name2
[system_name_length
] == ':')
13888 name2
+= system_name_length
;
13889 /* Treat this host's domainless name like an empty host name. */
13890 if (! strncmp (name1
, system_name
, length_until_period
)
13891 && name1
[length_until_period
] == ':')
13892 name1
+= length_until_period
;
13893 if (! strncmp (name2
, system_name
, length_until_period
)
13894 && name2
[length_until_period
] == ':')
13895 name2
+= length_until_period
;
13897 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13901 if (seen_colon
&& *name1
== '.')
13905 && (*name1
== '.' || *name1
== '\0')
13906 && (*name2
== '.' || *name2
== '\0'));
13910 struct x_display_info
*
13911 x_term_init (display_name
, xrm_option
, resource_name
)
13912 Lisp_Object display_name
;
13914 char *resource_name
;
13918 struct x_display_info
*dpyinfo
;
13923 if (!x_initialized
)
13929 #ifdef USE_X_TOOLKIT
13930 /* weiner@footloose.sps.mot.com reports that this causes
13932 X protocol error: BadAtom (invalid Atom parameter)
13933 on protocol request 18skiloaf.
13934 So let's not use it until R6. */
13935 #ifdef HAVE_X11XTR6
13936 XtSetLanguageProc (NULL
, NULL
, NULL
);
13947 argv
[argc
++] = "-xrm";
13948 argv
[argc
++] = xrm_option
;
13950 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
13951 resource_name
, EMACS_CLASS
,
13952 emacs_options
, XtNumber (emacs_options
),
13955 #ifdef HAVE_X11XTR6
13956 /* I think this is to compensate for XtSetLanguageProc. */
13961 #else /* not USE_X_TOOLKIT */
13963 XSetLocaleModifiers ("");
13965 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
13966 #endif /* not USE_X_TOOLKIT */
13968 /* Detect failure. */
13975 /* We have definitely succeeded. Record the new connection. */
13977 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
13978 bzero (dpyinfo
, sizeof *dpyinfo
);
13980 #ifdef MULTI_KBOARD
13982 struct x_display_info
*share
;
13985 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
13986 share
= share
->next
, tail
= XCDR (tail
))
13987 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
13988 XSTRING (display_name
)->data
))
13991 dpyinfo
->kboard
= share
->kboard
;
13994 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
13995 init_kboard (dpyinfo
->kboard
);
13996 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
13998 char *vendor
= ServerVendor (dpy
);
14000 dpyinfo
->kboard
->Vsystem_key_alist
14001 = call1 (Qvendor_specific_keysyms
,
14002 build_string (vendor
? vendor
: ""));
14006 dpyinfo
->kboard
->next_kboard
= all_kboards
;
14007 all_kboards
= dpyinfo
->kboard
;
14008 /* Don't let the initial kboard remain current longer than necessary.
14009 That would cause problems if a file loaded on startup tries to
14010 prompt in the mini-buffer. */
14011 if (current_kboard
== initial_kboard
)
14012 current_kboard
= dpyinfo
->kboard
;
14014 dpyinfo
->kboard
->reference_count
++;
14018 /* Put this display on the chain. */
14019 dpyinfo
->next
= x_display_list
;
14020 x_display_list
= dpyinfo
;
14022 /* Put it on x_display_name_list as well, to keep them parallel. */
14023 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
14024 x_display_name_list
);
14025 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
14027 dpyinfo
->display
= dpy
;
14030 XSetAfterFunction (x_current_display
, x_trace_wire
);
14034 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
14035 + STRING_BYTES (XSTRING (Vsystem_name
))
14037 sprintf (dpyinfo
->x_id_name
, "%s@%s",
14038 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
14040 /* Figure out which modifier bits mean what. */
14041 x_find_modifier_meanings (dpyinfo
);
14043 /* Get the scroll bar cursor. */
14044 dpyinfo
->vertical_scroll_bar_cursor
14045 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
14047 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
14048 resource_name
, EMACS_CLASS
);
14049 #ifdef HAVE_XRMSETDATABASE
14050 XrmSetDatabase (dpyinfo
->display
, xrdb
);
14052 dpyinfo
->display
->db
= xrdb
;
14054 /* Put the rdb where we can find it in a way that works on
14056 dpyinfo
->xrdb
= xrdb
;
14058 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14059 DefaultScreen (dpyinfo
->display
));
14060 select_visual (dpyinfo
);
14061 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
14062 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
14063 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
14064 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
14065 dpyinfo
->grabbed
= 0;
14066 dpyinfo
->reference_count
= 0;
14067 dpyinfo
->icon_bitmap_id
= -1;
14068 dpyinfo
->font_table
= NULL
;
14069 dpyinfo
->n_fonts
= 0;
14070 dpyinfo
->font_table_size
= 0;
14071 dpyinfo
->bitmaps
= 0;
14072 dpyinfo
->bitmaps_size
= 0;
14073 dpyinfo
->bitmaps_last
= 0;
14074 dpyinfo
->scratch_cursor_gc
= 0;
14075 dpyinfo
->mouse_face_mouse_frame
= 0;
14076 dpyinfo
->mouse_face_deferred_gc
= 0;
14077 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
14078 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
14079 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
14080 dpyinfo
->mouse_face_window
= Qnil
;
14081 dpyinfo
->mouse_face_overlay
= Qnil
;
14082 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
14083 dpyinfo
->mouse_face_defer
= 0;
14084 dpyinfo
->x_focus_frame
= 0;
14085 dpyinfo
->x_focus_event_frame
= 0;
14086 dpyinfo
->x_highlight_frame
= 0;
14087 dpyinfo
->image_cache
= make_image_cache ();
14089 /* See if a private colormap is requested. */
14090 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
14092 if (dpyinfo
->visual
->class == PseudoColor
)
14095 value
= display_x_get_resource (dpyinfo
,
14096 build_string ("privateColormap"),
14097 build_string ("PrivateColormap"),
14099 if (STRINGP (value
)
14100 && (!strcmp (XSTRING (value
)->data
, "true")
14101 || !strcmp (XSTRING (value
)->data
, "on")))
14102 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
14106 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
14107 dpyinfo
->visual
, AllocNone
);
14110 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
14111 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
14112 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
14113 dpyinfo
->resy
= pixels
* 25.4 / mm
;
14114 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
14115 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
14116 dpyinfo
->resx
= pixels
* 25.4 / mm
;
14119 dpyinfo
->Xatom_wm_protocols
14120 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
14121 dpyinfo
->Xatom_wm_take_focus
14122 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
14123 dpyinfo
->Xatom_wm_save_yourself
14124 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
14125 dpyinfo
->Xatom_wm_delete_window
14126 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
14127 dpyinfo
->Xatom_wm_change_state
14128 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
14129 dpyinfo
->Xatom_wm_configure_denied
14130 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
14131 dpyinfo
->Xatom_wm_window_moved
14132 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
14133 dpyinfo
->Xatom_editres
14134 = XInternAtom (dpyinfo
->display
, "Editres", False
);
14135 dpyinfo
->Xatom_CLIPBOARD
14136 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
14137 dpyinfo
->Xatom_TIMESTAMP
14138 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
14139 dpyinfo
->Xatom_TEXT
14140 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
14141 dpyinfo
->Xatom_COMPOUND_TEXT
14142 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
14143 dpyinfo
->Xatom_DELETE
14144 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
14145 dpyinfo
->Xatom_MULTIPLE
14146 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
14147 dpyinfo
->Xatom_INCR
14148 = XInternAtom (dpyinfo
->display
, "INCR", False
);
14149 dpyinfo
->Xatom_EMACS_TMP
14150 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
14151 dpyinfo
->Xatom_TARGETS
14152 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
14153 dpyinfo
->Xatom_NULL
14154 = XInternAtom (dpyinfo
->display
, "NULL", False
);
14155 dpyinfo
->Xatom_ATOM_PAIR
14156 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
14157 /* For properties of font. */
14158 dpyinfo
->Xatom_PIXEL_SIZE
14159 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
14160 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
14161 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
14162 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
14163 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
14164 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
14165 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
14167 /* Ghostscript support. */
14168 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
14169 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
14171 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
14174 dpyinfo
->cut_buffers_initialized
= 0;
14176 connection
= ConnectionNumber (dpyinfo
->display
);
14177 dpyinfo
->connection
= connection
;
14182 null_bits
[0] = 0x00;
14184 dpyinfo
->null_pixel
14185 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14186 null_bits
, 1, 1, (long) 0, (long) 0,
14191 extern int gray_bitmap_width
, gray_bitmap_height
;
14192 extern char *gray_bitmap_bits
;
14194 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14196 gray_bitmap_width
, gray_bitmap_height
,
14197 (unsigned long) 1, (unsigned long) 0, 1);
14201 xim_initialize (dpyinfo
, resource_name
);
14204 #ifdef subprocesses
14205 /* This is only needed for distinguishing keyboard and process input. */
14206 if (connection
!= 0)
14207 add_keyboard_wait_descriptor (connection
);
14210 #ifndef F_SETOWN_BUG
14212 #ifdef F_SETOWN_SOCK_NEG
14213 /* stdin is a socket here */
14214 fcntl (connection
, F_SETOWN
, -getpid ());
14215 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14216 fcntl (connection
, F_SETOWN
, getpid ());
14217 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14218 #endif /* ! defined (F_SETOWN) */
14219 #endif /* F_SETOWN_BUG */
14222 if (interrupt_input
)
14223 init_sigio (connection
);
14224 #endif /* ! defined (SIGIO) */
14227 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14228 /* Make sure that we have a valid font for dialog boxes
14229 so that Xt does not crash. */
14231 Display
*dpy
= dpyinfo
->display
;
14232 XrmValue d
, fr
, to
;
14236 d
.addr
= (XPointer
)&dpy
;
14237 d
.size
= sizeof (Display
*);
14238 fr
.addr
= XtDefaultFont
;
14239 fr
.size
= sizeof (XtDefaultFont
);
14240 to
.size
= sizeof (Font
*);
14241 to
.addr
= (XPointer
)&font
;
14242 count
= x_catch_errors (dpy
);
14243 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14245 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14246 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14247 x_uncatch_errors (dpy
, count
);
14252 /* See if we should run in synchronous mode. This is useful
14253 for debugging X code. */
14256 value
= display_x_get_resource (dpyinfo
,
14257 build_string ("synchronous"),
14258 build_string ("Synchronous"),
14260 if (STRINGP (value
)
14261 && (!strcmp (XSTRING (value
)->data
, "true")
14262 || !strcmp (XSTRING (value
)->data
, "on")))
14263 XSynchronize (dpyinfo
->display
, True
);
14271 /* Get rid of display DPYINFO, assuming all frames are already gone,
14272 and without sending any more commands to the X server. */
14275 x_delete_display (dpyinfo
)
14276 struct x_display_info
*dpyinfo
;
14278 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14280 /* Discard this display from x_display_name_list and x_display_list.
14281 We can't use Fdelq because that can quit. */
14282 if (! NILP (x_display_name_list
)
14283 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14284 x_display_name_list
= XCDR (x_display_name_list
);
14289 tail
= x_display_name_list
;
14290 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14292 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14294 XCDR (tail
) = XCDR (XCDR (tail
));
14297 tail
= XCDR (tail
);
14301 if (next_noop_dpyinfo
== dpyinfo
)
14302 next_noop_dpyinfo
= dpyinfo
->next
;
14304 if (x_display_list
== dpyinfo
)
14305 x_display_list
= dpyinfo
->next
;
14308 struct x_display_info
*tail
;
14310 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14311 if (tail
->next
== dpyinfo
)
14312 tail
->next
= tail
->next
->next
;
14315 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14316 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14317 XrmDestroyDatabase (dpyinfo
->xrdb
);
14320 #ifdef MULTI_KBOARD
14321 if (--dpyinfo
->kboard
->reference_count
== 0)
14322 delete_kboard (dpyinfo
->kboard
);
14326 xim_close_dpy (dpyinfo
);
14329 xfree (dpyinfo
->font_table
);
14330 xfree (dpyinfo
->x_id_name
);
14331 xfree (dpyinfo
->color_cells
);
14336 /* Set up use of X before we make the first connection. */
14338 static struct redisplay_interface x_redisplay_interface
=
14343 x_clear_end_of_line
,
14345 x_after_update_window_line
,
14346 x_update_window_begin
,
14347 x_update_window_end
,
14350 x_clear_mouse_face
,
14351 x_get_glyph_overhangs
,
14352 x_fix_overlapping_area
14358 rif
= &x_redisplay_interface
;
14360 clear_frame_hook
= x_clear_frame
;
14361 ins_del_lines_hook
= x_ins_del_lines
;
14362 change_line_highlight_hook
= x_change_line_highlight
;
14363 delete_glyphs_hook
= x_delete_glyphs
;
14364 ring_bell_hook
= XTring_bell
;
14365 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14366 set_terminal_modes_hook
= XTset_terminal_modes
;
14367 update_begin_hook
= x_update_begin
;
14368 update_end_hook
= x_update_end
;
14369 set_terminal_window_hook
= XTset_terminal_window
;
14370 read_socket_hook
= XTread_socket
;
14371 frame_up_to_date_hook
= XTframe_up_to_date
;
14372 reassert_line_highlight_hook
= XTreassert_line_highlight
;
14373 mouse_position_hook
= XTmouse_position
;
14374 frame_rehighlight_hook
= XTframe_rehighlight
;
14375 frame_raise_lower_hook
= XTframe_raise_lower
;
14376 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14377 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14378 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14379 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14380 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14382 scroll_region_ok
= 1; /* we'll scroll partial frames */
14383 char_ins_del_ok
= 1;
14384 line_ins_del_ok
= 1; /* we'll just blt 'em */
14385 fast_clear_end_of_line
= 1; /* X does this well */
14386 memory_below_frame
= 0; /* we don't remember what scrolls
14391 last_tool_bar_item
= -1;
14392 any_help_event_p
= 0;
14394 /* Try to use interrupt input; if we can't, then start polling. */
14395 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14397 #ifdef USE_X_TOOLKIT
14398 XtToolkitInitialize ();
14400 Xt_app_con
= XtCreateApplicationContext ();
14402 /* Register a converter from strings to pixels, which uses
14403 Emacs' color allocation infrastructure. */
14404 XtAppSetTypeConverter (Xt_app_con
,
14405 XtRString
, XtRPixel
, cvt_string_to_pixel
,
14406 cvt_string_to_pixel_args
,
14407 XtNumber (cvt_string_to_pixel_args
),
14408 XtCacheByDisplay
, cvt_pixel_dtor
);
14410 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14412 /* Install an asynchronous timer that processes Xt timeout events
14413 every 0.1s. This is necessary because some widget sets use
14414 timeouts internally, for example the LessTif menu bar, or the
14415 Xaw3d scroll bar. When Xt timouts aren't processed, these
14416 widgets don't behave normally. */
14418 EMACS_TIME interval
;
14419 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14420 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14424 #ifdef USE_TOOLKIT_SCROLL_BARS
14425 xaw3d_arrow_scroll
= False
;
14426 xaw3d_pick_top
= True
;
14429 /* Note that there is no real way portable across R3/R4 to get the
14430 original error handler. */
14431 XSetErrorHandler (x_error_handler
);
14432 XSetIOErrorHandler (x_io_error_quitter
);
14434 /* Disable Window Change signals; they are handled by X events. */
14436 signal (SIGWINCH
, SIG_DFL
);
14437 #endif /* ! defined (SIGWINCH) */
14439 signal (SIGPIPE
, x_connection_signal
);
14446 staticpro (&x_error_message_string
);
14447 x_error_message_string
= Qnil
;
14449 staticpro (&x_display_name_list
);
14450 x_display_name_list
= Qnil
;
14452 staticpro (&last_mouse_scroll_bar
);
14453 last_mouse_scroll_bar
= Qnil
;
14455 staticpro (&Qvendor_specific_keysyms
);
14456 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14458 staticpro (&last_mouse_press_frame
);
14459 last_mouse_press_frame
= Qnil
;
14462 staticpro (&help_echo
);
14463 help_echo_object
= Qnil
;
14464 staticpro (&help_echo_object
);
14465 help_echo_window
= Qnil
;
14466 staticpro (&help_echo_window
);
14467 previous_help_echo
= Qnil
;
14468 staticpro (&previous_help_echo
);
14469 help_echo_pos
= -1;
14471 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14472 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
14473 For example, if a block cursor is over a tab, it will be drawn as\n\
14474 wide as that tab on the display.");
14475 x_stretch_cursor_p
= 0;
14477 DEFVAR_BOOL ("x-use-underline-position-properties",
14478 &x_use_underline_position_properties
,
14479 "*Non-nil means make use of UNDERLINE_POSITION font properties.\n\
14480 Nil means ignore them. If you encounter fonts with bogus\n\
14481 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior\n\
14482 to 4.1, set this to nil.");
14483 x_use_underline_position_properties
= 1;
14485 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14486 "What X toolkit scroll bars Emacs uses.\n\
14487 A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
14488 Otherwise, value is a symbol describing the X toolkit.");
14489 #ifdef USE_TOOLKIT_SCROLL_BARS
14491 Vx_toolkit_scroll_bars
= intern ("motif");
14492 #elif defined HAVE_XAW3D
14493 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14495 Vx_toolkit_scroll_bars
= intern ("xaw");
14498 Vx_toolkit_scroll_bars
= Qnil
;
14501 staticpro (&last_mouse_motion_frame
);
14502 last_mouse_motion_frame
= Qnil
;
14505 #endif /* not HAVE_X_WINDOWS */