Merge from origin/emacs-26
[emacs.git] / src / xterm.c
blobd90654b101d740892f365f793e95e5dd4c2de2e8
1 /* X Communication module for terminals which understand the X protocol.
3 Copyright (C) 1989, 1993-2017 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 3 of the License, or (at
10 your option) any later version.
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. If not, see <https://www.gnu.org/licenses/>. */
20 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
21 /* Xt features made by Fred Pierresteguy. */
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
28 #include "lisp.h"
29 #include "blockinput.h"
31 /* This may include sys/types.h, and that somehow loses
32 if this is not done before the other system files. */
33 #include "xterm.h"
34 #include <X11/cursorfont.h>
36 /* If we have Xfixes extension, use it for pointer blanking. */
37 #ifdef HAVE_XFIXES
38 #include <X11/extensions/Xfixes.h>
39 #endif
41 /* Using Xft implies that XRender is available. */
42 #ifdef HAVE_XFT
43 #include <X11/extensions/Xrender.h>
44 #endif
46 #ifdef HAVE_XDBE
47 #include <X11/extensions/Xdbe.h>
48 #endif
50 /* Load sys/types.h if not already loaded.
51 In some systems loading it twice is suicidal. */
52 #ifndef makedev
53 #include <sys/types.h>
54 #endif /* makedev */
56 #include <sys/ioctl.h>
58 #include "systime.h"
60 #include <fcntl.h>
61 #include <errno.h>
62 #include <sys/stat.h>
63 #include "character.h"
64 #include "coding.h"
65 #include "composite.h"
66 #include "frame.h"
67 #include "dispextern.h"
68 #include "xwidget.h"
69 #include "fontset.h"
70 #include "termhooks.h"
71 #include "termopts.h"
72 #include "termchar.h"
73 #include "emacs-icon.h"
74 #include "buffer.h"
75 #include "window.h"
76 #include "keyboard.h"
77 #include "atimer.h"
78 #include "font.h"
79 #include "xsettings.h"
80 #include "sysselect.h"
81 #include "menu.h"
83 #ifdef USE_X_TOOLKIT
84 #include <X11/Shell.h>
85 #endif
87 #include <unistd.h>
89 #ifdef USE_GTK
90 #include "gtkutil.h"
91 #ifdef HAVE_GTK3
92 #include <X11/Xproto.h>
93 #endif
94 #endif
96 #if defined (USE_LUCID) || defined (USE_MOTIF)
97 #include "../lwlib/xlwmenu.h"
98 #endif
100 #ifdef USE_X_TOOLKIT
102 /* Include toolkit specific headers for the scroll bar widget. */
104 #ifdef USE_TOOLKIT_SCROLL_BARS
105 #if defined USE_MOTIF
106 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
107 #include <Xm/ScrollBar.h>
108 #else /* !USE_MOTIF i.e. use Xaw */
110 #ifdef HAVE_XAW3D
111 #include <X11/Xaw3d/Simple.h>
112 #include <X11/Xaw3d/Scrollbar.h>
113 #include <X11/Xaw3d/ThreeD.h>
114 #else /* !HAVE_XAW3D */
115 #include <X11/Xaw/Simple.h>
116 #include <X11/Xaw/Scrollbar.h>
117 #endif /* !HAVE_XAW3D */
118 #ifndef XtNpickTop
119 #define XtNpickTop "pickTop"
120 #endif /* !XtNpickTop */
121 #endif /* !USE_MOTIF */
122 #endif /* USE_TOOLKIT_SCROLL_BARS */
124 #endif /* USE_X_TOOLKIT */
126 #ifdef USE_X_TOOLKIT
127 #include "widget.h"
128 #ifndef XtNinitialState
129 #define XtNinitialState "initialState"
130 #endif
131 #endif
133 #include "bitmaps/gray.xbm"
135 #ifdef HAVE_XKB
136 #include <X11/XKBlib.h>
137 #endif
139 /* Default to using XIM if available. */
140 #ifdef USE_XIM
141 bool use_xim = true;
142 #else
143 bool use_xim = false; /* configure --without-xim */
144 #endif
146 /* Non-zero means that a HELP_EVENT has been generated since Emacs
147 start. */
149 static bool any_help_event_p;
151 /* This is a chain of structures for all the X displays currently in
152 use. */
154 struct x_display_info *x_display_list;
156 #ifdef USE_X_TOOLKIT
158 /* The application context for Xt use. */
159 XtAppContext Xt_app_con;
160 static String Xt_default_resources[] = {0};
162 /* Non-zero means user is interacting with a toolkit scroll bar. */
163 static bool toolkit_scroll_bar_interaction;
165 #endif /* USE_X_TOOLKIT */
167 /* Non-zero timeout value means ignore next mouse click if it arrives
168 before that timeout elapses (i.e. as part of the same sequence of
169 events resulting from clicking on a frame to select it). */
171 static Time ignore_next_mouse_click_timeout;
173 /* Used locally within XTread_socket. */
175 static int x_noop_count;
177 #ifdef USE_GTK
178 /* The name of the Emacs icon file. */
179 static Lisp_Object xg_default_icon_file;
180 #endif
182 /* Some functions take this as char *, not const char *. */
183 static char emacs_class[] = EMACS_CLASS;
185 enum xembed_info
187 XEMBED_MAPPED = 1 << 0
190 enum xembed_message
192 XEMBED_EMBEDDED_NOTIFY = 0,
193 XEMBED_WINDOW_ACTIVATE = 1,
194 XEMBED_WINDOW_DEACTIVATE = 2,
195 XEMBED_REQUEST_FOCUS = 3,
196 XEMBED_FOCUS_IN = 4,
197 XEMBED_FOCUS_OUT = 5,
198 XEMBED_FOCUS_NEXT = 6,
199 XEMBED_FOCUS_PREV = 7,
201 XEMBED_MODALITY_ON = 10,
202 XEMBED_MODALITY_OFF = 11,
203 XEMBED_REGISTER_ACCELERATOR = 12,
204 XEMBED_UNREGISTER_ACCELERATOR = 13,
205 XEMBED_ACTIVATE_ACCELERATOR = 14
208 static void x_free_cr_resources (struct frame *);
209 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
210 static void x_raise_frame (struct frame *);
211 static void x_lower_frame (struct frame *);
212 static int x_io_error_quitter (Display *);
213 static struct terminal *x_create_terminal (struct x_display_info *);
214 static void x_frame_rehighlight (struct x_display_info *);
216 static void x_clip_to_row (struct window *, struct glyph_row *,
217 enum glyph_row_area, GC);
218 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
219 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
220 enum scroll_bar_part *,
221 Lisp_Object *, Lisp_Object *,
222 Time *);
223 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
224 enum scroll_bar_part *,
225 Lisp_Object *, Lisp_Object *,
226 Time *);
227 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
228 static void x_check_fullscreen (struct frame *);
229 static void x_check_expected_move (struct frame *, int, int);
230 static void x_sync_with_move (struct frame *, int, int, bool);
231 static int handle_one_xevent (struct x_display_info *,
232 const XEvent *, int *,
233 struct input_event *);
234 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
235 static int x_dispatch_event (XEvent *, Display *);
236 #endif
237 static void x_wm_set_window_state (struct frame *, int);
238 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
239 static void x_initialize (void);
241 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
243 /* Flush display of frame F. */
245 static void
246 x_flush (struct frame *f)
248 eassert (f && FRAME_X_P (f));
249 /* Don't call XFlush when it is not safe to redisplay; the X
250 connection may be broken. */
251 if (!NILP (Vinhibit_redisplay))
252 return;
254 block_input ();
255 XFlush (FRAME_X_DISPLAY (f));
256 unblock_input ();
260 /* Remove calls to XFlush by defining XFlush to an empty replacement.
261 Calls to XFlush should be unnecessary because the X output buffer
262 is flushed automatically as needed by calls to XPending,
263 XNextEvent, or XWindowEvent according to the XFlush man page.
264 XTread_socket calls XPending. Removing XFlush improves
265 performance. */
267 #define XFlush(DISPLAY) (void) 0
270 /***********************************************************************
271 Debugging
272 ***********************************************************************/
274 #if false
276 /* This is a function useful for recording debugging information about
277 the sequence of occurrences in this file. */
279 struct record
281 char *locus;
282 int type;
285 struct record event_record[100];
287 int event_record_index;
289 void
290 record_event (char *locus, int type)
292 if (event_record_index == ARRAYELTS (event_record))
293 event_record_index = 0;
295 event_record[event_record_index].locus = locus;
296 event_record[event_record_index].type = type;
297 event_record_index++;
300 #endif
302 #ifdef USE_CAIRO
304 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
305 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
307 static struct x_gc_ext_data *
308 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
310 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
311 XEDataObject object;
312 XExtData **head, *ext_data;
314 object.gc = gc;
315 head = XEHeadOfExtensionList (object);
316 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
317 if (ext_data == NULL)
319 if (!create_if_not_found_p)
320 return NULL;
321 else
323 ext_data = xzalloc (sizeof (*ext_data));
324 ext_data->number = dpyinfo->ext_codes->extension;
325 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
326 XAddToExtensionList (head, ext_data);
329 return (struct x_gc_ext_data *) ext_data->private_data;
332 static void
333 x_extension_initialize (struct x_display_info *dpyinfo)
335 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
337 dpyinfo->ext_codes = ext_codes;
340 static void
341 x_cr_destroy_surface (struct frame *f)
343 if (FRAME_CR_SURFACE (f))
345 cairo_t *cr = FRAME_CR_CONTEXT (f);
346 cairo_surface_destroy (FRAME_CR_SURFACE (f));
347 FRAME_CR_SURFACE (f) = 0;
348 if (cr) cairo_destroy (cr);
349 FRAME_CR_CONTEXT (f) = NULL;
353 cairo_t *
354 x_begin_cr_clip (struct frame *f, GC gc)
356 cairo_t *cr = FRAME_CR_CONTEXT (f);
358 if (!cr)
361 if (! FRAME_CR_SURFACE (f))
363 cairo_surface_t *surface;
364 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
365 FRAME_X_DRAWABLE (f),
366 FRAME_DISPLAY_INFO (f)->visual,
367 FRAME_PIXEL_WIDTH (f),
368 FRAME_PIXEL_HEIGHT (f));
369 cr = cairo_create (surface);
370 cairo_surface_destroy (surface);
372 else
373 cr = cairo_create (FRAME_CR_SURFACE (f));
374 FRAME_CR_CONTEXT (f) = cr;
376 cairo_save (cr);
378 if (gc)
380 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
382 if (gc_ext && gc_ext->n_clip_rects)
384 int i;
386 for (i = 0; i < gc_ext->n_clip_rects; i++)
387 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
388 gc_ext->clip_rects[i].y,
389 gc_ext->clip_rects[i].width,
390 gc_ext->clip_rects[i].height);
391 cairo_clip (cr);
395 return cr;
398 void
399 x_end_cr_clip (struct frame *f)
401 cairo_restore (FRAME_CR_CONTEXT (f));
404 void
405 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
407 XGCValues xgcv;
408 XColor color;
410 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
411 color.pixel = xgcv.foreground;
412 x_query_color (f, &color);
413 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
414 color.green / 65535.0, color.blue / 65535.0);
417 void
418 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
420 XGCValues xgcv;
421 XColor color;
423 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
424 color.pixel = xgcv.background;
425 x_query_color (f, &color);
426 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
427 color.green / 65535.0, color.blue / 65535.0);
430 /* Fringe bitmaps. */
432 static int max_fringe_bmp = 0;
433 static cairo_pattern_t **fringe_bmp = 0;
435 static void
436 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
438 int i, stride;
439 cairo_surface_t *surface;
440 unsigned char *data;
441 cairo_pattern_t *pattern;
443 if (which >= max_fringe_bmp)
445 i = max_fringe_bmp;
446 max_fringe_bmp = which + 20;
447 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
448 while (i < max_fringe_bmp)
449 fringe_bmp[i++] = 0;
452 block_input ();
454 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
455 stride = cairo_image_surface_get_stride (surface);
456 data = cairo_image_surface_get_data (surface);
458 for (i = 0; i < h; i++)
460 *((unsigned short *) data) = bits[i];
461 data += stride;
464 cairo_surface_mark_dirty (surface);
465 pattern = cairo_pattern_create_for_surface (surface);
466 cairo_surface_destroy (surface);
468 unblock_input ();
470 fringe_bmp[which] = pattern;
473 static void
474 x_cr_destroy_fringe_bitmap (int which)
476 if (which >= max_fringe_bmp)
477 return;
479 if (fringe_bmp[which])
481 block_input ();
482 cairo_pattern_destroy (fringe_bmp[which]);
483 unblock_input ();
485 fringe_bmp[which] = 0;
488 static void
489 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
490 int src_x, int src_y, int width, int height,
491 int dest_x, int dest_y, bool overlay_p)
493 cairo_t *cr;
494 cairo_matrix_t matrix;
495 cairo_surface_t *surface;
496 cairo_format_t format;
498 cr = x_begin_cr_clip (f, gc);
499 if (overlay_p)
500 cairo_rectangle (cr, dest_x, dest_y, width, height);
501 else
503 x_set_cr_source_with_gc_background (f, gc);
504 cairo_rectangle (cr, dest_x, dest_y, width, height);
505 cairo_fill_preserve (cr);
507 cairo_clip (cr);
508 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
509 cairo_pattern_set_matrix (image, &matrix);
510 cairo_pattern_get_surface (image, &surface);
511 format = cairo_image_surface_get_format (surface);
512 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
514 cairo_set_source (cr, image);
515 cairo_fill (cr);
517 else
519 x_set_cr_source_with_gc_foreground (f, gc);
520 cairo_mask (cr, image);
522 x_end_cr_clip (f);
525 void
526 x_cr_draw_frame (cairo_t *cr, struct frame *f)
528 int width, height;
530 width = FRAME_PIXEL_WIDTH (f);
531 height = FRAME_PIXEL_HEIGHT (f);
533 x_free_cr_resources (f);
534 FRAME_CR_CONTEXT (f) = cr;
535 x_clear_area (f, 0, 0, width, height);
536 expose_frame (f, 0, 0, width, height);
537 FRAME_CR_CONTEXT (f) = NULL;
540 static cairo_status_t
541 x_cr_accumulate_data (void *closure, const unsigned char *data,
542 unsigned int length)
544 Lisp_Object *acc = (Lisp_Object *) closure;
546 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
548 return CAIRO_STATUS_SUCCESS;
551 static void
552 x_cr_destroy (Lisp_Object arg)
554 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
556 block_input ();
557 cairo_destroy (cr);
558 unblock_input ();
561 Lisp_Object
562 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
564 struct frame *f;
565 cairo_surface_t *surface;
566 cairo_t *cr;
567 int width, height;
568 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
569 Lisp_Object acc = Qnil;
570 ptrdiff_t count = SPECPDL_INDEX ();
572 specbind (Qredisplay_dont_pause, Qt);
573 redisplay_preserve_echo_area (31);
575 f = XFRAME (XCAR (frames));
576 frames = XCDR (frames);
577 width = FRAME_PIXEL_WIDTH (f);
578 height = FRAME_PIXEL_HEIGHT (f);
580 block_input ();
581 #ifdef CAIRO_HAS_PDF_SURFACE
582 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
584 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
585 width, height);
586 surface_set_size_func = cairo_pdf_surface_set_size;
588 else
589 #endif
590 #ifdef CAIRO_HAS_PNG_FUNCTIONS
591 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
592 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
593 else
594 #endif
595 #ifdef CAIRO_HAS_PS_SURFACE
596 if (surface_type == CAIRO_SURFACE_TYPE_PS)
598 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
599 width, height);
600 surface_set_size_func = cairo_ps_surface_set_size;
602 else
603 #endif
604 #ifdef CAIRO_HAS_SVG_SURFACE
605 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
606 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
607 width, height);
608 else
609 #endif
610 abort ();
612 cr = cairo_create (surface);
613 cairo_surface_destroy (surface);
614 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
616 while (1)
618 x_free_cr_resources (f);
619 FRAME_CR_CONTEXT (f) = cr;
620 x_clear_area (f, 0, 0, width, height);
621 expose_frame (f, 0, 0, width, height);
622 FRAME_CR_CONTEXT (f) = NULL;
624 if (NILP (frames))
625 break;
627 cairo_surface_show_page (surface);
628 f = XFRAME (XCAR (frames));
629 frames = XCDR (frames);
630 width = FRAME_PIXEL_WIDTH (f);
631 height = FRAME_PIXEL_HEIGHT (f);
632 if (surface_set_size_func)
633 (*surface_set_size_func) (surface, width, height);
635 unblock_input ();
636 maybe_quit ();
637 block_input ();
640 #ifdef CAIRO_HAS_PNG_FUNCTIONS
641 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
643 cairo_surface_flush (surface);
644 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
646 #endif
647 unblock_input ();
649 unbind_to (count, Qnil);
651 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
654 #endif /* USE_CAIRO */
656 static void
657 x_free_cr_resources (struct frame *f)
659 #ifdef USE_CAIRO
660 if (f == NULL)
662 Lisp_Object rest, frame;
663 FOR_EACH_FRAME (rest, frame)
664 if (FRAME_X_P (XFRAME (frame)))
665 x_free_cr_resources (XFRAME (frame));
667 else
669 cairo_t *cr = FRAME_CR_CONTEXT (f);
671 if (cr)
673 cairo_surface_t *surface = cairo_get_target (cr);
675 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
677 cairo_destroy (cr);
678 FRAME_CR_CONTEXT (f) = NULL;
682 #endif
685 static void
686 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
688 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
689 #ifdef USE_CAIRO
690 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
693 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
695 gc_ext->n_clip_rects = n;
696 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
698 #endif
701 static void
702 x_reset_clip_rectangles (struct frame *f, GC gc)
704 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
705 #ifdef USE_CAIRO
707 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
709 if (gc_ext)
710 gc_ext->n_clip_rects = 0;
712 #endif
715 static void
716 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
718 #ifdef USE_CAIRO
719 cairo_t *cr;
721 cr = x_begin_cr_clip (f, gc);
722 x_set_cr_source_with_gc_foreground (f, gc);
723 cairo_rectangle (cr, x, y, width, height);
724 cairo_fill (cr);
725 x_end_cr_clip (f);
726 #else
727 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
728 gc, x, y, width, height);
729 #endif
732 static void
733 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
735 #ifdef USE_CAIRO
736 cairo_t *cr;
738 cr = x_begin_cr_clip (f, gc);
739 x_set_cr_source_with_gc_foreground (f, gc);
740 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
741 cairo_set_line_width (cr, 1);
742 cairo_stroke (cr);
743 x_end_cr_clip (f);
744 #else
745 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
746 gc, x, y, width, height);
747 #endif
750 static void
751 x_clear_window (struct frame *f)
753 #ifdef USE_CAIRO
754 cairo_t *cr;
756 cr = x_begin_cr_clip (f, NULL);
757 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
758 cairo_paint (cr);
759 x_end_cr_clip (f);
760 #else
761 if (FRAME_X_DOUBLE_BUFFERED_P (f))
762 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
763 else
764 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
765 #endif
768 #ifdef USE_CAIRO
769 static void
770 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
771 int width, int height, int top_p)
773 cairo_t *cr;
775 cr = x_begin_cr_clip (f, gc);
776 x_set_cr_source_with_gc_foreground (f, gc);
777 cairo_move_to (cr, top_p ? x : x + height, y);
778 cairo_line_to (cr, x, y + height);
779 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
780 cairo_line_to (cr, x + width, y);
781 cairo_fill (cr);
782 x_end_cr_clip (f);
785 enum corners
787 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
788 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
789 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
790 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
791 CORNER_LAST
794 static void
795 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
796 int width, int height,
797 double radius, double margin, int corners)
799 cairo_t *cr;
800 int i;
802 cr = x_begin_cr_clip (f, gc);
803 x_set_cr_source_with_gc_background (f, gc);
804 for (i = 0; i < CORNER_LAST; i++)
805 if (corners & (1 << i))
807 double xm, ym, xc, yc;
809 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
810 xm = x - margin, xc = xm + radius;
811 else
812 xm = x + width + margin, xc = xm - radius;
813 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
814 ym = y - margin, yc = ym + radius;
815 else
816 ym = y + height + margin, yc = ym - radius;
818 cairo_move_to (cr, xm, ym);
819 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
821 cairo_clip (cr);
822 cairo_rectangle (cr, x, y, width, height);
823 cairo_fill (cr);
824 x_end_cr_clip (f);
827 static void
828 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
829 int width, int height, int wave_length)
831 cairo_t *cr;
832 double dx = wave_length, dy = height - 1;
833 int xoffset, n;
835 cr = x_begin_cr_clip (f, gc);
836 x_set_cr_source_with_gc_foreground (f, gc);
837 cairo_rectangle (cr, x, y, width, height);
838 cairo_clip (cr);
840 if (x >= 0)
842 xoffset = x % (wave_length * 2);
843 if (xoffset == 0)
844 xoffset = wave_length * 2;
846 else
847 xoffset = x % (wave_length * 2) + wave_length * 2;
848 n = (width + xoffset) / wave_length + 1;
849 if (xoffset > wave_length)
851 xoffset -= wave_length;
852 --n;
853 y += height - 1;
854 dy = -dy;
857 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
858 while (--n >= 0)
860 cairo_rel_line_to (cr, dx, dy);
861 dy = -dy;
863 cairo_set_line_width (cr, 1);
864 cairo_stroke (cr);
865 x_end_cr_clip (f);
867 #endif
870 /* Return the struct x_display_info corresponding to DPY. */
872 struct x_display_info *
873 x_display_info_for_display (Display *dpy)
875 struct x_display_info *dpyinfo;
877 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
878 if (dpyinfo->display == dpy)
879 return dpyinfo;
881 return 0;
884 static Window
885 x_find_topmost_parent (struct frame *f)
887 struct x_output *x = f->output_data.x;
888 Window win = None, wi = x->parent_desc;
889 Display *dpy = FRAME_X_DISPLAY (f);
891 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
893 Window root;
894 Window *children;
895 unsigned int nchildren;
897 win = wi;
898 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
899 XFree (children);
900 else
901 break;
904 return win;
907 #define OPAQUE 0xffffffff
909 void
910 x_set_frame_alpha (struct frame *f)
912 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
913 Display *dpy = FRAME_X_DISPLAY (f);
914 Window win = FRAME_OUTER_WINDOW (f);
915 double alpha = 1.0;
916 double alpha_min = 1.0;
917 unsigned long opac;
918 Window parent;
920 if (dpyinfo->x_highlight_frame == f)
921 alpha = f->alpha[0];
922 else
923 alpha = f->alpha[1];
925 if (FLOATP (Vframe_alpha_lower_limit))
926 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
927 else if (INTEGERP (Vframe_alpha_lower_limit))
928 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
930 if (alpha < 0.0)
931 return;
932 else if (alpha > 1.0)
933 alpha = 1.0;
934 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
935 alpha = alpha_min;
937 opac = alpha * OPAQUE;
939 x_catch_errors (dpy);
941 /* If there is a parent from the window manager, put the property there
942 also, to work around broken window managers that fail to do that.
943 Do this unconditionally as this function is called on reparent when
944 alpha has not changed on the frame. */
946 if (!FRAME_PARENT_FRAME (f))
948 parent = x_find_topmost_parent (f);
949 if (parent != None)
950 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
951 XA_CARDINAL, 32, PropModeReplace,
952 (unsigned char *) &opac, 1);
955 /* return unless necessary */
957 unsigned char *data;
958 Atom actual;
959 int rc, format;
960 unsigned long n, left;
962 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
963 0, 1, False, XA_CARDINAL,
964 &actual, &format, &n, &left,
965 &data);
967 if (rc == Success && actual != None)
969 unsigned long value = *(unsigned long *)data;
970 XFree (data);
971 if (value == opac)
973 x_uncatch_errors ();
974 return;
979 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
980 XA_CARDINAL, 32, PropModeReplace,
981 (unsigned char *) &opac, 1);
982 x_uncatch_errors ();
985 /***********************************************************************
986 Starting and ending an update
987 ***********************************************************************/
989 /* Start an update of frame F. This function is installed as a hook
990 for update_begin, i.e. it is called when update_begin is called.
991 This function is called prior to calls to x_update_window_begin for
992 each window being updated. Currently, there is nothing to do here
993 because all interesting stuff is done on a window basis. */
995 static void
996 x_update_begin (struct frame *f)
998 #ifdef USE_CAIRO
999 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
1000 && ! FRAME_VISIBLE_P (f))
1001 return;
1003 if (! FRAME_CR_SURFACE (f))
1005 int width, height;
1006 #ifdef USE_GTK
1007 if (FRAME_GTK_WIDGET (f))
1009 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1010 width = gdk_window_get_width (w);
1011 height = gdk_window_get_height (w);
1013 else
1014 #endif
1016 width = FRAME_PIXEL_WIDTH (f);
1017 height = FRAME_PIXEL_HEIGHT (f);
1018 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1019 height += FRAME_TOOL_BAR_HEIGHT (f);
1020 if (! FRAME_EXTERNAL_MENU_BAR (f))
1021 height += FRAME_MENU_BAR_HEIGHT (f);
1024 if (width > 0 && height > 0)
1026 block_input();
1027 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1028 (CAIRO_FORMAT_ARGB32, width, height);
1029 unblock_input();
1032 #endif /* USE_CAIRO */
1035 /* Start update of window W. */
1037 static void
1038 x_update_window_begin (struct window *w)
1040 struct frame *f = XFRAME (WINDOW_FRAME (w));
1041 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1043 w->output_cursor = w->cursor;
1045 block_input ();
1047 if (f == hlinfo->mouse_face_mouse_frame)
1049 /* Don't do highlighting for mouse motion during the update. */
1050 hlinfo->mouse_face_defer = true;
1052 /* If F needs to be redrawn, simply forget about any prior mouse
1053 highlighting. */
1054 if (FRAME_GARBAGED_P (f))
1055 hlinfo->mouse_face_window = Qnil;
1058 unblock_input ();
1062 /* Draw a vertical window border from (x,y0) to (x,y1) */
1064 static void
1065 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1067 struct frame *f = XFRAME (WINDOW_FRAME (w));
1068 struct face *face;
1070 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1071 if (face)
1072 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1073 face->foreground);
1075 #ifdef USE_CAIRO
1076 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1077 #else
1078 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1079 f->output_data.x->normal_gc, x, y0, x, y1);
1080 #endif
1083 /* Draw a window divider from (x0,y0) to (x1,y1) */
1085 static void
1086 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1088 struct frame *f = XFRAME (WINDOW_FRAME (w));
1089 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1090 struct face *face_first
1091 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1092 struct face *face_last
1093 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1094 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1095 unsigned long color_first = (face_first
1096 ? face_first->foreground
1097 : FRAME_FOREGROUND_PIXEL (f));
1098 unsigned long color_last = (face_last
1099 ? face_last->foreground
1100 : FRAME_FOREGROUND_PIXEL (f));
1101 Display *display = FRAME_X_DISPLAY (f);
1103 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1104 /* Vertical. */
1106 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1107 x_fill_rectangle (f, f->output_data.x->normal_gc,
1108 x0, y0, 1, y1 - y0);
1109 XSetForeground (display, f->output_data.x->normal_gc, color);
1110 x_fill_rectangle (f, f->output_data.x->normal_gc,
1111 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1112 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1113 x_fill_rectangle (f, f->output_data.x->normal_gc,
1114 x1 - 1, y0, 1, y1 - y0);
1116 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1117 /* Horizontal. */
1119 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1120 x_fill_rectangle (f, f->output_data.x->normal_gc,
1121 x0, y0, x1 - x0, 1);
1122 XSetForeground (display, f->output_data.x->normal_gc, color);
1123 x_fill_rectangle (f, f->output_data.x->normal_gc,
1124 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1125 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1126 x_fill_rectangle (f, f->output_data.x->normal_gc,
1127 x0, y1 - 1, x1 - x0, 1);
1129 else
1131 XSetForeground (display, f->output_data.x->normal_gc, color);
1132 x_fill_rectangle (f, f->output_data.x->normal_gc,
1133 x0, y0, x1 - x0, y1 - y0);
1137 /* End update of window W.
1139 Draw vertical borders between horizontally adjacent windows, and
1140 display W's cursor if CURSOR_ON_P is non-zero.
1142 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1143 glyphs in mouse-face were overwritten. In that case we have to
1144 make sure that the mouse-highlight is properly redrawn.
1146 W may be a menu bar pseudo-window in case we don't have X toolkit
1147 support. Such windows don't have a cursor, so don't display it
1148 here. */
1150 static void
1151 x_update_window_end (struct window *w, bool cursor_on_p,
1152 bool mouse_face_overwritten_p)
1154 if (!w->pseudo_window_p)
1156 block_input ();
1158 if (cursor_on_p)
1159 display_and_set_cursor (w, true,
1160 w->output_cursor.hpos, w->output_cursor.vpos,
1161 w->output_cursor.x, w->output_cursor.y);
1163 if (draw_window_fringes (w, true))
1165 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1166 x_draw_right_divider (w);
1167 else
1168 x_draw_vertical_border (w);
1171 unblock_input ();
1174 /* If a row with mouse-face was overwritten, arrange for
1175 XTframe_up_to_date to redisplay the mouse highlight. */
1176 if (mouse_face_overwritten_p)
1178 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1180 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1181 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1182 hlinfo->mouse_face_window = Qnil;
1186 /* Show the frame back buffer. If frame is double-buffered,
1187 atomically publish to the user's screen graphics updates made since
1188 the last call to show_back_buffer. */
1189 static void
1190 show_back_buffer (struct frame *f)
1192 block_input ();
1193 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1195 #ifdef HAVE_XDBE
1196 XdbeSwapInfo swap_info;
1197 memset (&swap_info, 0, sizeof (swap_info));
1198 swap_info.swap_window = FRAME_X_WINDOW (f);
1199 swap_info.swap_action = XdbeCopied;
1200 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1201 #else
1202 eassert (!"should have back-buffer only with XDBE");
1203 #endif
1205 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1206 unblock_input ();
1209 /* Updates back buffer and flushes changes to display. Called from
1210 minibuf read code. Note that we display the back buffer even if
1211 buffer flipping is blocked. */
1212 static void
1213 x_flip_and_flush (struct frame *f)
1215 block_input ();
1216 if (FRAME_X_NEED_BUFFER_FLIP (f))
1217 show_back_buffer (f);
1218 x_flush (f);
1219 unblock_input ();
1222 /* End update of frame F. This function is installed as a hook in
1223 update_end. */
1225 static void
1226 x_update_end (struct frame *f)
1228 /* Mouse highlight may be displayed again. */
1229 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1231 #ifdef USE_CAIRO
1232 if (FRAME_CR_SURFACE (f))
1234 cairo_t *cr = 0;
1235 block_input();
1236 #if defined (USE_GTK) && defined (HAVE_GTK3)
1237 if (FRAME_GTK_WIDGET (f))
1239 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1240 cr = gdk_cairo_create (w);
1242 else
1243 #endif
1245 cairo_surface_t *surface;
1246 int width = FRAME_PIXEL_WIDTH (f);
1247 int height = FRAME_PIXEL_HEIGHT (f);
1248 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1249 height += FRAME_TOOL_BAR_HEIGHT (f);
1250 if (! FRAME_EXTERNAL_MENU_BAR (f))
1251 height += FRAME_MENU_BAR_HEIGHT (f);
1252 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1253 FRAME_X_DRAWABLE (f),
1254 FRAME_DISPLAY_INFO (f)->visual,
1255 width,
1256 height);
1257 cr = cairo_create (surface);
1258 cairo_surface_destroy (surface);
1261 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1262 cairo_paint (cr);
1263 cairo_destroy (cr);
1264 unblock_input ();
1266 #endif
1268 #ifndef XFlush
1269 block_input ();
1270 XFlush (FRAME_X_DISPLAY (f));
1271 unblock_input ();
1272 #endif
1275 /* This function is called from various places in xdisp.c
1276 whenever a complete update has been performed. */
1278 static void
1279 XTframe_up_to_date (struct frame *f)
1281 eassert (FRAME_X_P (f));
1282 block_input ();
1283 FRAME_MOUSE_UPDATE (f);
1284 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1285 show_back_buffer (f);
1286 unblock_input ();
1289 static void
1290 XTbuffer_flipping_unblocked_hook (struct frame *f)
1292 if (FRAME_X_NEED_BUFFER_FLIP (f))
1293 show_back_buffer (f);
1297 * x_clear_under_internal_border:
1299 * Clear area of frame F's internal border. If the internal border face
1300 * of F has been specified (is not null), fill the area with that face.
1302 void
1303 x_clear_under_internal_border (struct frame *f)
1305 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1307 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1308 int width = FRAME_PIXEL_WIDTH (f);
1309 int height = FRAME_PIXEL_HEIGHT (f);
1310 #ifdef USE_GTK
1311 int margin = 0;
1312 #else
1313 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1314 #endif
1315 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1317 block_input ();
1319 if (face)
1321 unsigned long color = face->background;
1322 Display *display = FRAME_X_DISPLAY (f);
1323 GC gc = f->output_data.x->normal_gc;
1325 XSetForeground (display, gc, color);
1326 x_fill_rectangle (f, gc, 0, margin, width, border);
1327 x_fill_rectangle (f, gc, 0, 0, border, height);
1328 x_fill_rectangle (f, gc, width - border, 0, border, height);
1329 x_fill_rectangle (f, gc, 0, height - border, width, border);
1330 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1332 else
1334 x_clear_area (f, 0, 0, border, height);
1335 x_clear_area (f, 0, margin, width, border);
1336 x_clear_area (f, width - border, 0, border, height);
1337 x_clear_area (f, 0, height - border, width, border);
1340 unblock_input ();
1344 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1345 arrow bitmaps, or clear the fringes if no bitmaps are required
1346 before DESIRED_ROW is made current. This function is called from
1347 update_window_line only if it is known that there are differences
1348 between bitmaps to be drawn between current row and DESIRED_ROW. */
1350 static void
1351 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1353 eassert (w);
1355 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1356 desired_row->redraw_fringe_bitmaps_p = true;
1358 #ifdef USE_X_TOOLKIT
1359 /* When a window has disappeared, make sure that no rest of
1360 full-width rows stays visible in the internal border. Could
1361 check here if updated window is the leftmost/rightmost window,
1362 but I guess it's not worth doing since vertically split windows
1363 are almost never used, internal border is rarely set, and the
1364 overhead is very small. */
1366 struct frame *f;
1367 int width, height;
1369 if (windows_or_buffers_changed
1370 && desired_row->full_width_p
1371 && (f = XFRAME (w->frame),
1372 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1373 width != 0)
1374 && (height = desired_row->visible_height,
1375 height > 0))
1377 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1378 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1380 block_input ();
1381 if (face)
1383 unsigned long color = face->background;
1384 Display *display = FRAME_X_DISPLAY (f);
1385 GC gc = f->output_data.x->normal_gc;
1387 XSetForeground (display, gc, color);
1388 x_fill_rectangle (f, gc, 0, y, width, height);
1389 x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
1390 width, height);
1391 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1393 else
1395 x_clear_area (f, 0, y, width, height);
1396 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1398 unblock_input ();
1401 #endif
1404 static void
1405 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1407 struct frame *f = XFRAME (WINDOW_FRAME (w));
1408 Display *display = FRAME_X_DISPLAY (f);
1409 GC gc = f->output_data.x->normal_gc;
1410 struct face *face = p->face;
1412 /* Must clip because of partially visible lines. */
1413 x_clip_to_row (w, row, ANY_AREA, gc);
1415 if (p->bx >= 0 && !p->overlay_p)
1417 /* In case the same realized face is used for fringes and
1418 for something displayed in the text (e.g. face `region' on
1419 mono-displays, the fill style may have been changed to
1420 FillSolid in x_draw_glyph_string_background. */
1421 if (face->stipple)
1422 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1423 else
1424 XSetForeground (display, face->gc, face->background);
1426 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1428 if (!face->stipple)
1429 XSetForeground (display, face->gc, face->foreground);
1432 #ifdef USE_CAIRO
1433 if (p->which && p->which < max_fringe_bmp)
1435 XGCValues gcv;
1437 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1438 XSetForeground (display, gc, (p->cursor_p
1439 ? (p->overlay_p ? face->background
1440 : f->output_data.x->cursor_pixel)
1441 : face->foreground));
1442 XSetBackground (display, gc, face->background);
1443 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1444 p->wd, p->h, p->x, p->y, p->overlay_p);
1445 XSetForeground (display, gc, gcv.foreground);
1446 XSetBackground (display, gc, gcv.background);
1448 #else /* not USE_CAIRO */
1449 if (p->which)
1451 Drawable drawable = FRAME_X_DRAWABLE (f);
1452 char *bits;
1453 Pixmap pixmap, clipmask = (Pixmap) 0;
1454 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1455 XGCValues gcv;
1457 if (p->wd > 8)
1458 bits = (char *) (p->bits + p->dh);
1459 else
1460 bits = (char *) p->bits + p->dh;
1462 /* Draw the bitmap. I believe these small pixmaps can be cached
1463 by the server. */
1464 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1465 (p->cursor_p
1466 ? (p->overlay_p ? face->background
1467 : f->output_data.x->cursor_pixel)
1468 : face->foreground),
1469 face->background, depth);
1471 if (p->overlay_p)
1473 clipmask = XCreatePixmapFromBitmapData (display,
1474 FRAME_DISPLAY_INFO (f)->root_window,
1475 bits, p->wd, p->h,
1476 1, 0, 1);
1477 gcv.clip_mask = clipmask;
1478 gcv.clip_x_origin = p->x;
1479 gcv.clip_y_origin = p->y;
1480 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1483 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1484 p->wd, p->h, p->x, p->y);
1485 XFreePixmap (display, pixmap);
1487 if (p->overlay_p)
1489 gcv.clip_mask = (Pixmap) 0;
1490 XChangeGC (display, gc, GCClipMask, &gcv);
1491 XFreePixmap (display, clipmask);
1494 #endif /* not USE_CAIRO */
1496 x_reset_clip_rectangles (f, gc);
1499 /***********************************************************************
1500 Glyph display
1501 ***********************************************************************/
1505 static void x_set_glyph_string_clipping (struct glyph_string *);
1506 static void x_set_glyph_string_gc (struct glyph_string *);
1507 static void x_draw_glyph_string_foreground (struct glyph_string *);
1508 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1509 static void x_draw_glyph_string_box (struct glyph_string *);
1510 static void x_draw_glyph_string (struct glyph_string *);
1511 static _Noreturn void x_delete_glyphs (struct frame *, int);
1512 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1513 static void x_set_cursor_gc (struct glyph_string *);
1514 static void x_set_mode_line_face_gc (struct glyph_string *);
1515 static void x_set_mouse_face_gc (struct glyph_string *);
1516 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1517 unsigned long *, double, int);
1518 static void x_setup_relief_color (struct frame *, struct relief *,
1519 double, int, unsigned long);
1520 static void x_setup_relief_colors (struct glyph_string *);
1521 static void x_draw_image_glyph_string (struct glyph_string *);
1522 static void x_draw_image_relief (struct glyph_string *);
1523 static void x_draw_image_foreground (struct glyph_string *);
1524 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1525 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1526 int, int, int);
1527 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1528 int, bool, bool, bool, bool, bool,
1529 XRectangle *);
1530 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1531 int, bool, bool, XRectangle *);
1532 static void x_scroll_bar_clear (struct frame *);
1534 #ifdef GLYPH_DEBUG
1535 static void x_check_font (struct frame *, struct font *);
1536 #endif
1539 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1540 face. */
1542 static void
1543 x_set_cursor_gc (struct glyph_string *s)
1545 if (s->font == FRAME_FONT (s->f)
1546 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1547 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1548 && !s->cmp)
1549 s->gc = s->f->output_data.x->cursor_gc;
1550 else
1552 /* Cursor on non-default face: must merge. */
1553 XGCValues xgcv;
1554 unsigned long mask;
1556 xgcv.background = s->f->output_data.x->cursor_pixel;
1557 xgcv.foreground = s->face->background;
1559 /* If the glyph would be invisible, try a different foreground. */
1560 if (xgcv.foreground == xgcv.background)
1561 xgcv.foreground = s->face->foreground;
1562 if (xgcv.foreground == xgcv.background)
1563 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1564 if (xgcv.foreground == xgcv.background)
1565 xgcv.foreground = s->face->foreground;
1567 /* Make sure the cursor is distinct from text in this face. */
1568 if (xgcv.background == s->face->background
1569 && xgcv.foreground == s->face->foreground)
1571 xgcv.background = s->face->foreground;
1572 xgcv.foreground = s->face->background;
1575 IF_DEBUG (x_check_font (s->f, s->font));
1576 xgcv.graphics_exposures = False;
1577 mask = GCForeground | GCBackground | GCGraphicsExposures;
1579 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1580 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1581 mask, &xgcv);
1582 else
1583 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1584 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1586 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1591 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1593 static void
1594 x_set_mouse_face_gc (struct glyph_string *s)
1596 int face_id;
1597 struct face *face;
1599 /* What face has to be used last for the mouse face? */
1600 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1601 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1602 if (face == NULL)
1603 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1605 if (s->first_glyph->type == CHAR_GLYPH)
1606 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1607 else
1608 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1609 s->face = FACE_FROM_ID (s->f, face_id);
1610 prepare_face_for_display (s->f, s->face);
1612 if (s->font == s->face->font)
1613 s->gc = s->face->gc;
1614 else
1616 /* Otherwise construct scratch_cursor_gc with values from FACE
1617 except for FONT. */
1618 XGCValues xgcv;
1619 unsigned long mask;
1621 xgcv.background = s->face->background;
1622 xgcv.foreground = s->face->foreground;
1623 xgcv.graphics_exposures = False;
1624 mask = GCForeground | GCBackground | GCGraphicsExposures;
1626 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1627 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1628 mask, &xgcv);
1629 else
1630 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1631 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1633 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1636 eassert (s->gc != 0);
1640 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1641 Faces to use in the mode line have already been computed when the
1642 matrix was built, so there isn't much to do, here. */
1644 static void
1645 x_set_mode_line_face_gc (struct glyph_string *s)
1647 s->gc = s->face->gc;
1651 /* Set S->gc of glyph string S for drawing that glyph string. Set
1652 S->stippled_p to a non-zero value if the face of S has a stipple
1653 pattern. */
1655 static void
1656 x_set_glyph_string_gc (struct glyph_string *s)
1658 prepare_face_for_display (s->f, s->face);
1660 if (s->hl == DRAW_NORMAL_TEXT)
1662 s->gc = s->face->gc;
1663 s->stippled_p = s->face->stipple != 0;
1665 else if (s->hl == DRAW_INVERSE_VIDEO)
1667 x_set_mode_line_face_gc (s);
1668 s->stippled_p = s->face->stipple != 0;
1670 else if (s->hl == DRAW_CURSOR)
1672 x_set_cursor_gc (s);
1673 s->stippled_p = false;
1675 else if (s->hl == DRAW_MOUSE_FACE)
1677 x_set_mouse_face_gc (s);
1678 s->stippled_p = s->face->stipple != 0;
1680 else if (s->hl == DRAW_IMAGE_RAISED
1681 || s->hl == DRAW_IMAGE_SUNKEN)
1683 s->gc = s->face->gc;
1684 s->stippled_p = s->face->stipple != 0;
1686 else
1687 emacs_abort ();
1689 /* GC must have been set. */
1690 eassert (s->gc != 0);
1694 /* Set clipping for output of glyph string S. S may be part of a mode
1695 line or menu if we don't have X toolkit support. */
1697 static void
1698 x_set_glyph_string_clipping (struct glyph_string *s)
1700 XRectangle *r = s->clip;
1701 int n = get_glyph_string_clip_rects (s, r, 2);
1703 if (n > 0)
1704 x_set_clip_rectangles (s->f, s->gc, r, n);
1705 s->num_clips = n;
1709 /* Set SRC's clipping for output of glyph string DST. This is called
1710 when we are drawing DST's left_overhang or right_overhang only in
1711 the area of SRC. */
1713 static void
1714 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1716 XRectangle r;
1718 r.x = src->x;
1719 r.width = src->width;
1720 r.y = src->y;
1721 r.height = src->height;
1722 dst->clip[0] = r;
1723 dst->num_clips = 1;
1724 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1728 /* RIF:
1729 Compute left and right overhang of glyph string S. */
1731 static void
1732 x_compute_glyph_string_overhangs (struct glyph_string *s)
1734 if (s->cmp == NULL
1735 && (s->first_glyph->type == CHAR_GLYPH
1736 || s->first_glyph->type == COMPOSITE_GLYPH))
1738 struct font_metrics metrics;
1740 if (s->first_glyph->type == CHAR_GLYPH)
1742 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1743 struct font *font = s->font;
1744 int i;
1746 for (i = 0; i < s->nchars; i++)
1747 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1748 font->driver->text_extents (font, code, s->nchars, &metrics);
1750 else
1752 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1754 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1756 s->right_overhang = (metrics.rbearing > metrics.width
1757 ? metrics.rbearing - metrics.width : 0);
1758 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1760 else if (s->cmp)
1762 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1763 s->left_overhang = - s->cmp->lbearing;
1768 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1770 static void
1771 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1773 XGCValues xgcv;
1774 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1775 XSetForeground (s->display, s->gc, xgcv.background);
1776 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1777 XSetForeground (s->display, s->gc, xgcv.foreground);
1781 /* Draw the background of glyph_string S. If S->background_filled_p
1782 is non-zero don't draw it. FORCE_P non-zero means draw the
1783 background even if it wouldn't be drawn normally. This is used
1784 when a string preceding S draws into the background of S, or S
1785 contains the first component of a composition. */
1787 static void
1788 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1790 /* Nothing to do if background has already been drawn or if it
1791 shouldn't be drawn in the first place. */
1792 if (!s->background_filled_p)
1794 int box_line_width = max (s->face->box_line_width, 0);
1796 if (s->stippled_p)
1798 /* Fill background with a stipple pattern. */
1799 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1800 x_fill_rectangle (s->f, s->gc, s->x,
1801 s->y + box_line_width,
1802 s->background_width,
1803 s->height - 2 * box_line_width);
1804 XSetFillStyle (s->display, s->gc, FillSolid);
1805 s->background_filled_p = true;
1807 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1808 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1809 font dimensions, since the actual glyphs might be
1810 much smaller. So in that case we always clear the
1811 rectangle with background color. */
1812 || FONT_TOO_HIGH (s->font)
1813 || s->font_not_found_p
1814 || s->extends_to_end_of_line_p
1815 || force_p)
1817 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1818 s->background_width,
1819 s->height - 2 * box_line_width);
1820 s->background_filled_p = true;
1826 /* Draw the foreground of glyph string S. */
1828 static void
1829 x_draw_glyph_string_foreground (struct glyph_string *s)
1831 int i, x;
1833 /* If first glyph of S has a left box line, start drawing the text
1834 of S to the right of that box line. */
1835 if (s->face->box != FACE_NO_BOX
1836 && s->first_glyph->left_box_line_p)
1837 x = s->x + eabs (s->face->box_line_width);
1838 else
1839 x = s->x;
1841 /* Draw characters of S as rectangles if S's font could not be
1842 loaded. */
1843 if (s->font_not_found_p)
1845 for (i = 0; i < s->nchars; ++i)
1847 struct glyph *g = s->first_glyph + i;
1848 x_draw_rectangle (s->f,
1849 s->gc, x, s->y, g->pixel_width - 1,
1850 s->height - 1);
1851 x += g->pixel_width;
1854 else
1856 struct font *font = s->font;
1857 int boff = font->baseline_offset;
1858 int y;
1860 if (font->vertical_centering)
1861 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1863 y = s->ybase - boff;
1864 if (s->for_overlaps
1865 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1866 font->driver->draw (s, 0, s->nchars, x, y, false);
1867 else
1868 font->driver->draw (s, 0, s->nchars, x, y, true);
1869 if (s->face->overstrike)
1870 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1874 /* Draw the foreground of composite glyph string S. */
1876 static void
1877 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1879 int i, j, x;
1880 struct font *font = s->font;
1882 /* If first glyph of S has a left box line, start drawing the text
1883 of S to the right of that box line. */
1884 if (s->face && s->face->box != FACE_NO_BOX
1885 && s->first_glyph->left_box_line_p)
1886 x = s->x + eabs (s->face->box_line_width);
1887 else
1888 x = s->x;
1890 /* S is a glyph string for a composition. S->cmp_from is the index
1891 of the first character drawn for glyphs of this composition.
1892 S->cmp_from == 0 means we are drawing the very first character of
1893 this composition. */
1895 /* Draw a rectangle for the composition if the font for the very
1896 first character of the composition could not be loaded. */
1897 if (s->font_not_found_p)
1899 if (s->cmp_from == 0)
1900 x_draw_rectangle (s->f, s->gc, x, s->y,
1901 s->width - 1, s->height - 1);
1903 else if (! s->first_glyph->u.cmp.automatic)
1905 int y = s->ybase;
1907 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1908 /* TAB in a composition means display glyphs with padding
1909 space on the left or right. */
1910 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1912 int xx = x + s->cmp->offsets[j * 2];
1913 int yy = y - s->cmp->offsets[j * 2 + 1];
1915 font->driver->draw (s, j, j + 1, xx, yy, false);
1916 if (s->face->overstrike)
1917 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1920 else
1922 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1923 Lisp_Object glyph;
1924 int y = s->ybase;
1925 int width = 0;
1927 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1929 glyph = LGSTRING_GLYPH (gstring, i);
1930 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1931 width += LGLYPH_WIDTH (glyph);
1932 else
1934 int xoff, yoff, wadjust;
1936 if (j < i)
1938 font->driver->draw (s, j, i, x, y, false);
1939 if (s->face->overstrike)
1940 font->driver->draw (s, j, i, x + 1, y, false);
1941 x += width;
1943 xoff = LGLYPH_XOFF (glyph);
1944 yoff = LGLYPH_YOFF (glyph);
1945 wadjust = LGLYPH_WADJUST (glyph);
1946 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1947 if (s->face->overstrike)
1948 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1949 false);
1950 x += wadjust;
1951 j = i + 1;
1952 width = 0;
1955 if (j < i)
1957 font->driver->draw (s, j, i, x, y, false);
1958 if (s->face->overstrike)
1959 font->driver->draw (s, j, i, x + 1, y, false);
1965 /* Draw the foreground of glyph string S for glyphless characters. */
1967 static void
1968 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1970 struct glyph *glyph = s->first_glyph;
1971 XChar2b char2b[8];
1972 int x, i, j;
1974 /* If first glyph of S has a left box line, start drawing the text
1975 of S to the right of that box line. */
1976 if (s->face && s->face->box != FACE_NO_BOX
1977 && s->first_glyph->left_box_line_p)
1978 x = s->x + eabs (s->face->box_line_width);
1979 else
1980 x = s->x;
1982 s->char2b = char2b;
1984 for (i = 0; i < s->nchars; i++, glyph++)
1986 char buf[7], *str = NULL;
1987 int len = glyph->u.glyphless.len;
1989 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1991 if (len > 0
1992 && CHAR_TABLE_P (Vglyphless_char_display)
1993 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1994 >= 1))
1996 Lisp_Object acronym
1997 = (! glyph->u.glyphless.for_no_font
1998 ? CHAR_TABLE_REF (Vglyphless_char_display,
1999 glyph->u.glyphless.ch)
2000 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
2001 if (STRINGP (acronym))
2002 str = SSDATA (acronym);
2005 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
2007 unsigned int ch = glyph->u.glyphless.ch;
2008 eassume (ch <= MAX_CHAR);
2009 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
2010 str = buf;
2013 if (str)
2015 int upper_len = (len + 1) / 2;
2016 unsigned code;
2018 /* It is assured that all LEN characters in STR is ASCII. */
2019 for (j = 0; j < len; j++)
2021 code = s->font->driver->encode_char (s->font, str[j]);
2022 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
2024 s->font->driver->draw (s, 0, upper_len,
2025 x + glyph->slice.glyphless.upper_xoff,
2026 s->ybase + glyph->slice.glyphless.upper_yoff,
2027 false);
2028 s->font->driver->draw (s, upper_len, len,
2029 x + glyph->slice.glyphless.lower_xoff,
2030 s->ybase + glyph->slice.glyphless.lower_yoff,
2031 false);
2033 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
2034 x_draw_rectangle (s->f, s->gc,
2035 x, s->ybase - glyph->ascent,
2036 glyph->pixel_width - 1,
2037 glyph->ascent + glyph->descent - 1);
2038 x += glyph->pixel_width;
2042 #ifdef USE_X_TOOLKIT
2044 #ifdef USE_LUCID
2046 /* Return the frame on which widget WIDGET is used.. Abort if frame
2047 cannot be determined. */
2049 static struct frame *
2050 x_frame_of_widget (Widget widget)
2052 struct x_display_info *dpyinfo;
2053 Lisp_Object tail, frame;
2054 struct frame *f;
2056 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2058 /* Find the top-level shell of the widget. Note that this function
2059 can be called when the widget is not yet realized, so XtWindow
2060 (widget) == 0. That's the reason we can't simply use
2061 x_any_window_to_frame. */
2062 while (!XtIsTopLevelShell (widget))
2063 widget = XtParent (widget);
2065 /* Look for a frame with that top-level widget. Allocate the color
2066 on that frame to get the right gamma correction value. */
2067 FOR_EACH_FRAME (tail, frame)
2069 f = XFRAME (frame);
2070 if (FRAME_X_P (f)
2071 && f->output_data.nothing != 1
2072 && FRAME_DISPLAY_INFO (f) == dpyinfo
2073 && f->output_data.x->widget == widget)
2074 return f;
2076 emacs_abort ();
2079 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2080 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2081 If this produces the same color as PIXEL, try a color where all RGB
2082 values have DELTA added. Return the allocated color in *PIXEL.
2083 DISPLAY is the X display, CMAP is the colormap to operate on.
2084 Value is true if successful. */
2086 bool
2087 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2088 unsigned long *pixel, double factor, int delta)
2090 struct frame *f = x_frame_of_widget (widget);
2091 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2094 #endif /* USE_LUCID */
2097 /* Structure specifying which arguments should be passed by Xt to
2098 cvt_string_to_pixel. We want the widget's screen and colormap. */
2100 static XtConvertArgRec cvt_string_to_pixel_args[] =
2102 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2103 sizeof (Screen *)},
2104 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2105 sizeof (Colormap)}
2109 /* The address of this variable is returned by
2110 cvt_string_to_pixel. */
2112 static Pixel cvt_string_to_pixel_value;
2115 /* Convert a color name to a pixel color.
2117 DPY is the display we are working on.
2119 ARGS is an array of *NARGS XrmValue structures holding additional
2120 information about the widget for which the conversion takes place.
2121 The contents of this array are determined by the specification
2122 in cvt_string_to_pixel_args.
2124 FROM is a pointer to an XrmValue which points to the color name to
2125 convert. TO is an XrmValue in which to return the pixel color.
2127 CLOSURE_RET is a pointer to user-data, in which we record if
2128 we allocated the color or not.
2130 Value is True if successful, False otherwise. */
2132 static Boolean
2133 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2134 XrmValue *from, XrmValue *to,
2135 XtPointer *closure_ret)
2137 Screen *screen;
2138 Colormap cmap;
2139 Pixel pixel;
2140 String color_name;
2141 XColor color;
2143 if (*nargs != 2)
2145 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2146 "wrongParameters", "cvt_string_to_pixel",
2147 "XtToolkitError",
2148 "Screen and colormap args required", NULL, NULL);
2149 return False;
2152 screen = *(Screen **) args[0].addr;
2153 cmap = *(Colormap *) args[1].addr;
2154 color_name = (String) from->addr;
2156 if (strcmp (color_name, XtDefaultBackground) == 0)
2158 *closure_ret = (XtPointer) False;
2159 pixel = WhitePixelOfScreen (screen);
2161 else if (strcmp (color_name, XtDefaultForeground) == 0)
2163 *closure_ret = (XtPointer) False;
2164 pixel = BlackPixelOfScreen (screen);
2166 else if (XParseColor (dpy, cmap, color_name, &color)
2167 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2169 pixel = color.pixel;
2170 *closure_ret = (XtPointer) True;
2172 else
2174 String params[1];
2175 Cardinal nparams = 1;
2177 params[0] = color_name;
2178 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2179 "badValue", "cvt_string_to_pixel",
2180 "XtToolkitError", "Invalid color '%s'",
2181 params, &nparams);
2182 return False;
2185 if (to->addr != NULL)
2187 if (to->size < sizeof (Pixel))
2189 to->size = sizeof (Pixel);
2190 return False;
2193 *(Pixel *) to->addr = pixel;
2195 else
2197 cvt_string_to_pixel_value = pixel;
2198 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2201 to->size = sizeof (Pixel);
2202 return True;
2206 /* Free a pixel color which was previously allocated via
2207 cvt_string_to_pixel. This is registered as the destructor
2208 for this type of resource via XtSetTypeConverter.
2210 APP is the application context in which we work.
2212 TO is a pointer to an XrmValue holding the color to free.
2213 CLOSURE is the value we stored in CLOSURE_RET for this color
2214 in cvt_string_to_pixel.
2216 ARGS and NARGS are like for cvt_string_to_pixel. */
2218 static void
2219 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2220 Cardinal *nargs)
2222 if (*nargs != 2)
2224 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2225 "XtToolkitError",
2226 "Screen and colormap arguments required",
2227 NULL, NULL);
2229 else if (closure != NULL)
2231 /* We did allocate the pixel, so free it. */
2232 Screen *screen = *(Screen **) args[0].addr;
2233 Colormap cmap = *(Colormap *) args[1].addr;
2234 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2235 (Pixel *) to->addr, 1);
2240 #endif /* USE_X_TOOLKIT */
2243 /* Value is an array of XColor structures for the contents of the
2244 color map of display DPY. Set *NCELLS to the size of the array.
2245 Note that this probably shouldn't be called for large color maps,
2246 say a 24-bit TrueColor map. */
2248 static const XColor *
2249 x_color_cells (Display *dpy, int *ncells)
2251 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2252 eassume (dpyinfo);
2254 if (dpyinfo->color_cells == NULL)
2256 Screen *screen = dpyinfo->screen;
2257 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2258 int i;
2260 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2261 sizeof *dpyinfo->color_cells);
2262 dpyinfo->ncolor_cells = ncolor_cells;
2264 for (i = 0; i < ncolor_cells; ++i)
2265 dpyinfo->color_cells[i].pixel = i;
2267 XQueryColors (dpy, dpyinfo->cmap,
2268 dpyinfo->color_cells, ncolor_cells);
2271 *ncells = dpyinfo->ncolor_cells;
2272 return dpyinfo->color_cells;
2276 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2277 colors in COLORS. Use cached information, if available. */
2279 void
2280 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2282 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2284 if (dpyinfo->red_bits > 0)
2286 /* For TrueColor displays, we can decompose the RGB value
2287 directly. */
2288 int i;
2289 unsigned int rmult, gmult, bmult;
2290 unsigned int rmask, gmask, bmask;
2292 rmask = (1 << dpyinfo->red_bits) - 1;
2293 gmask = (1 << dpyinfo->green_bits) - 1;
2294 bmask = (1 << dpyinfo->blue_bits) - 1;
2295 /* If we're widening, for example, 8 bits in the pixel value to
2296 16 bits for the separate-color representation, we want to
2297 extrapolate the lower bits based on those bits available --
2298 in other words, we'd like 0xff to become 0xffff instead of
2299 the 0xff00 we'd get by just zero-filling the lower bits.
2301 We generate a 32-bit scaled-up value and shift it, in case
2302 the bit count doesn't divide 16 evenly (e.g., when dealing
2303 with a 3-3-2 bit RGB display), to get more of the lower bits
2304 correct.
2306 Should we cache the multipliers in dpyinfo? Maybe
2307 special-case the 8-8-8 common case? */
2308 rmult = 0xffffffff / rmask;
2309 gmult = 0xffffffff / gmask;
2310 bmult = 0xffffffff / bmask;
2312 for (i = 0; i < ncolors; ++i)
2314 unsigned int r, g, b;
2315 unsigned long pixel = colors[i].pixel;
2317 r = (pixel >> dpyinfo->red_offset) & rmask;
2318 g = (pixel >> dpyinfo->green_offset) & gmask;
2319 b = (pixel >> dpyinfo->blue_offset) & bmask;
2321 colors[i].red = (r * rmult) >> 16;
2322 colors[i].green = (g * gmult) >> 16;
2323 colors[i].blue = (b * bmult) >> 16;
2325 return;
2328 if (dpyinfo->color_cells)
2330 int i;
2331 for (i = 0; i < ncolors; ++i)
2333 unsigned long pixel = colors[i].pixel;
2334 eassert (pixel < dpyinfo->ncolor_cells);
2335 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2336 colors[i] = dpyinfo->color_cells[pixel];
2338 return;
2341 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2345 /* On frame F, translate pixel color to RGB values for the color in
2346 COLOR. Use cached information, if available. */
2348 void
2349 x_query_color (struct frame *f, XColor *color)
2351 x_query_colors (f, color, 1);
2355 /* On frame F, translate the color name to RGB values. Use cached
2356 information, if possible.
2358 Note that there is currently no way to clean old entries out of the
2359 cache. However, it is limited to names in the server's database,
2360 and names we've actually looked up; list-colors-display is probably
2361 the most color-intensive case we're likely to hit. */
2363 Status x_parse_color (struct frame *f, const char *color_name,
2364 XColor *color)
2366 Display *dpy = FRAME_X_DISPLAY (f);
2367 Colormap cmap = FRAME_X_COLORMAP (f);
2368 struct color_name_cache_entry *cache_entry;
2370 if (color_name[0] == '#')
2372 /* The hex form is parsed directly by XParseColor without
2373 talking to the X server. No need for caching. */
2374 return XParseColor (dpy, cmap, color_name, color);
2377 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2378 cache_entry = cache_entry->next)
2380 if (!xstrcasecmp(cache_entry->name, color_name))
2382 *color = cache_entry->rgb;
2383 return 1;
2387 if (XParseColor (dpy, cmap, color_name, color) == 0)
2388 /* No caching of negative results, currently. */
2389 return 0;
2391 cache_entry = xzalloc (sizeof *cache_entry);
2392 cache_entry->rgb = *color;
2393 cache_entry->name = xstrdup (color_name);
2394 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2395 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2396 return 1;
2400 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2401 exact match can't be allocated, try the nearest color available.
2402 Value is true if successful. Set *COLOR to the color
2403 allocated. */
2405 static bool
2406 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2408 bool rc;
2410 rc = XAllocColor (dpy, cmap, color) != 0;
2411 if (rc == 0)
2413 /* If we got to this point, the colormap is full, so we're going
2414 to try to get the next closest color. The algorithm used is
2415 a least-squares matching, which is what X uses for closest
2416 color matching with StaticColor visuals. */
2417 int nearest, i;
2418 int max_color_delta = 255;
2419 int max_delta = 3 * max_color_delta;
2420 int nearest_delta = max_delta + 1;
2421 int ncells;
2422 const XColor *cells = x_color_cells (dpy, &ncells);
2424 for (nearest = i = 0; i < ncells; ++i)
2426 int dred = (color->red >> 8) - (cells[i].red >> 8);
2427 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2428 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2429 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2431 if (delta < nearest_delta)
2433 nearest = i;
2434 nearest_delta = delta;
2438 color->red = cells[nearest].red;
2439 color->green = cells[nearest].green;
2440 color->blue = cells[nearest].blue;
2441 rc = XAllocColor (dpy, cmap, color) != 0;
2443 else
2445 /* If allocation succeeded, and the allocated pixel color is not
2446 equal to a cached pixel color recorded earlier, there was a
2447 change in the colormap, so clear the color cache. */
2448 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2449 eassume (dpyinfo);
2451 if (dpyinfo->color_cells)
2453 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2454 if (cached_color->red != color->red
2455 || cached_color->blue != color->blue
2456 || cached_color->green != color->green)
2458 xfree (dpyinfo->color_cells);
2459 dpyinfo->color_cells = NULL;
2460 dpyinfo->ncolor_cells = 0;
2465 #ifdef DEBUG_X_COLORS
2466 if (rc)
2467 register_color (color->pixel);
2468 #endif /* DEBUG_X_COLORS */
2470 return rc;
2474 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2475 gamma correction. If an exact match can't be allocated, try the
2476 nearest color available. Value is true if successful. Set *COLOR
2477 to the color allocated. */
2479 bool
2480 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2482 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2484 gamma_correct (f, color);
2486 if (dpyinfo->red_bits > 0)
2488 color->pixel = x_make_truecolor_pixel (dpyinfo,
2489 color->red,
2490 color->green,
2491 color->blue);
2492 return true;
2495 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2499 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2500 It's necessary to do this instead of just using PIXEL directly to
2501 get color reference counts right. */
2503 unsigned long
2504 x_copy_color (struct frame *f, unsigned long pixel)
2506 XColor color;
2508 /* If display has an immutable color map, freeing colors is not
2509 necessary and some servers don't allow it. Since we won't free a
2510 color once we've allocated it, we don't need to re-allocate it to
2511 maintain the server's reference count. */
2512 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2513 return pixel;
2515 color.pixel = pixel;
2516 block_input ();
2517 /* The color could still be found in the color_cells array. */
2518 x_query_color (f, &color);
2519 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2520 unblock_input ();
2521 #ifdef DEBUG_X_COLORS
2522 register_color (pixel);
2523 #endif
2524 return color.pixel;
2528 /* Brightness beyond which a color won't have its highlight brightness
2529 boosted.
2531 Nominally, highlight colors for `3d' faces are calculated by
2532 brightening an object's color by a constant scale factor, but this
2533 doesn't yield good results for dark colors, so for colors who's
2534 brightness is less than this value (on a scale of 0-65535) have an
2535 use an additional additive factor.
2537 The value here is set so that the default menu-bar/mode-line color
2538 (grey75) will not have its highlights changed at all. */
2539 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2542 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2543 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2544 If this produces the same color as PIXEL, try a color where all RGB
2545 values have DELTA added. Return the allocated color in *PIXEL.
2546 DISPLAY is the X display, CMAP is the colormap to operate on.
2547 Value is non-zero if successful. */
2549 static bool
2550 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2551 unsigned long *pixel, double factor, int delta)
2553 XColor color, new;
2554 long bright;
2555 bool success_p;
2557 /* Get RGB color values. */
2558 color.pixel = *pixel;
2559 x_query_color (f, &color);
2561 /* Change RGB values by specified FACTOR. Avoid overflow! */
2562 eassert (factor >= 0);
2563 new.red = min (0xffff, factor * color.red);
2564 new.green = min (0xffff, factor * color.green);
2565 new.blue = min (0xffff, factor * color.blue);
2567 /* Calculate brightness of COLOR. */
2568 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2570 /* We only boost colors that are darker than
2571 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2572 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2573 /* Make an additive adjustment to NEW, because it's dark enough so
2574 that scaling by FACTOR alone isn't enough. */
2576 /* How far below the limit this color is (0 - 1, 1 being darker). */
2577 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2578 /* The additive adjustment. */
2579 int min_delta = delta * dimness * factor / 2;
2581 if (factor < 1)
2583 new.red = max (0, new.red - min_delta);
2584 new.green = max (0, new.green - min_delta);
2585 new.blue = max (0, new.blue - min_delta);
2587 else
2589 new.red = min (0xffff, min_delta + new.red);
2590 new.green = min (0xffff, min_delta + new.green);
2591 new.blue = min (0xffff, min_delta + new.blue);
2595 /* Try to allocate the color. */
2596 success_p = x_alloc_nearest_color (f, cmap, &new);
2597 if (success_p)
2599 if (new.pixel == *pixel)
2601 /* If we end up with the same color as before, try adding
2602 delta to the RGB values. */
2603 x_free_colors (f, &new.pixel, 1);
2605 new.red = min (0xffff, delta + color.red);
2606 new.green = min (0xffff, delta + color.green);
2607 new.blue = min (0xffff, delta + color.blue);
2608 success_p = x_alloc_nearest_color (f, cmap, &new);
2610 else
2611 success_p = true;
2612 *pixel = new.pixel;
2615 return success_p;
2619 /* Set up the foreground color for drawing relief lines of glyph
2620 string S. RELIEF is a pointer to a struct relief containing the GC
2621 with which lines will be drawn. Use a color that is FACTOR or
2622 DELTA lighter or darker than the relief's background which is found
2623 in S->f->output_data.x->relief_background. If such a color cannot
2624 be allocated, use DEFAULT_PIXEL, instead. */
2626 static void
2627 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2628 int delta, unsigned long default_pixel)
2630 XGCValues xgcv;
2631 struct x_output *di = f->output_data.x;
2632 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2633 unsigned long pixel;
2634 unsigned long background = di->relief_background;
2635 Colormap cmap = FRAME_X_COLORMAP (f);
2636 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2637 Display *dpy = FRAME_X_DISPLAY (f);
2639 xgcv.graphics_exposures = False;
2640 xgcv.line_width = 1;
2642 /* Free previously allocated color. The color cell will be reused
2643 when it has been freed as many times as it was allocated, so this
2644 doesn't affect faces using the same colors. */
2645 if (relief->gc && relief->pixel != -1)
2647 x_free_colors (f, &relief->pixel, 1);
2648 relief->pixel = -1;
2651 /* Allocate new color. */
2652 xgcv.foreground = default_pixel;
2653 pixel = background;
2654 if (dpyinfo->n_planes != 1
2655 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2656 xgcv.foreground = relief->pixel = pixel;
2658 if (relief->gc == 0)
2660 xgcv.stipple = dpyinfo->gray;
2661 mask |= GCStipple;
2662 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2664 else
2665 XChangeGC (dpy, relief->gc, mask, &xgcv);
2669 /* Set up colors for the relief lines around glyph string S. */
2671 static void
2672 x_setup_relief_colors (struct glyph_string *s)
2674 struct x_output *di = s->f->output_data.x;
2675 unsigned long color;
2677 if (s->face->use_box_color_for_shadows_p)
2678 color = s->face->box_color;
2679 else if (s->first_glyph->type == IMAGE_GLYPH
2680 && s->img->pixmap
2681 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2682 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2683 else
2685 XGCValues xgcv;
2687 /* Get the background color of the face. */
2688 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2689 color = xgcv.background;
2692 if (di->white_relief.gc == 0
2693 || color != di->relief_background)
2695 di->relief_background = color;
2696 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2697 WHITE_PIX_DEFAULT (s->f));
2698 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2699 BLACK_PIX_DEFAULT (s->f));
2704 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2705 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2706 to draw, it must be >= 0. RAISED_P means draw a raised
2707 relief. LEFT_P means draw a relief on the left side of
2708 the rectangle. RIGHT_P means draw a relief on the right
2709 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2710 when drawing. */
2712 static void
2713 x_draw_relief_rect (struct frame *f,
2714 int left_x, int top_y, int right_x, int bottom_y,
2715 int width, bool raised_p, bool top_p, bool bot_p,
2716 bool left_p, bool right_p,
2717 XRectangle *clip_rect)
2719 #ifdef USE_CAIRO
2720 GC top_left_gc, bottom_right_gc;
2721 int corners = 0;
2723 if (raised_p)
2725 top_left_gc = f->output_data.x->white_relief.gc;
2726 bottom_right_gc = f->output_data.x->black_relief.gc;
2728 else
2730 top_left_gc = f->output_data.x->black_relief.gc;
2731 bottom_right_gc = f->output_data.x->white_relief.gc;
2734 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2735 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2737 if (left_p)
2739 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2740 width, bottom_y + 1 - top_y);
2741 if (top_p)
2742 corners |= 1 << CORNER_TOP_LEFT;
2743 if (bot_p)
2744 corners |= 1 << CORNER_BOTTOM_LEFT;
2746 if (right_p)
2748 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2749 width, bottom_y + 1 - top_y);
2750 if (top_p)
2751 corners |= 1 << CORNER_TOP_RIGHT;
2752 if (bot_p)
2753 corners |= 1 << CORNER_BOTTOM_RIGHT;
2755 if (top_p)
2757 if (!right_p)
2758 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2759 right_x + 1 - left_x, width);
2760 else
2761 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2762 right_x + 1 - left_x, width, 1);
2764 if (bot_p)
2766 if (!left_p)
2767 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2768 right_x + 1 - left_x, width);
2769 else
2770 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2771 left_x, bottom_y + 1 - width,
2772 right_x + 1 - left_x, width, 0);
2774 if (left_p && width != 1)
2775 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2776 1, bottom_y + 1 - top_y);
2777 if (top_p && width != 1)
2778 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2779 right_x + 1 - left_x, 1);
2780 if (corners)
2782 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2783 FRAME_BACKGROUND_PIXEL (f));
2784 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2785 right_x - left_x + 1, bottom_y - top_y + 1,
2786 6, 1, corners);
2789 x_reset_clip_rectangles (f, top_left_gc);
2790 x_reset_clip_rectangles (f, bottom_right_gc);
2791 #else
2792 Display *dpy = FRAME_X_DISPLAY (f);
2793 Drawable drawable = FRAME_X_DRAWABLE (f);
2794 int i;
2795 GC gc;
2797 if (raised_p)
2798 gc = f->output_data.x->white_relief.gc;
2799 else
2800 gc = f->output_data.x->black_relief.gc;
2801 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2803 /* This code is more complicated than it has to be, because of two
2804 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2805 the outermost line using the black relief. (ii) Omit the four
2806 corner pixels. */
2808 /* Top. */
2809 if (top_p)
2811 if (width == 1)
2812 XDrawLine (dpy, drawable, gc,
2813 left_x + left_p, top_y,
2814 right_x + !right_p, top_y);
2816 for (i = 1; i < width; ++i)
2817 XDrawLine (dpy, drawable, gc,
2818 left_x + i * left_p, top_y + i,
2819 right_x + 1 - i * right_p, top_y + i);
2822 /* Left. */
2823 if (left_p)
2825 if (width == 1)
2826 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2828 x_clear_area(f, left_x, top_y, 1, 1);
2829 x_clear_area(f, left_x, bottom_y, 1, 1);
2831 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2832 XDrawLine (dpy, drawable, gc,
2833 left_x + i, top_y + (i + 1) * top_p,
2834 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2837 XSetClipMask (dpy, gc, None);
2838 if (raised_p)
2839 gc = f->output_data.x->black_relief.gc;
2840 else
2841 gc = f->output_data.x->white_relief.gc;
2842 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2844 if (width > 1)
2846 /* Outermost top line. */
2847 if (top_p)
2848 XDrawLine (dpy, drawable, gc,
2849 left_x + left_p, top_y,
2850 right_x + !right_p, top_y);
2852 /* Outermost left line. */
2853 if (left_p)
2854 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2857 /* Bottom. */
2858 if (bot_p)
2860 XDrawLine (dpy, drawable, gc,
2861 left_x + left_p, bottom_y,
2862 right_x + !right_p, bottom_y);
2863 for (i = 1; i < width; ++i)
2864 XDrawLine (dpy, drawable, gc,
2865 left_x + i * left_p, bottom_y - i,
2866 right_x + 1 - i * right_p, bottom_y - i);
2869 /* Right. */
2870 if (right_p)
2872 x_clear_area(f, right_x, top_y, 1, 1);
2873 x_clear_area(f, right_x, bottom_y, 1, 1);
2874 for (i = 0; i < width; ++i)
2875 XDrawLine (dpy, drawable, gc,
2876 right_x - i, top_y + (i + 1) * top_p,
2877 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2880 x_reset_clip_rectangles (f, gc);
2882 #endif
2886 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2887 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2888 draw, it must be >= 0. LEFT_P means draw a line on the
2889 left side of the rectangle. RIGHT_P means draw a line
2890 on the right side of the rectangle. CLIP_RECT is the clipping
2891 rectangle to use when drawing. */
2893 static void
2894 x_draw_box_rect (struct glyph_string *s,
2895 int left_x, int top_y, int right_x, int bottom_y, int width,
2896 bool left_p, bool right_p, XRectangle *clip_rect)
2898 XGCValues xgcv;
2900 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2901 XSetForeground (s->display, s->gc, s->face->box_color);
2902 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2904 /* Top. */
2905 x_fill_rectangle (s->f, s->gc,
2906 left_x, top_y, right_x - left_x + 1, width);
2908 /* Left. */
2909 if (left_p)
2910 x_fill_rectangle (s->f, s->gc,
2911 left_x, top_y, width, bottom_y - top_y + 1);
2913 /* Bottom. */
2914 x_fill_rectangle (s->f, s->gc,
2915 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2917 /* Right. */
2918 if (right_p)
2919 x_fill_rectangle (s->f, s->gc,
2920 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2922 XSetForeground (s->display, s->gc, xgcv.foreground);
2923 x_reset_clip_rectangles (s->f, s->gc);
2927 /* Draw a box around glyph string S. */
2929 static void
2930 x_draw_glyph_string_box (struct glyph_string *s)
2932 int width, left_x, right_x, top_y, bottom_y, last_x;
2933 bool raised_p, left_p, right_p;
2934 struct glyph *last_glyph;
2935 XRectangle clip_rect;
2937 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2938 ? WINDOW_RIGHT_EDGE_X (s->w)
2939 : window_box_right (s->w, s->area));
2941 /* The glyph that may have a right box line. */
2942 last_glyph = (s->cmp || s->img
2943 ? s->first_glyph
2944 : s->first_glyph + s->nchars - 1);
2946 width = eabs (s->face->box_line_width);
2947 raised_p = s->face->box == FACE_RAISED_BOX;
2948 left_x = s->x;
2949 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2950 ? last_x - 1
2951 : min (last_x, s->x + s->background_width) - 1);
2952 top_y = s->y;
2953 bottom_y = top_y + s->height - 1;
2955 left_p = (s->first_glyph->left_box_line_p
2956 || (s->hl == DRAW_MOUSE_FACE
2957 && (s->prev == NULL
2958 || s->prev->hl != s->hl)));
2959 right_p = (last_glyph->right_box_line_p
2960 || (s->hl == DRAW_MOUSE_FACE
2961 && (s->next == NULL
2962 || s->next->hl != s->hl)));
2964 get_glyph_string_clip_rect (s, &clip_rect);
2966 if (s->face->box == FACE_SIMPLE_BOX)
2967 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2968 left_p, right_p, &clip_rect);
2969 else
2971 x_setup_relief_colors (s);
2972 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2973 width, raised_p, true, true, left_p, right_p,
2974 &clip_rect);
2979 /* Draw foreground of image glyph string S. */
2981 static void
2982 x_draw_image_foreground (struct glyph_string *s)
2984 int x = s->x;
2985 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2987 /* If first glyph of S has a left box line, start drawing it to the
2988 right of that line. */
2989 if (s->face->box != FACE_NO_BOX
2990 && s->first_glyph->left_box_line_p
2991 && s->slice.x == 0)
2992 x += eabs (s->face->box_line_width);
2994 /* If there is a margin around the image, adjust x- and y-position
2995 by that margin. */
2996 if (s->slice.x == 0)
2997 x += s->img->hmargin;
2998 if (s->slice.y == 0)
2999 y += s->img->vmargin;
3001 if (s->img->pixmap)
3003 if (s->img->mask)
3005 /* We can't set both a clip mask and use XSetClipRectangles
3006 because the latter also sets a clip mask. We also can't
3007 trust on the shape extension to be available
3008 (XShapeCombineRegion). So, compute the rectangle to draw
3009 manually. */
3010 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3011 | GCFunction);
3012 XGCValues xgcv;
3013 XRectangle clip_rect, image_rect, r;
3015 xgcv.clip_mask = s->img->mask;
3016 xgcv.clip_x_origin = x;
3017 xgcv.clip_y_origin = y;
3018 xgcv.function = GXcopy;
3019 XChangeGC (s->display, s->gc, mask, &xgcv);
3021 get_glyph_string_clip_rect (s, &clip_rect);
3022 image_rect.x = x;
3023 image_rect.y = y;
3024 image_rect.width = s->slice.width;
3025 image_rect.height = s->slice.height;
3026 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3027 XCopyArea (s->display, s->img->pixmap,
3028 FRAME_X_DRAWABLE (s->f), s->gc,
3029 s->slice.x + r.x - x, s->slice.y + r.y - y,
3030 r.width, r.height, r.x, r.y);
3032 else
3034 XRectangle clip_rect, image_rect, r;
3036 get_glyph_string_clip_rect (s, &clip_rect);
3037 image_rect.x = x;
3038 image_rect.y = y;
3039 image_rect.width = s->slice.width;
3040 image_rect.height = s->slice.height;
3041 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3042 XCopyArea (s->display, s->img->pixmap,
3043 FRAME_X_DRAWABLE (s->f), s->gc,
3044 s->slice.x + r.x - x, s->slice.y + r.y - y,
3045 r.width, r.height, r.x, r.y);
3047 /* When the image has a mask, we can expect that at
3048 least part of a mouse highlight or a block cursor will
3049 be visible. If the image doesn't have a mask, make
3050 a block cursor visible by drawing a rectangle around
3051 the image. I believe it's looking better if we do
3052 nothing here for mouse-face. */
3053 if (s->hl == DRAW_CURSOR)
3055 int relief = eabs (s->img->relief);
3056 x_draw_rectangle (s->f, s->gc,
3057 x - relief, y - relief,
3058 s->slice.width + relief*2 - 1,
3059 s->slice.height + relief*2 - 1);
3063 else
3064 /* Draw a rectangle if image could not be loaded. */
3065 x_draw_rectangle (s->f, s->gc, x, y,
3066 s->slice.width - 1, s->slice.height - 1);
3070 /* Draw a relief around the image glyph string S. */
3072 static void
3073 x_draw_image_relief (struct glyph_string *s)
3075 int x1, y1, thick;
3076 bool raised_p, top_p, bot_p, left_p, right_p;
3077 int extra_x, extra_y;
3078 XRectangle r;
3079 int x = s->x;
3080 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3082 /* If first glyph of S has a left box line, start drawing it to the
3083 right of that line. */
3084 if (s->face->box != FACE_NO_BOX
3085 && s->first_glyph->left_box_line_p
3086 && s->slice.x == 0)
3087 x += eabs (s->face->box_line_width);
3089 /* If there is a margin around the image, adjust x- and y-position
3090 by that margin. */
3091 if (s->slice.x == 0)
3092 x += s->img->hmargin;
3093 if (s->slice.y == 0)
3094 y += s->img->vmargin;
3096 if (s->hl == DRAW_IMAGE_SUNKEN
3097 || s->hl == DRAW_IMAGE_RAISED)
3099 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3100 raised_p = s->hl == DRAW_IMAGE_RAISED;
3102 else
3104 thick = eabs (s->img->relief);
3105 raised_p = s->img->relief > 0;
3108 x1 = x + s->slice.width - 1;
3109 y1 = y + s->slice.height - 1;
3111 extra_x = extra_y = 0;
3112 if (s->face->id == TOOL_BAR_FACE_ID)
3114 if (CONSP (Vtool_bar_button_margin)
3115 && INTEGERP (XCAR (Vtool_bar_button_margin))
3116 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3118 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3119 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3121 else if (INTEGERP (Vtool_bar_button_margin))
3122 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3125 top_p = bot_p = left_p = right_p = false;
3127 if (s->slice.x == 0)
3128 x -= thick + extra_x, left_p = true;
3129 if (s->slice.y == 0)
3130 y -= thick + extra_y, top_p = true;
3131 if (s->slice.x + s->slice.width == s->img->width)
3132 x1 += thick + extra_x, right_p = true;
3133 if (s->slice.y + s->slice.height == s->img->height)
3134 y1 += thick + extra_y, bot_p = true;
3136 x_setup_relief_colors (s);
3137 get_glyph_string_clip_rect (s, &r);
3138 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3139 top_p, bot_p, left_p, right_p, &r);
3143 /* Draw the foreground of image glyph string S to PIXMAP. */
3145 static void
3146 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3148 int x = 0;
3149 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3151 /* If first glyph of S has a left box line, start drawing it to the
3152 right of that line. */
3153 if (s->face->box != FACE_NO_BOX
3154 && s->first_glyph->left_box_line_p
3155 && s->slice.x == 0)
3156 x += eabs (s->face->box_line_width);
3158 /* If there is a margin around the image, adjust x- and y-position
3159 by that margin. */
3160 if (s->slice.x == 0)
3161 x += s->img->hmargin;
3162 if (s->slice.y == 0)
3163 y += s->img->vmargin;
3165 if (s->img->pixmap)
3167 if (s->img->mask)
3169 /* We can't set both a clip mask and use XSetClipRectangles
3170 because the latter also sets a clip mask. We also can't
3171 trust on the shape extension to be available
3172 (XShapeCombineRegion). So, compute the rectangle to draw
3173 manually. */
3174 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3175 | GCFunction);
3176 XGCValues xgcv;
3178 xgcv.clip_mask = s->img->mask;
3179 xgcv.clip_x_origin = x - s->slice.x;
3180 xgcv.clip_y_origin = y - s->slice.y;
3181 xgcv.function = GXcopy;
3182 XChangeGC (s->display, s->gc, mask, &xgcv);
3184 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3185 s->slice.x, s->slice.y,
3186 s->slice.width, s->slice.height, x, y);
3187 XSetClipMask (s->display, s->gc, None);
3189 else
3191 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3192 s->slice.x, s->slice.y,
3193 s->slice.width, s->slice.height, x, y);
3195 /* When the image has a mask, we can expect that at
3196 least part of a mouse highlight or a block cursor will
3197 be visible. If the image doesn't have a mask, make
3198 a block cursor visible by drawing a rectangle around
3199 the image. I believe it's looking better if we do
3200 nothing here for mouse-face. */
3201 if (s->hl == DRAW_CURSOR)
3203 int r = eabs (s->img->relief);
3204 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3205 s->slice.width + r*2 - 1,
3206 s->slice.height + r*2 - 1);
3210 else
3211 /* Draw a rectangle if image could not be loaded. */
3212 x_draw_rectangle (s->f, s->gc, x, y,
3213 s->slice.width - 1, s->slice.height - 1);
3217 /* Draw part of the background of glyph string S. X, Y, W, and H
3218 give the rectangle to draw. */
3220 static void
3221 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3223 if (s->stippled_p)
3225 /* Fill background with a stipple pattern. */
3226 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3227 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3228 XSetFillStyle (s->display, s->gc, FillSolid);
3230 else
3231 x_clear_glyph_string_rect (s, x, y, w, h);
3235 /* Draw image glyph string S.
3237 s->y
3238 s->x +-------------------------
3239 | s->face->box
3241 | +-------------------------
3242 | | s->img->margin
3244 | | +-------------------
3245 | | | the image
3249 static void
3250 x_draw_image_glyph_string (struct glyph_string *s)
3252 int box_line_hwidth = eabs (s->face->box_line_width);
3253 int box_line_vwidth = max (s->face->box_line_width, 0);
3254 int height;
3255 Pixmap pixmap = None;
3257 height = s->height;
3258 if (s->slice.y == 0)
3259 height -= box_line_vwidth;
3260 if (s->slice.y + s->slice.height >= s->img->height)
3261 height -= box_line_vwidth;
3263 /* Fill background with face under the image. Do it only if row is
3264 taller than image or if image has a clip mask to reduce
3265 flickering. */
3266 s->stippled_p = s->face->stipple != 0;
3267 if (height > s->slice.height
3268 || s->img->hmargin
3269 || s->img->vmargin
3270 || s->img->mask
3271 || s->img->pixmap == 0
3272 || s->width != s->background_width)
3274 if (s->img->mask)
3276 /* Create a pixmap as large as the glyph string. Fill it
3277 with the background color. Copy the image to it, using
3278 its mask. Copy the temporary pixmap to the display. */
3279 Screen *screen = FRAME_X_SCREEN (s->f);
3280 int depth = DefaultDepthOfScreen (screen);
3282 /* Create a pixmap as large as the glyph string. */
3283 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3284 s->background_width,
3285 s->height, depth);
3287 /* Don't clip in the following because we're working on the
3288 pixmap. */
3289 XSetClipMask (s->display, s->gc, None);
3291 /* Fill the pixmap with the background color/stipple. */
3292 if (s->stippled_p)
3294 /* Fill background with a stipple pattern. */
3295 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3296 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3297 XFillRectangle (s->display, pixmap, s->gc,
3298 0, 0, s->background_width, s->height);
3299 XSetFillStyle (s->display, s->gc, FillSolid);
3300 XSetTSOrigin (s->display, s->gc, 0, 0);
3302 else
3304 XGCValues xgcv;
3305 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3306 &xgcv);
3307 XSetForeground (s->display, s->gc, xgcv.background);
3308 XFillRectangle (s->display, pixmap, s->gc,
3309 0, 0, s->background_width, s->height);
3310 XSetForeground (s->display, s->gc, xgcv.foreground);
3313 else
3315 int x = s->x;
3316 int y = s->y;
3317 int width = s->background_width;
3319 if (s->first_glyph->left_box_line_p
3320 && s->slice.x == 0)
3322 x += box_line_hwidth;
3323 width -= box_line_hwidth;
3326 if (s->slice.y == 0)
3327 y += box_line_vwidth;
3329 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3332 s->background_filled_p = true;
3335 /* Draw the foreground. */
3336 #ifdef USE_CAIRO
3337 if (s->img->cr_data)
3339 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3341 int x = s->x + s->img->hmargin;
3342 int y = s->y + s->img->vmargin;
3343 int width = s->background_width;
3345 cairo_set_source_surface (cr, s->img->cr_data,
3346 x - s->slice.x,
3347 y - s->slice.y);
3348 cairo_rectangle (cr, x, y, width, height);
3349 cairo_fill (cr);
3350 x_end_cr_clip (s->f);
3352 else
3353 #endif
3354 if (pixmap != None)
3356 x_draw_image_foreground_1 (s, pixmap);
3357 x_set_glyph_string_clipping (s);
3358 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3359 0, 0, s->background_width, s->height, s->x, s->y);
3360 XFreePixmap (s->display, pixmap);
3362 else
3363 x_draw_image_foreground (s);
3365 /* If we must draw a relief around the image, do it. */
3366 if (s->img->relief
3367 || s->hl == DRAW_IMAGE_RAISED
3368 || s->hl == DRAW_IMAGE_SUNKEN)
3369 x_draw_image_relief (s);
3373 /* Draw stretch glyph string S. */
3375 static void
3376 x_draw_stretch_glyph_string (struct glyph_string *s)
3378 eassert (s->first_glyph->type == STRETCH_GLYPH);
3380 if (s->hl == DRAW_CURSOR
3381 && !x_stretch_cursor_p)
3383 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3384 wide as the stretch glyph. */
3385 int width, background_width = s->background_width;
3386 int x = s->x;
3388 if (!s->row->reversed_p)
3390 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3392 if (x < left_x)
3394 background_width -= left_x - x;
3395 x = left_x;
3398 else
3400 /* In R2L rows, draw the cursor on the right edge of the
3401 stretch glyph. */
3402 int right_x = window_box_right (s->w, TEXT_AREA);
3404 if (x + background_width > right_x)
3405 background_width -= x - right_x;
3406 x += background_width;
3408 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3409 if (s->row->reversed_p)
3410 x -= width;
3412 /* Draw cursor. */
3413 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3415 /* Clear rest using the GC of the original non-cursor face. */
3416 if (width < background_width)
3418 int y = s->y;
3419 int w = background_width - width, h = s->height;
3420 XRectangle r;
3421 GC gc;
3423 if (!s->row->reversed_p)
3424 x += width;
3425 else
3426 x = s->x;
3427 if (s->row->mouse_face_p
3428 && cursor_in_mouse_face_p (s->w))
3430 x_set_mouse_face_gc (s);
3431 gc = s->gc;
3433 else
3434 gc = s->face->gc;
3436 get_glyph_string_clip_rect (s, &r);
3437 x_set_clip_rectangles (s->f, gc, &r, 1);
3439 if (s->face->stipple)
3441 /* Fill background with a stipple pattern. */
3442 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3443 x_fill_rectangle (s->f, gc, x, y, w, h);
3444 XSetFillStyle (s->display, gc, FillSolid);
3446 else
3448 XGCValues xgcv;
3449 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3450 XSetForeground (s->display, gc, xgcv.background);
3451 x_fill_rectangle (s->f, gc, x, y, w, h);
3452 XSetForeground (s->display, gc, xgcv.foreground);
3455 x_reset_clip_rectangles (s->f, gc);
3458 else if (!s->background_filled_p)
3460 int background_width = s->background_width;
3461 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3463 /* Don't draw into left margin, fringe or scrollbar area
3464 except for header line and mode line. */
3465 if (x < left_x && !s->row->mode_line_p)
3467 background_width -= left_x - x;
3468 x = left_x;
3470 if (background_width > 0)
3471 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3474 s->background_filled_p = true;
3477 static void
3478 x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
3480 const int base_res = 96;
3481 struct x_display_info * dpyinfo = x_display_info_for_display (disp);
3483 *scale_x = *scale_y = 1;
3485 if (dpyinfo)
3487 if (dpyinfo->resx > base_res)
3488 *scale_x = floor (dpyinfo->resx / base_res);
3489 if (dpyinfo->resy > base_res)
3490 *scale_y = floor (dpyinfo->resy / base_res);
3495 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3497 x0 wave_length = 2
3499 y0 * * * * *
3500 |* * * * * * * * *
3501 wave_height = 3 | * * * *
3504 static void
3505 x_draw_underwave (struct glyph_string *s)
3507 /* Adjust for scale/HiDPI. */
3508 int scale_x, scale_y;
3510 x_get_scale_factor (s->display, &scale_x, &scale_y);
3512 int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
3514 #ifdef USE_CAIRO
3515 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3516 s->width, wave_height, wave_length);
3517 #else /* not USE_CAIRO */
3518 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3519 bool odd;
3520 XRectangle wave_clip, string_clip, final_clip;
3522 dx = wave_length;
3523 dy = wave_height - 1;
3524 x0 = s->x;
3525 y0 = s->ybase + wave_height / 2 - scale_y;
3526 width = s->width;
3527 xmax = x0 + width;
3529 /* Find and set clipping rectangle */
3531 wave_clip.x = x0;
3532 wave_clip.y = y0;
3533 wave_clip.width = width;
3534 wave_clip.height = wave_height;
3535 get_glyph_string_clip_rect (s, &string_clip);
3537 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3538 return;
3540 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3542 /* Draw the waves */
3544 x1 = x0 - (x0 % dx);
3545 x2 = x1 + dx;
3546 odd = (x1 / dx) & 1;
3547 y1 = y2 = y0;
3549 if (odd)
3550 y1 += dy;
3551 else
3552 y2 += dy;
3554 if (INT_MAX - dx < xmax)
3555 emacs_abort ();
3557 while (x1 <= xmax)
3559 XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt,
3560 JoinRound);
3561 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3562 x1 = x2, y1 = y2;
3563 x2 += dx, y2 = y0 + odd*dy;
3564 odd = !odd;
3567 /* Restore previous clipping rectangle(s) */
3568 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3569 #endif /* not USE_CAIRO */
3573 /* Draw glyph string S. */
3575 static void
3576 x_draw_glyph_string (struct glyph_string *s)
3578 bool relief_drawn_p = false;
3580 /* If S draws into the background of its successors, draw the
3581 background of the successors first so that S can draw into it.
3582 This makes S->next use XDrawString instead of XDrawImageString. */
3583 if (s->next && s->right_overhang && !s->for_overlaps)
3585 int width;
3586 struct glyph_string *next;
3588 for (width = 0, next = s->next;
3589 next && width < s->right_overhang;
3590 width += next->width, next = next->next)
3591 if (next->first_glyph->type != IMAGE_GLYPH)
3593 x_set_glyph_string_gc (next);
3594 x_set_glyph_string_clipping (next);
3595 if (next->first_glyph->type == STRETCH_GLYPH)
3596 x_draw_stretch_glyph_string (next);
3597 else
3598 x_draw_glyph_string_background (next, true);
3599 next->num_clips = 0;
3603 /* Set up S->gc, set clipping and draw S. */
3604 x_set_glyph_string_gc (s);
3606 /* Draw relief (if any) in advance for char/composition so that the
3607 glyph string can be drawn over it. */
3608 if (!s->for_overlaps
3609 && s->face->box != FACE_NO_BOX
3610 && (s->first_glyph->type == CHAR_GLYPH
3611 || s->first_glyph->type == COMPOSITE_GLYPH))
3614 x_set_glyph_string_clipping (s);
3615 x_draw_glyph_string_background (s, true);
3616 x_draw_glyph_string_box (s);
3617 x_set_glyph_string_clipping (s);
3618 relief_drawn_p = true;
3620 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3621 && !s->clip_tail
3622 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3623 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3624 /* We must clip just this glyph. left_overhang part has already
3625 drawn when s->prev was drawn, and right_overhang part will be
3626 drawn later when s->next is drawn. */
3627 x_set_glyph_string_clipping_exactly (s, s);
3628 else
3629 x_set_glyph_string_clipping (s);
3631 switch (s->first_glyph->type)
3633 case IMAGE_GLYPH:
3634 x_draw_image_glyph_string (s);
3635 break;
3637 case XWIDGET_GLYPH:
3638 x_draw_xwidget_glyph_string (s);
3639 break;
3641 case STRETCH_GLYPH:
3642 x_draw_stretch_glyph_string (s);
3643 break;
3645 case CHAR_GLYPH:
3646 if (s->for_overlaps)
3647 s->background_filled_p = true;
3648 else
3649 x_draw_glyph_string_background (s, false);
3650 x_draw_glyph_string_foreground (s);
3651 break;
3653 case COMPOSITE_GLYPH:
3654 if (s->for_overlaps || (s->cmp_from > 0
3655 && ! s->first_glyph->u.cmp.automatic))
3656 s->background_filled_p = true;
3657 else
3658 x_draw_glyph_string_background (s, true);
3659 x_draw_composite_glyph_string_foreground (s);
3660 break;
3662 case GLYPHLESS_GLYPH:
3663 if (s->for_overlaps)
3664 s->background_filled_p = true;
3665 else
3666 x_draw_glyph_string_background (s, true);
3667 x_draw_glyphless_glyph_string_foreground (s);
3668 break;
3670 default:
3671 emacs_abort ();
3674 if (!s->for_overlaps)
3676 /* Draw underline. */
3677 if (s->face->underline_p)
3679 if (s->face->underline_type == FACE_UNDER_WAVE)
3681 if (s->face->underline_defaulted_p)
3682 x_draw_underwave (s);
3683 else
3685 XGCValues xgcv;
3686 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3687 XSetForeground (s->display, s->gc, s->face->underline_color);
3688 x_draw_underwave (s);
3689 XSetForeground (s->display, s->gc, xgcv.foreground);
3692 else if (s->face->underline_type == FACE_UNDER_LINE)
3694 unsigned long thickness, position;
3695 int y;
3697 if (s->prev && s->prev->face->underline_p
3698 && s->prev->face->underline_type == FACE_UNDER_LINE)
3700 /* We use the same underline style as the previous one. */
3701 thickness = s->prev->underline_thickness;
3702 position = s->prev->underline_position;
3704 else
3706 struct font *font = font_for_underline_metrics (s);
3708 /* Get the underline thickness. Default is 1 pixel. */
3709 if (font && font->underline_thickness > 0)
3710 thickness = font->underline_thickness;
3711 else
3712 thickness = 1;
3713 if (x_underline_at_descent_line)
3714 position = (s->height - thickness) - (s->ybase - s->y);
3715 else
3717 /* Get the underline position. This is the recommended
3718 vertical offset in pixels from the baseline to the top of
3719 the underline. This is a signed value according to the
3720 specs, and its default is
3722 ROUND ((maximum descent) / 2), with
3723 ROUND(x) = floor (x + 0.5) */
3725 if (x_use_underline_position_properties
3726 && font && font->underline_position >= 0)
3727 position = font->underline_position;
3728 else if (font)
3729 position = (font->descent + 1) / 2;
3730 else
3731 position = underline_minimum_offset;
3733 position = max (position, underline_minimum_offset);
3735 /* Check the sanity of thickness and position. We should
3736 avoid drawing underline out of the current line area. */
3737 if (s->y + s->height <= s->ybase + position)
3738 position = (s->height - 1) - (s->ybase - s->y);
3739 if (s->y + s->height < s->ybase + position + thickness)
3740 thickness = (s->y + s->height) - (s->ybase + position);
3741 s->underline_thickness = thickness;
3742 s->underline_position = position;
3743 y = s->ybase + position;
3744 if (s->face->underline_defaulted_p)
3745 x_fill_rectangle (s->f, s->gc,
3746 s->x, y, s->width, thickness);
3747 else
3749 XGCValues xgcv;
3750 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3751 XSetForeground (s->display, s->gc, s->face->underline_color);
3752 x_fill_rectangle (s->f, s->gc,
3753 s->x, y, s->width, thickness);
3754 XSetForeground (s->display, s->gc, xgcv.foreground);
3758 /* Draw overline. */
3759 if (s->face->overline_p)
3761 unsigned long dy = 0, h = 1;
3763 if (s->face->overline_color_defaulted_p)
3764 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3765 s->width, h);
3766 else
3768 XGCValues xgcv;
3769 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3770 XSetForeground (s->display, s->gc, s->face->overline_color);
3771 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3772 s->width, h);
3773 XSetForeground (s->display, s->gc, xgcv.foreground);
3777 /* Draw strike-through. */
3778 if (s->face->strike_through_p)
3780 /* Y-coordinate and height of the glyph string's first
3781 glyph. We cannot use s->y and s->height because those
3782 could be larger if there are taller display elements
3783 (e.g., characters displayed with a larger font) in the
3784 same glyph row. */
3785 int glyph_y = s->ybase - s->first_glyph->ascent;
3786 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3787 /* Strike-through width and offset from the glyph string's
3788 top edge. */
3789 unsigned long h = 1;
3790 unsigned long dy = (glyph_height - h) / 2;
3792 if (s->face->strike_through_color_defaulted_p)
3793 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3794 s->width, h);
3795 else
3797 XGCValues xgcv;
3798 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3799 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3800 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3801 s->width, h);
3802 XSetForeground (s->display, s->gc, xgcv.foreground);
3806 /* Draw relief if not yet drawn. */
3807 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3808 x_draw_glyph_string_box (s);
3810 if (s->prev)
3812 struct glyph_string *prev;
3814 for (prev = s->prev; prev; prev = prev->prev)
3815 if (prev->hl != s->hl
3816 && prev->x + prev->width + prev->right_overhang > s->x)
3818 /* As prev was drawn while clipped to its own area, we
3819 must draw the right_overhang part using s->hl now. */
3820 enum draw_glyphs_face save = prev->hl;
3822 prev->hl = s->hl;
3823 x_set_glyph_string_gc (prev);
3824 x_set_glyph_string_clipping_exactly (s, prev);
3825 if (prev->first_glyph->type == CHAR_GLYPH)
3826 x_draw_glyph_string_foreground (prev);
3827 else
3828 x_draw_composite_glyph_string_foreground (prev);
3829 x_reset_clip_rectangles (prev->f, prev->gc);
3830 prev->hl = save;
3831 prev->num_clips = 0;
3835 if (s->next)
3837 struct glyph_string *next;
3839 for (next = s->next; next; next = next->next)
3840 if (next->hl != s->hl
3841 && next->x - next->left_overhang < s->x + s->width)
3843 /* As next will be drawn while clipped to its own area,
3844 we must draw the left_overhang part using s->hl now. */
3845 enum draw_glyphs_face save = next->hl;
3847 next->hl = s->hl;
3848 x_set_glyph_string_gc (next);
3849 x_set_glyph_string_clipping_exactly (s, next);
3850 if (next->first_glyph->type == CHAR_GLYPH)
3851 x_draw_glyph_string_foreground (next);
3852 else
3853 x_draw_composite_glyph_string_foreground (next);
3854 x_reset_clip_rectangles (next->f, next->gc);
3855 next->hl = save;
3856 next->num_clips = 0;
3857 next->clip_head = s->next;
3862 /* Reset clipping. */
3863 x_reset_clip_rectangles (s->f, s->gc);
3864 s->num_clips = 0;
3867 /* Shift display to make room for inserted glyphs. */
3869 static void
3870 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3872 /* Never called on a GUI frame, see
3873 https://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3875 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3876 f->output_data.x->normal_gc,
3877 x, y, width, height,
3878 x + shift_by, y);
3881 /* Delete N glyphs at the nominal cursor position. Not implemented
3882 for X frames. */
3884 static void
3885 x_delete_glyphs (struct frame *f, register int n)
3887 emacs_abort ();
3891 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3892 If they are <= 0, this is probably an error. */
3894 static ATTRIBUTE_UNUSED void
3895 x_clear_area1 (Display *dpy, Window window,
3896 int x, int y, int width, int height, int exposures)
3898 eassert (width > 0 && height > 0);
3899 XClearArea (dpy, window, x, y, width, height, exposures);
3902 void
3903 x_clear_area (struct frame *f, int x, int y, int width, int height)
3905 #ifdef USE_CAIRO
3906 cairo_t *cr;
3908 eassert (width > 0 && height > 0);
3910 cr = x_begin_cr_clip (f, NULL);
3911 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3912 cairo_rectangle (cr, x, y, width, height);
3913 cairo_fill (cr);
3914 x_end_cr_clip (f);
3915 #else
3916 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3917 XFillRectangle (FRAME_X_DISPLAY (f),
3918 FRAME_X_DRAWABLE (f),
3919 f->output_data.x->reverse_gc,
3920 x, y, width, height);
3921 else
3922 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3923 x, y, width, height, False);
3924 #endif
3928 /* Clear an entire frame. */
3930 static void
3931 x_clear_frame (struct frame *f)
3933 /* Clearing the frame will erase any cursor, so mark them all as no
3934 longer visible. */
3935 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3937 block_input ();
3939 font_drop_xrender_surfaces (f);
3940 x_clear_window (f);
3942 /* We have to clear the scroll bars. If we have changed colors or
3943 something like that, then they should be notified. */
3944 x_scroll_bar_clear (f);
3946 XFlush (FRAME_X_DISPLAY (f));
3948 unblock_input ();
3951 /* RIF: Show hourglass cursor on frame F. */
3953 static void
3954 x_show_hourglass (struct frame *f)
3956 Display *dpy = FRAME_X_DISPLAY (f);
3958 if (dpy)
3960 struct x_output *x = FRAME_X_OUTPUT (f);
3961 #ifdef USE_X_TOOLKIT
3962 if (x->widget)
3963 #else
3964 if (FRAME_OUTER_WINDOW (f))
3965 #endif
3967 x->hourglass_p = true;
3969 if (!x->hourglass_window)
3971 unsigned long mask = CWCursor;
3972 XSetWindowAttributes attrs;
3973 #ifdef USE_GTK
3974 Window parent = FRAME_X_WINDOW (f);
3975 #else
3976 Window parent = FRAME_OUTER_WINDOW (f);
3977 #endif
3978 attrs.cursor = x->hourglass_cursor;
3980 x->hourglass_window = XCreateWindow
3981 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3982 InputOnly, CopyFromParent, mask, &attrs);
3985 XMapRaised (dpy, x->hourglass_window);
3986 XFlush (dpy);
3991 /* RIF: Cancel hourglass cursor on frame F. */
3993 static void
3994 x_hide_hourglass (struct frame *f)
3996 struct x_output *x = FRAME_X_OUTPUT (f);
3998 /* Watch out for newly created frames. */
3999 if (x->hourglass_window)
4001 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
4002 /* Sync here because XTread_socket looks at the
4003 hourglass_p flag that is reset to zero below. */
4004 XSync (FRAME_X_DISPLAY (f), False);
4005 x->hourglass_p = false;
4009 /* Invert the middle quarter of the frame for .15 sec. */
4011 static void
4012 XTflash (struct frame *f)
4014 block_input ();
4017 #ifdef USE_GTK
4018 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
4019 when the scroll bars and the edit widget share the same X window. */
4020 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4021 #ifdef HAVE_GTK3
4022 #if GTK_CHECK_VERSION (3, 22, 0)
4023 cairo_region_t *region = gdk_window_get_visible_region (window);
4024 GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
4025 cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
4026 #else
4027 cairo_t *cr = gdk_cairo_create (window);
4028 #endif
4029 cairo_set_source_rgb (cr, 1, 1, 1);
4030 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4031 #define XFillRectangle(d, win, gc, x, y, w, h) \
4032 do { \
4033 cairo_rectangle (cr, x, y, w, h); \
4034 cairo_fill (cr); \
4036 while (false)
4037 #else /* ! HAVE_GTK3 */
4038 GdkGCValues vals;
4039 GdkGC *gc;
4040 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4041 ^ FRAME_BACKGROUND_PIXEL (f));
4042 vals.function = GDK_XOR;
4043 gc = gdk_gc_new_with_values (window,
4044 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4045 #define XFillRectangle(d, win, gc, x, y, w, h) \
4046 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4047 #endif /* ! HAVE_GTK3 */
4048 #else /* ! USE_GTK */
4049 GC gc;
4051 /* Create a GC that will use the GXxor function to flip foreground
4052 pixels into background pixels. */
4054 XGCValues values;
4056 values.function = GXxor;
4057 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
4058 ^ FRAME_BACKGROUND_PIXEL (f));
4060 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4061 GCFunction | GCForeground, &values);
4063 #endif
4065 /* Get the height not including a menu bar widget. */
4066 int height = FRAME_PIXEL_HEIGHT (f);
4067 /* Height of each line to flash. */
4068 int flash_height = FRAME_LINE_HEIGHT (f);
4069 /* These will be the left and right margins of the rectangles. */
4070 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4071 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4072 int width = flash_right - flash_left;
4074 /* If window is tall, flash top and bottom line. */
4075 if (height > 3 * FRAME_LINE_HEIGHT (f))
4077 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4078 flash_left,
4079 (FRAME_INTERNAL_BORDER_WIDTH (f)
4080 + FRAME_TOP_MARGIN_HEIGHT (f)),
4081 width, flash_height);
4082 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4083 flash_left,
4084 (height - flash_height
4085 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4086 width, flash_height);
4089 else
4090 /* If it is short, flash it all. */
4091 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4092 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4093 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4095 x_flush (f);
4098 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4099 struct timespec wakeup = timespec_add (current_timespec (), delay);
4101 /* Keep waiting until past the time wakeup or any input gets
4102 available. */
4103 while (! detect_input_pending ())
4105 struct timespec current = current_timespec ();
4106 struct timespec timeout;
4108 /* Break if result would not be positive. */
4109 if (timespec_cmp (wakeup, current) <= 0)
4110 break;
4112 /* How long `select' should wait. */
4113 timeout = make_timespec (0, 10 * 1000 * 1000);
4115 /* Try to wait that long--but we might wake up sooner. */
4116 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4120 /* If window is tall, flash top and bottom line. */
4121 if (height > 3 * FRAME_LINE_HEIGHT (f))
4123 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4124 flash_left,
4125 (FRAME_INTERNAL_BORDER_WIDTH (f)
4126 + FRAME_TOP_MARGIN_HEIGHT (f)),
4127 width, flash_height);
4128 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4129 flash_left,
4130 (height - flash_height
4131 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4132 width, flash_height);
4134 else
4135 /* If it is short, flash it all. */
4136 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4137 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4138 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4140 #ifdef USE_GTK
4141 #ifdef HAVE_GTK3
4142 #if GTK_CHECK_VERSION (3, 22, 0)
4143 gdk_window_end_draw_frame (window, context);
4144 cairo_region_destroy (region);
4145 #else
4146 cairo_destroy (cr);
4147 #endif
4148 #else
4149 g_object_unref (G_OBJECT (gc));
4150 #endif
4151 #undef XFillRectangle
4152 #else
4153 XFreeGC (FRAME_X_DISPLAY (f), gc);
4154 #endif
4155 x_flush (f);
4159 unblock_input ();
4163 static void
4164 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4166 block_input ();
4167 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4168 unblock_input ();
4172 /* Make audible bell. */
4174 static void
4175 XTring_bell (struct frame *f)
4177 if (FRAME_X_DISPLAY (f))
4179 if (visible_bell)
4180 XTflash (f);
4181 else
4183 block_input ();
4184 #ifdef HAVE_XKB
4185 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4186 #else
4187 XBell (FRAME_X_DISPLAY (f), 0);
4188 #endif
4189 XFlush (FRAME_X_DISPLAY (f));
4190 unblock_input ();
4195 /***********************************************************************
4196 Line Dance
4197 ***********************************************************************/
4199 /* Perform an insert-lines or delete-lines operation, inserting N
4200 lines or deleting -N lines at vertical position VPOS. */
4202 static void
4203 x_ins_del_lines (struct frame *f, int vpos, int n)
4205 emacs_abort ();
4209 /* Scroll part of the display as described by RUN. */
4211 static void
4212 x_scroll_run (struct window *w, struct run *run)
4214 struct frame *f = XFRAME (w->frame);
4215 int x, y, width, height, from_y, to_y, bottom_y;
4217 /* Get frame-relative bounding box of the text display area of W,
4218 without mode lines. Include in this box the left and right
4219 fringe of W. */
4220 window_box (w, ANY_AREA, &x, &y, &width, &height);
4222 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4223 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4224 bottom_y = y + height;
4226 if (to_y < from_y)
4228 /* Scrolling up. Make sure we don't copy part of the mode
4229 line at the bottom. */
4230 if (from_y + run->height > bottom_y)
4231 height = bottom_y - from_y;
4232 else
4233 height = run->height;
4235 else
4237 /* Scrolling down. Make sure we don't copy over the mode line.
4238 at the bottom. */
4239 if (to_y + run->height > bottom_y)
4240 height = bottom_y - to_y;
4241 else
4242 height = run->height;
4245 block_input ();
4247 /* Cursor off. Will be switched on again in x_update_window_end. */
4248 x_clear_cursor (w);
4250 #ifdef USE_CAIRO
4251 SET_FRAME_GARBAGED (f);
4252 #else
4253 XCopyArea (FRAME_X_DISPLAY (f),
4254 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4255 f->output_data.x->normal_gc,
4256 x, from_y,
4257 width, height,
4258 x, to_y);
4259 #endif
4261 unblock_input ();
4266 /***********************************************************************
4267 Exposure Events
4268 ***********************************************************************/
4271 static void
4272 frame_highlight (struct frame *f)
4274 /* We used to only do this if Vx_no_window_manager was non-nil, but
4275 the ICCCM (section 4.1.6) says that the window's border pixmap
4276 and border pixel are window attributes which are "private to the
4277 client", so we can always change it to whatever we want. */
4278 block_input ();
4279 /* I recently started to get errors in this XSetWindowBorder, depending on
4280 the window-manager in use, tho something more is at play since I've been
4281 using that same window-manager binary for ever. Let's not crash just
4282 because of this (bug#9310). */
4283 x_catch_errors (FRAME_X_DISPLAY (f));
4284 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4285 f->output_data.x->border_pixel);
4286 x_uncatch_errors ();
4287 unblock_input ();
4288 x_update_cursor (f, true);
4289 x_set_frame_alpha (f);
4292 static void
4293 frame_unhighlight (struct frame *f)
4295 /* We used to only do this if Vx_no_window_manager was non-nil, but
4296 the ICCCM (section 4.1.6) says that the window's border pixmap
4297 and border pixel are window attributes which are "private to the
4298 client", so we can always change it to whatever we want. */
4299 block_input ();
4300 /* Same as above for XSetWindowBorder (bug#9310). */
4301 x_catch_errors (FRAME_X_DISPLAY (f));
4302 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4303 f->output_data.x->border_tile);
4304 x_uncatch_errors ();
4305 unblock_input ();
4306 x_update_cursor (f, true);
4307 x_set_frame_alpha (f);
4310 /* The focus has changed. Update the frames as necessary to reflect
4311 the new situation. Note that we can't change the selected frame
4312 here, because the Lisp code we are interrupting might become confused.
4313 Each event gets marked with the frame in which it occurred, so the
4314 Lisp code can tell when the switch took place by examining the events. */
4316 static void
4317 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4319 struct frame *old_focus = dpyinfo->x_focus_frame;
4321 if (frame != dpyinfo->x_focus_frame)
4323 /* Set this before calling other routines, so that they see
4324 the correct value of x_focus_frame. */
4325 dpyinfo->x_focus_frame = frame;
4327 if (old_focus && old_focus->auto_lower)
4328 x_lower_frame (old_focus);
4330 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4331 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4332 else
4333 dpyinfo->x_pending_autoraise_frame = NULL;
4336 x_frame_rehighlight (dpyinfo);
4339 /* Handle FocusIn and FocusOut state changes for FRAME.
4340 If FRAME has focus and there exists more than one frame, puts
4341 a FOCUS_IN_EVENT into *BUFP. */
4343 static void
4344 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4346 if (type == FocusIn)
4348 if (dpyinfo->x_focus_event_frame != frame)
4350 x_new_focus_frame (dpyinfo, frame);
4351 dpyinfo->x_focus_event_frame = frame;
4353 /* Don't stop displaying the initial startup message
4354 for a switch-frame event we don't need. */
4355 /* When run as a daemon, Vterminal_frame is always NIL. */
4356 bufp->arg = (((NILP (Vterminal_frame)
4357 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4358 || EQ (Fdaemonp (), Qt))
4359 && CONSP (Vframe_list)
4360 && !NILP (XCDR (Vframe_list)))
4361 ? Qt : Qnil);
4362 bufp->kind = FOCUS_IN_EVENT;
4363 XSETFRAME (bufp->frame_or_window, frame);
4366 frame->output_data.x->focus_state |= state;
4368 #ifdef HAVE_X_I18N
4369 if (FRAME_XIC (frame))
4370 XSetICFocus (FRAME_XIC (frame));
4371 #endif
4373 else if (type == FocusOut)
4375 frame->output_data.x->focus_state &= ~state;
4377 if (dpyinfo->x_focus_event_frame == frame)
4379 dpyinfo->x_focus_event_frame = 0;
4380 x_new_focus_frame (dpyinfo, 0);
4382 bufp->kind = FOCUS_OUT_EVENT;
4383 XSETFRAME (bufp->frame_or_window, frame);
4386 #ifdef HAVE_X_I18N
4387 if (FRAME_XIC (frame))
4388 XUnsetICFocus (FRAME_XIC (frame));
4389 #endif
4390 if (frame->pointer_invisible)
4391 XTtoggle_invisible_pointer (frame, false);
4395 /* Return the Emacs frame-object corresponding to an X window.
4396 It could be the frame's main window or an icon window. */
4398 static struct frame *
4399 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4401 Lisp_Object tail, frame;
4402 struct frame *f;
4404 if (wdesc == None)
4405 return NULL;
4407 FOR_EACH_FRAME (tail, frame)
4409 f = XFRAME (frame);
4410 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4411 continue;
4412 if (f->output_data.x->hourglass_window == wdesc)
4413 return f;
4414 #ifdef USE_X_TOOLKIT
4415 if ((f->output_data.x->edit_widget
4416 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4417 /* A tooltip frame? */
4418 || (!f->output_data.x->edit_widget
4419 && FRAME_X_WINDOW (f) == wdesc)
4420 || f->output_data.x->icon_desc == wdesc)
4421 return f;
4422 #else /* not USE_X_TOOLKIT */
4423 #ifdef USE_GTK
4424 if (f->output_data.x->edit_widget)
4426 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4427 struct x_output *x = f->output_data.x;
4428 if (gwdesc != 0 && gwdesc == x->edit_widget)
4429 return f;
4431 #endif /* USE_GTK */
4432 if (FRAME_X_WINDOW (f) == wdesc
4433 || f->output_data.x->icon_desc == wdesc)
4434 return f;
4435 #endif /* not USE_X_TOOLKIT */
4437 return 0;
4440 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4442 /* Like x_window_to_frame but also compares the window with the widget's
4443 windows. */
4445 static struct frame *
4446 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4448 Lisp_Object tail, frame;
4449 struct frame *f, *found = NULL;
4450 struct x_output *x;
4452 if (wdesc == None)
4453 return NULL;
4455 FOR_EACH_FRAME (tail, frame)
4457 if (found)
4458 break;
4459 f = XFRAME (frame);
4460 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4462 /* This frame matches if the window is any of its widgets. */
4463 x = f->output_data.x;
4464 if (x->hourglass_window == wdesc)
4465 found = f;
4466 else if (x->widget)
4468 #ifdef USE_GTK
4469 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4470 if (gwdesc != 0
4471 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4472 found = f;
4473 #else
4474 if (wdesc == XtWindow (x->widget)
4475 || wdesc == XtWindow (x->column_widget)
4476 || wdesc == XtWindow (x->edit_widget))
4477 found = f;
4478 /* Match if the window is this frame's menubar. */
4479 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4480 found = f;
4481 #endif
4483 else if (FRAME_X_WINDOW (f) == wdesc)
4484 /* A tooltip frame. */
4485 found = f;
4489 return found;
4492 /* Likewise, but consider only the menu bar widget. */
4494 static struct frame *
4495 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4496 const XEvent *event)
4498 Window wdesc = event->xany.window;
4499 Lisp_Object tail, frame;
4500 struct frame *f;
4501 struct x_output *x;
4503 if (wdesc == None)
4504 return NULL;
4506 FOR_EACH_FRAME (tail, frame)
4508 f = XFRAME (frame);
4509 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4510 continue;
4511 x = f->output_data.x;
4512 #ifdef USE_GTK
4513 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4514 return f;
4515 #else
4516 /* Match if the window is this frame's menubar. */
4517 if (x->menubar_widget
4518 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4519 return f;
4520 #endif
4522 return 0;
4525 /* Return the frame whose principal (outermost) window is WDESC.
4526 If WDESC is some other (smaller) window, we return 0. */
4528 struct frame *
4529 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4531 Lisp_Object tail, frame;
4532 struct frame *f;
4533 struct x_output *x;
4535 if (wdesc == None)
4536 return NULL;
4538 FOR_EACH_FRAME (tail, frame)
4540 f = XFRAME (frame);
4541 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4542 continue;
4543 x = f->output_data.x;
4545 if (x->widget)
4547 /* This frame matches if the window is its topmost widget. */
4548 #ifdef USE_GTK
4549 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4550 if (gwdesc == x->widget)
4551 return f;
4552 #else
4553 if (wdesc == XtWindow (x->widget))
4554 return f;
4555 #endif
4557 else if (FRAME_X_WINDOW (f) == wdesc)
4558 /* Tooltip frame. */
4559 return f;
4561 return 0;
4564 #else /* !USE_X_TOOLKIT && !USE_GTK */
4566 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4567 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4569 #endif /* USE_X_TOOLKIT || USE_GTK */
4571 /* The focus may have changed. Figure out if it is a real focus change,
4572 by checking both FocusIn/Out and Enter/LeaveNotify events.
4574 Returns FOCUS_IN_EVENT event in *BUFP. */
4576 static void
4577 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4578 const XEvent *event, struct input_event *bufp)
4580 if (!frame)
4581 return;
4583 switch (event->type)
4585 case EnterNotify:
4586 case LeaveNotify:
4588 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4589 int focus_state
4590 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4592 if (event->xcrossing.detail != NotifyInferior
4593 && event->xcrossing.focus
4594 && ! (focus_state & FOCUS_EXPLICIT))
4595 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4596 FOCUS_IMPLICIT,
4597 dpyinfo, frame, bufp);
4599 break;
4601 case FocusIn:
4602 case FocusOut:
4603 x_focus_changed (event->type,
4604 (event->xfocus.detail == NotifyPointer ?
4605 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4606 dpyinfo, frame, bufp);
4607 break;
4609 case ClientMessage:
4610 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4612 enum xembed_message msg = event->xclient.data.l[1];
4613 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4614 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4616 break;
4621 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4622 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4624 void
4625 x_mouse_leave (struct x_display_info *dpyinfo)
4627 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4629 #endif
4631 /* The focus has changed, or we have redirected a frame's focus to
4632 another frame (this happens when a frame uses a surrogate
4633 mini-buffer frame). Shift the highlight as appropriate.
4635 The FRAME argument doesn't necessarily have anything to do with which
4636 frame is being highlighted or un-highlighted; we only use it to find
4637 the appropriate X display info. */
4639 static void
4640 XTframe_rehighlight (struct frame *frame)
4642 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4645 static void
4646 x_frame_rehighlight (struct x_display_info *dpyinfo)
4648 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4650 if (dpyinfo->x_focus_frame)
4652 dpyinfo->x_highlight_frame
4653 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4654 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4655 : dpyinfo->x_focus_frame);
4656 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4658 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4659 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4662 else
4663 dpyinfo->x_highlight_frame = 0;
4665 if (dpyinfo->x_highlight_frame != old_highlight)
4667 if (old_highlight)
4668 frame_unhighlight (old_highlight);
4669 if (dpyinfo->x_highlight_frame)
4670 frame_highlight (dpyinfo->x_highlight_frame);
4676 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4678 /* Initialize mode_switch_bit and modifier_meaning. */
4679 static void
4680 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4682 int min_code, max_code;
4683 KeySym *syms;
4684 int syms_per_code;
4685 XModifierKeymap *mods;
4687 dpyinfo->meta_mod_mask = 0;
4688 dpyinfo->shift_lock_mask = 0;
4689 dpyinfo->alt_mod_mask = 0;
4690 dpyinfo->super_mod_mask = 0;
4691 dpyinfo->hyper_mod_mask = 0;
4693 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4695 syms = XGetKeyboardMapping (dpyinfo->display,
4696 min_code, max_code - min_code + 1,
4697 &syms_per_code);
4698 mods = XGetModifierMapping (dpyinfo->display);
4700 /* Scan the modifier table to see which modifier bits the Meta and
4701 Alt keysyms are on. */
4703 int row, col; /* The row and column in the modifier table. */
4704 bool found_alt_or_meta;
4706 for (row = 3; row < 8; row++)
4708 found_alt_or_meta = false;
4709 for (col = 0; col < mods->max_keypermod; col++)
4711 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4713 /* Zeroes are used for filler. Skip them. */
4714 if (code == 0)
4715 continue;
4717 /* Are any of this keycode's keysyms a meta key? */
4719 int code_col;
4721 for (code_col = 0; code_col < syms_per_code; code_col++)
4723 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4725 switch (sym)
4727 case XK_Meta_L:
4728 case XK_Meta_R:
4729 found_alt_or_meta = true;
4730 dpyinfo->meta_mod_mask |= (1 << row);
4731 break;
4733 case XK_Alt_L:
4734 case XK_Alt_R:
4735 found_alt_or_meta = true;
4736 dpyinfo->alt_mod_mask |= (1 << row);
4737 break;
4739 case XK_Hyper_L:
4740 case XK_Hyper_R:
4741 if (!found_alt_or_meta)
4742 dpyinfo->hyper_mod_mask |= (1 << row);
4743 code_col = syms_per_code;
4744 col = mods->max_keypermod;
4745 break;
4747 case XK_Super_L:
4748 case XK_Super_R:
4749 if (!found_alt_or_meta)
4750 dpyinfo->super_mod_mask |= (1 << row);
4751 code_col = syms_per_code;
4752 col = mods->max_keypermod;
4753 break;