Small cus-start fix for custom-delayed-init-variables
[emacs.git] / src / xterm.c
blobf771631dafaaaec5692ce9f0eda1033b3b105ac8
1 /* X Communication module for terminals which understand the X protocol.
3 Copyright (C) 1989, 1993-2018 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) && defined USE_GTK
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 #ifdef USE_GTK
1002 && !NILP (Fframe_parameter (tip_frame, Qtooltip))
1003 #endif
1005 return;
1007 if (! FRAME_CR_SURFACE (f))
1009 int width, height;
1010 #ifdef USE_GTK
1011 if (FRAME_GTK_WIDGET (f))
1013 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1014 width = gdk_window_get_width (w);
1015 height = gdk_window_get_height (w);
1017 else
1018 #endif
1020 width = FRAME_PIXEL_WIDTH (f);
1021 height = FRAME_PIXEL_HEIGHT (f);
1022 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1023 height += FRAME_TOOL_BAR_HEIGHT (f);
1024 if (! FRAME_EXTERNAL_MENU_BAR (f))
1025 height += FRAME_MENU_BAR_HEIGHT (f);
1028 if (width > 0 && height > 0)
1030 block_input();
1031 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1032 (CAIRO_FORMAT_ARGB32, width, height);
1033 unblock_input();
1036 #endif /* USE_CAIRO */
1039 /* Start update of window W. */
1041 static void
1042 x_update_window_begin (struct window *w)
1044 struct frame *f = XFRAME (WINDOW_FRAME (w));
1045 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1047 w->output_cursor = w->cursor;
1049 block_input ();
1051 if (f == hlinfo->mouse_face_mouse_frame)
1053 /* Don't do highlighting for mouse motion during the update. */
1054 hlinfo->mouse_face_defer = true;
1056 /* If F needs to be redrawn, simply forget about any prior mouse
1057 highlighting. */
1058 if (FRAME_GARBAGED_P (f))
1059 hlinfo->mouse_face_window = Qnil;
1062 unblock_input ();
1066 /* Draw a vertical window border from (x,y0) to (x,y1) */
1068 static void
1069 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1071 struct frame *f = XFRAME (WINDOW_FRAME (w));
1072 struct face *face;
1074 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1075 if (face)
1076 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1077 face->foreground);
1079 #ifdef USE_CAIRO
1080 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1081 #else
1082 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1083 f->output_data.x->normal_gc, x, y0, x, y1);
1084 #endif
1087 /* Draw a window divider from (x0,y0) to (x1,y1) */
1089 static void
1090 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1092 struct frame *f = XFRAME (WINDOW_FRAME (w));
1093 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1094 struct face *face_first
1095 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1096 struct face *face_last
1097 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1098 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1099 unsigned long color_first = (face_first
1100 ? face_first->foreground
1101 : FRAME_FOREGROUND_PIXEL (f));
1102 unsigned long color_last = (face_last
1103 ? face_last->foreground
1104 : FRAME_FOREGROUND_PIXEL (f));
1105 Display *display = FRAME_X_DISPLAY (f);
1107 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
1108 /* A vertical divider, at least three pixels wide: Draw first and
1109 last pixels differently. */
1111 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1112 x_fill_rectangle (f, f->output_data.x->normal_gc,
1113 x0, y0, 1, y1 - y0);
1114 XSetForeground (display, f->output_data.x->normal_gc, color);
1115 x_fill_rectangle (f, f->output_data.x->normal_gc,
1116 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1117 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1118 x_fill_rectangle (f, f->output_data.x->normal_gc,
1119 x1 - 1, y0, 1, y1 - y0);
1121 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
1122 /* A horizontal divider, at least three pixels high: Draw first and
1123 last pixels differently. */
1125 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1126 x_fill_rectangle (f, f->output_data.x->normal_gc,
1127 x0, y0, x1 - x0, 1);
1128 XSetForeground (display, f->output_data.x->normal_gc, color);
1129 x_fill_rectangle (f, f->output_data.x->normal_gc,
1130 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1131 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1132 x_fill_rectangle (f, f->output_data.x->normal_gc,
1133 x0, y1 - 1, x1 - x0, 1);
1135 else
1137 /* In any other case do not draw the first and last pixels
1138 differently. */
1139 XSetForeground (display, f->output_data.x->normal_gc, color);
1140 x_fill_rectangle (f, f->output_data.x->normal_gc,
1141 x0, y0, x1 - x0, y1 - y0);
1145 /* End update of window W.
1147 Draw vertical borders between horizontally adjacent windows, and
1148 display W's cursor if CURSOR_ON_P is non-zero.
1150 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1151 glyphs in mouse-face were overwritten. In that case we have to
1152 make sure that the mouse-highlight is properly redrawn.
1154 W may be a menu bar pseudo-window in case we don't have X toolkit
1155 support. Such windows don't have a cursor, so don't display it
1156 here. */
1158 static void
1159 x_update_window_end (struct window *w, bool cursor_on_p,
1160 bool mouse_face_overwritten_p)
1162 if (!w->pseudo_window_p)
1164 block_input ();
1166 if (cursor_on_p)
1167 display_and_set_cursor (w, true,
1168 w->output_cursor.hpos, w->output_cursor.vpos,
1169 w->output_cursor.x, w->output_cursor.y);
1171 if (draw_window_fringes (w, true))
1173 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1174 x_draw_right_divider (w);
1175 else
1176 x_draw_vertical_border (w);
1179 unblock_input ();
1182 /* If a row with mouse-face was overwritten, arrange for
1183 XTframe_up_to_date to redisplay the mouse highlight. */
1184 if (mouse_face_overwritten_p)
1186 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1188 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1189 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1190 hlinfo->mouse_face_window = Qnil;
1194 /* Show the frame back buffer. If frame is double-buffered,
1195 atomically publish to the user's screen graphics updates made since
1196 the last call to show_back_buffer. */
1197 static void
1198 show_back_buffer (struct frame *f)
1200 block_input ();
1201 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1203 #ifdef HAVE_XDBE
1204 XdbeSwapInfo swap_info;
1205 memset (&swap_info, 0, sizeof (swap_info));
1206 swap_info.swap_window = FRAME_X_WINDOW (f);
1207 swap_info.swap_action = XdbeCopied;
1208 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1209 #else
1210 eassert (!"should have back-buffer only with XDBE");
1211 #endif
1213 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1214 unblock_input ();
1217 /* Updates back buffer and flushes changes to display. Called from
1218 minibuf read code. Note that we display the back buffer even if
1219 buffer flipping is blocked. */
1220 static void
1221 x_flip_and_flush (struct frame *f)
1223 block_input ();
1224 if (FRAME_X_NEED_BUFFER_FLIP (f))
1225 show_back_buffer (f);
1226 x_flush (f);
1227 unblock_input ();
1230 /* End update of frame F. This function is installed as a hook in
1231 update_end. */
1233 static void
1234 x_update_end (struct frame *f)
1236 /* Mouse highlight may be displayed again. */
1237 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1239 #ifdef USE_CAIRO
1240 if (FRAME_CR_SURFACE (f))
1242 cairo_t *cr = 0;
1243 block_input();
1244 #if defined (USE_GTK) && defined (HAVE_GTK3)
1245 if (FRAME_GTK_WIDGET (f))
1247 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1248 cr = gdk_cairo_create (w);
1250 else
1251 #endif
1253 cairo_surface_t *surface;
1254 int width = FRAME_PIXEL_WIDTH (f);
1255 int height = FRAME_PIXEL_HEIGHT (f);
1256 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1257 height += FRAME_TOOL_BAR_HEIGHT (f);
1258 if (! FRAME_EXTERNAL_MENU_BAR (f))
1259 height += FRAME_MENU_BAR_HEIGHT (f);
1260 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1261 FRAME_X_DRAWABLE (f),
1262 FRAME_DISPLAY_INFO (f)->visual,
1263 width,
1264 height);
1265 cr = cairo_create (surface);
1266 cairo_surface_destroy (surface);
1269 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1270 cairo_paint (cr);
1271 cairo_destroy (cr);
1272 unblock_input ();
1274 #endif
1276 #ifndef XFlush
1277 block_input ();
1278 XFlush (FRAME_X_DISPLAY (f));
1279 unblock_input ();
1280 #endif
1283 /* This function is called from various places in xdisp.c
1284 whenever a complete update has been performed. */
1286 static void
1287 XTframe_up_to_date (struct frame *f)
1289 eassert (FRAME_X_P (f));
1290 block_input ();
1291 FRAME_MOUSE_UPDATE (f);
1292 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1293 show_back_buffer (f);
1294 unblock_input ();
1297 static void
1298 XTbuffer_flipping_unblocked_hook (struct frame *f)
1300 if (FRAME_X_NEED_BUFFER_FLIP (f))
1301 show_back_buffer (f);
1305 * x_clear_under_internal_border:
1307 * Clear area of frame F's internal border. If the internal border face
1308 * of F has been specified (is not null), fill the area with that face.
1310 void
1311 x_clear_under_internal_border (struct frame *f)
1313 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1315 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1316 int width = FRAME_PIXEL_WIDTH (f);
1317 int height = FRAME_PIXEL_HEIGHT (f);
1318 #ifdef USE_GTK
1319 int margin = 0;
1320 #else
1321 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1322 #endif
1323 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1325 block_input ();
1327 if (face)
1329 unsigned long color = face->background;
1330 Display *display = FRAME_X_DISPLAY (f);
1331 GC gc = f->output_data.x->normal_gc;
1333 XSetForeground (display, gc, color);
1334 x_fill_rectangle (f, gc, 0, margin, width, border);
1335 x_fill_rectangle (f, gc, 0, 0, border, height);
1336 x_fill_rectangle (f, gc, width - border, 0, border, height);
1337 x_fill_rectangle (f, gc, 0, height - border, width, border);
1338 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1340 else
1342 x_clear_area (f, 0, 0, border, height);
1343 x_clear_area (f, 0, margin, width, border);
1344 x_clear_area (f, width - border, 0, border, height);
1345 x_clear_area (f, 0, height - border, width, border);
1348 unblock_input ();
1352 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1353 arrow bitmaps, or clear the fringes if no bitmaps are required
1354 before DESIRED_ROW is made current. This function is called from
1355 update_window_line only if it is known that there are differences
1356 between bitmaps to be drawn between current row and DESIRED_ROW. */
1358 static void
1359 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1361 eassert (w);
1363 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1364 desired_row->redraw_fringe_bitmaps_p = true;
1366 #ifdef USE_X_TOOLKIT
1367 /* When a window has disappeared, make sure that no rest of
1368 full-width rows stays visible in the internal border. Could
1369 check here if updated window is the leftmost/rightmost window,
1370 but I guess it's not worth doing since vertically split windows
1371 are almost never used, internal border is rarely set, and the
1372 overhead is very small. */
1374 struct frame *f;
1375 int width, height;
1377 if (windows_or_buffers_changed
1378 && desired_row->full_width_p
1379 && (f = XFRAME (w->frame),
1380 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1381 width != 0)
1382 && (height = desired_row->visible_height,
1383 height > 0))
1385 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1386 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1388 block_input ();
1389 if (face)
1391 unsigned long color = face->background;
1392 Display *display = FRAME_X_DISPLAY (f);
1393 GC gc = f->output_data.x->normal_gc;
1395 XSetForeground (display, gc, color);
1396 x_fill_rectangle (f, gc, 0, y, width, height);
1397 x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
1398 width, height);
1399 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1401 else
1403 x_clear_area (f, 0, y, width, height);
1404 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1406 unblock_input ();
1409 #endif
1412 static void
1413 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1415 struct frame *f = XFRAME (WINDOW_FRAME (w));
1416 Display *display = FRAME_X_DISPLAY (f);
1417 GC gc = f->output_data.x->normal_gc;
1418 struct face *face = p->face;
1420 /* Must clip because of partially visible lines. */
1421 x_clip_to_row (w, row, ANY_AREA, gc);
1423 if (p->bx >= 0 && !p->overlay_p)
1425 /* In case the same realized face is used for fringes and
1426 for something displayed in the text (e.g. face `region' on
1427 mono-displays, the fill style may have been changed to
1428 FillSolid in x_draw_glyph_string_background. */
1429 if (face->stipple)
1430 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1431 else
1432 XSetForeground (display, face->gc, face->background);
1434 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1436 if (!face->stipple)
1437 XSetForeground (display, face->gc, face->foreground);
1440 #ifdef USE_CAIRO
1441 if (p->which && p->which < max_fringe_bmp)
1443 XGCValues gcv;
1445 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1446 XSetForeground (display, gc, (p->cursor_p
1447 ? (p->overlay_p ? face->background
1448 : f->output_data.x->cursor_pixel)
1449 : face->foreground));
1450 XSetBackground (display, gc, face->background);
1451 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1452 p->wd, p->h, p->x, p->y, p->overlay_p);
1453 XSetForeground (display, gc, gcv.foreground);
1454 XSetBackground (display, gc, gcv.background);
1456 #else /* not USE_CAIRO */
1457 if (p->which)
1459 Drawable drawable = FRAME_X_DRAWABLE (f);
1460 char *bits;
1461 Pixmap pixmap, clipmask = (Pixmap) 0;
1462 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1463 XGCValues gcv;
1465 if (p->wd > 8)
1466 bits = (char *) (p->bits + p->dh);
1467 else
1468 bits = (char *) p->bits + p->dh;
1470 /* Draw the bitmap. I believe these small pixmaps can be cached
1471 by the server. */
1472 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1473 (p->cursor_p
1474 ? (p->overlay_p ? face->background
1475 : f->output_data.x->cursor_pixel)
1476 : face->foreground),
1477 face->background, depth);
1479 if (p->overlay_p)
1481 clipmask = XCreatePixmapFromBitmapData (display,
1482 FRAME_DISPLAY_INFO (f)->root_window,
1483 bits, p->wd, p->h,
1484 1, 0, 1);
1485 gcv.clip_mask = clipmask;
1486 gcv.clip_x_origin = p->x;
1487 gcv.clip_y_origin = p->y;
1488 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1491 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1492 p->wd, p->h, p->x, p->y);
1493 XFreePixmap (display, pixmap);
1495 if (p->overlay_p)
1497 gcv.clip_mask = (Pixmap) 0;
1498 XChangeGC (display, gc, GCClipMask, &gcv);
1499 XFreePixmap (display, clipmask);
1502 #endif /* not USE_CAIRO */
1504 x_reset_clip_rectangles (f, gc);
1507 /***********************************************************************
1508 Glyph display
1509 ***********************************************************************/
1513 static void x_set_glyph_string_clipping (struct glyph_string *);
1514 static void x_set_glyph_string_gc (struct glyph_string *);
1515 static void x_draw_glyph_string_foreground (struct glyph_string *);
1516 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1517 static void x_draw_glyph_string_box (struct glyph_string *);
1518 static void x_draw_glyph_string (struct glyph_string *);
1519 static _Noreturn void x_delete_glyphs (struct frame *, int);
1520 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1521 static void x_set_cursor_gc (struct glyph_string *);
1522 static void x_set_mode_line_face_gc (struct glyph_string *);
1523 static void x_set_mouse_face_gc (struct glyph_string *);
1524 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1525 unsigned long *, double, int);
1526 static void x_setup_relief_color (struct frame *, struct relief *,
1527 double, int, unsigned long);
1528 static void x_setup_relief_colors (struct glyph_string *);
1529 static void x_draw_image_glyph_string (struct glyph_string *);
1530 static void x_draw_image_relief (struct glyph_string *);
1531 static void x_draw_image_foreground (struct glyph_string *);
1532 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1533 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1534 int, int, int);
1535 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1536 int, bool, bool, bool, bool, bool,
1537 XRectangle *);
1538 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1539 int, bool, bool, XRectangle *);
1540 static void x_scroll_bar_clear (struct frame *);
1542 #ifdef GLYPH_DEBUG
1543 static void x_check_font (struct frame *, struct font *);
1544 #endif
1547 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1548 face. */
1550 static void
1551 x_set_cursor_gc (struct glyph_string *s)
1553 if (s->font == FRAME_FONT (s->f)
1554 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1555 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1556 && !s->cmp)
1557 s->gc = s->f->output_data.x->cursor_gc;
1558 else
1560 /* Cursor on non-default face: must merge. */
1561 XGCValues xgcv;
1562 unsigned long mask;
1564 xgcv.background = s->f->output_data.x->cursor_pixel;
1565 xgcv.foreground = s->face->background;
1567 /* If the glyph would be invisible, try a different foreground. */
1568 if (xgcv.foreground == xgcv.background)
1569 xgcv.foreground = s->face->foreground;
1570 if (xgcv.foreground == xgcv.background)
1571 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1572 if (xgcv.foreground == xgcv.background)
1573 xgcv.foreground = s->face->foreground;
1575 /* Make sure the cursor is distinct from text in this face. */
1576 if (xgcv.background == s->face->background
1577 && xgcv.foreground == s->face->foreground)
1579 xgcv.background = s->face->foreground;
1580 xgcv.foreground = s->face->background;
1583 IF_DEBUG (x_check_font (s->f, s->font));
1584 xgcv.graphics_exposures = False;
1585 mask = GCForeground | GCBackground | GCGraphicsExposures;
1587 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1588 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1589 mask, &xgcv);
1590 else
1591 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1592 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1594 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1599 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1601 static void
1602 x_set_mouse_face_gc (struct glyph_string *s)
1604 int face_id;
1605 struct face *face;
1607 /* What face has to be used last for the mouse face? */
1608 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1609 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1610 if (face == NULL)
1611 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1613 if (s->first_glyph->type == CHAR_GLYPH)
1614 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1615 else
1616 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1617 s->face = FACE_FROM_ID (s->f, face_id);
1618 prepare_face_for_display (s->f, s->face);
1620 if (s->font == s->face->font)
1621 s->gc = s->face->gc;
1622 else
1624 /* Otherwise construct scratch_cursor_gc with values from FACE
1625 except for FONT. */
1626 XGCValues xgcv;
1627 unsigned long mask;
1629 xgcv.background = s->face->background;
1630 xgcv.foreground = s->face->foreground;
1631 xgcv.graphics_exposures = False;
1632 mask = GCForeground | GCBackground | GCGraphicsExposures;
1634 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1635 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1636 mask, &xgcv);
1637 else
1638 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1639 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1641 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1644 eassert (s->gc != 0);
1648 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1649 Faces to use in the mode line have already been computed when the
1650 matrix was built, so there isn't much to do, here. */
1652 static void
1653 x_set_mode_line_face_gc (struct glyph_string *s)
1655 s->gc = s->face->gc;
1659 /* Set S->gc of glyph string S for drawing that glyph string. Set
1660 S->stippled_p to a non-zero value if the face of S has a stipple
1661 pattern. */
1663 static void
1664 x_set_glyph_string_gc (struct glyph_string *s)
1666 prepare_face_for_display (s->f, s->face);
1668 if (s->hl == DRAW_NORMAL_TEXT)
1670 s->gc = s->face->gc;
1671 s->stippled_p = s->face->stipple != 0;
1673 else if (s->hl == DRAW_INVERSE_VIDEO)
1675 x_set_mode_line_face_gc (s);
1676 s->stippled_p = s->face->stipple != 0;
1678 else if (s->hl == DRAW_CURSOR)
1680 x_set_cursor_gc (s);
1681 s->stippled_p = false;
1683 else if (s->hl == DRAW_MOUSE_FACE)
1685 x_set_mouse_face_gc (s);
1686 s->stippled_p = s->face->stipple != 0;
1688 else if (s->hl == DRAW_IMAGE_RAISED
1689 || s->hl == DRAW_IMAGE_SUNKEN)
1691 s->gc = s->face->gc;
1692 s->stippled_p = s->face->stipple != 0;
1694 else
1695 emacs_abort ();
1697 /* GC must have been set. */
1698 eassert (s->gc != 0);
1702 /* Set clipping for output of glyph string S. S may be part of a mode
1703 line or menu if we don't have X toolkit support. */
1705 static void
1706 x_set_glyph_string_clipping (struct glyph_string *s)
1708 XRectangle *r = s->clip;
1709 int n = get_glyph_string_clip_rects (s, r, 2);
1711 if (n > 0)
1712 x_set_clip_rectangles (s->f, s->gc, r, n);
1713 s->num_clips = n;
1717 /* Set SRC's clipping for output of glyph string DST. This is called
1718 when we are drawing DST's left_overhang or right_overhang only in
1719 the area of SRC. */
1721 static void
1722 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1724 XRectangle r;
1726 r.x = src->x;
1727 r.width = src->width;
1728 r.y = src->y;
1729 r.height = src->height;
1730 dst->clip[0] = r;
1731 dst->num_clips = 1;
1732 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1736 /* RIF:
1737 Compute left and right overhang of glyph string S. */
1739 static void
1740 x_compute_glyph_string_overhangs (struct glyph_string *s)
1742 if (s->cmp == NULL
1743 && (s->first_glyph->type == CHAR_GLYPH
1744 || s->first_glyph->type == COMPOSITE_GLYPH))
1746 struct font_metrics metrics;
1748 if (s->first_glyph->type == CHAR_GLYPH)
1750 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1751 struct font *font = s->font;
1752 int i;
1754 for (i = 0; i < s->nchars; i++)
1755 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1756 font->driver->text_extents (font, code, s->nchars, &metrics);
1758 else
1760 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1762 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1764 s->right_overhang = (metrics.rbearing > metrics.width
1765 ? metrics.rbearing - metrics.width : 0);
1766 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1768 else if (s->cmp)
1770 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1771 s->left_overhang = - s->cmp->lbearing;
1776 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1778 static void
1779 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1781 XGCValues xgcv;
1782 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1783 XSetForeground (s->display, s->gc, xgcv.background);
1784 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1785 XSetForeground (s->display, s->gc, xgcv.foreground);
1789 /* Draw the background of glyph_string S. If S->background_filled_p
1790 is non-zero don't draw it. FORCE_P non-zero means draw the
1791 background even if it wouldn't be drawn normally. This is used
1792 when a string preceding S draws into the background of S, or S
1793 contains the first component of a composition. */
1795 static void
1796 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1798 /* Nothing to do if background has already been drawn or if it
1799 shouldn't be drawn in the first place. */
1800 if (!s->background_filled_p)
1802 int box_line_width = max (s->face->box_line_width, 0);
1804 if (s->stippled_p)
1806 /* Fill background with a stipple pattern. */
1807 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1808 x_fill_rectangle (s->f, s->gc, s->x,
1809 s->y + box_line_width,
1810 s->background_width,
1811 s->height - 2 * box_line_width);
1812 XSetFillStyle (s->display, s->gc, FillSolid);
1813 s->background_filled_p = true;
1815 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1816 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1817 font dimensions, since the actual glyphs might be
1818 much smaller. So in that case we always clear the
1819 rectangle with background color. */
1820 || FONT_TOO_HIGH (s->font)
1821 || s->font_not_found_p
1822 || s->extends_to_end_of_line_p
1823 || force_p)
1825 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1826 s->background_width,
1827 s->height - 2 * box_line_width);
1828 s->background_filled_p = true;
1834 /* Draw the foreground of glyph string S. */
1836 static void
1837 x_draw_glyph_string_foreground (struct glyph_string *s)
1839 int i, x;
1841 /* If first glyph of S has a left box line, start drawing the text
1842 of S to the right of that box line. */
1843 if (s->face->box != FACE_NO_BOX
1844 && s->first_glyph->left_box_line_p)
1845 x = s->x + eabs (s->face->box_line_width);
1846 else
1847 x = s->x;
1849 /* Draw characters of S as rectangles if S's font could not be
1850 loaded. */
1851 if (s->font_not_found_p)
1853 for (i = 0; i < s->nchars; ++i)
1855 struct glyph *g = s->first_glyph + i;
1856 x_draw_rectangle (s->f,
1857 s->gc, x, s->y, g->pixel_width - 1,
1858 s->height - 1);
1859 x += g->pixel_width;
1862 else
1864 struct font *font = s->font;
1865 int boff = font->baseline_offset;
1866 int y;
1868 if (font->vertical_centering)
1869 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1871 y = s->ybase - boff;
1872 if (s->for_overlaps
1873 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1874 font->driver->draw (s, 0, s->nchars, x, y, false);
1875 else
1876 font->driver->draw (s, 0, s->nchars, x, y, true);
1877 if (s->face->overstrike)
1878 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1882 /* Draw the foreground of composite glyph string S. */
1884 static void
1885 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1887 int i, j, x;
1888 struct font *font = s->font;
1890 /* If first glyph of S has a left box line, start drawing the text
1891 of S to the right of that box line. */
1892 if (s->face && s->face->box != FACE_NO_BOX
1893 && s->first_glyph->left_box_line_p)
1894 x = s->x + eabs (s->face->box_line_width);
1895 else
1896 x = s->x;
1898 /* S is a glyph string for a composition. S->cmp_from is the index
1899 of the first character drawn for glyphs of this composition.
1900 S->cmp_from == 0 means we are drawing the very first character of
1901 this composition. */
1903 /* Draw a rectangle for the composition if the font for the very
1904 first character of the composition could not be loaded. */
1905 if (s->font_not_found_p)
1907 if (s->cmp_from == 0)
1908 x_draw_rectangle (s->f, s->gc, x, s->y,
1909 s->width - 1, s->height - 1);
1911 else if (! s->first_glyph->u.cmp.automatic)
1913 int y = s->ybase;
1915 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1916 /* TAB in a composition means display glyphs with padding
1917 space on the left or right. */
1918 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1920 int xx = x + s->cmp->offsets[j * 2];
1921 int yy = y - s->cmp->offsets[j * 2 + 1];
1923 font->driver->draw (s, j, j + 1, xx, yy, false);
1924 if (s->face->overstrike)
1925 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1928 else
1930 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1931 Lisp_Object glyph;
1932 int y = s->ybase;
1933 int width = 0;
1935 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1937 glyph = LGSTRING_GLYPH (gstring, i);
1938 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1939 width += LGLYPH_WIDTH (glyph);
1940 else
1942 int xoff, yoff, wadjust;
1944 if (j < i)
1946 font->driver->draw (s, j, i, x, y, false);
1947 if (s->face->overstrike)
1948 font->driver->draw (s, j, i, x + 1, y, false);
1949 x += width;
1951 xoff = LGLYPH_XOFF (glyph);
1952 yoff = LGLYPH_YOFF (glyph);
1953 wadjust = LGLYPH_WADJUST (glyph);
1954 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1955 if (s->face->overstrike)
1956 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1957 false);
1958 x += wadjust;
1959 j = i + 1;
1960 width = 0;
1963 if (j < i)
1965 font->driver->draw (s, j, i, x, y, false);
1966 if (s->face->overstrike)
1967 font->driver->draw (s, j, i, x + 1, y, false);
1973 /* Draw the foreground of glyph string S for glyphless characters. */
1975 static void
1976 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1978 struct glyph *glyph = s->first_glyph;
1979 XChar2b char2b[8];
1980 int x, i, j;
1982 /* If first glyph of S has a left box line, start drawing the text
1983 of S to the right of that box line. */
1984 if (s->face && s->face->box != FACE_NO_BOX
1985 && s->first_glyph->left_box_line_p)
1986 x = s->x + eabs (s->face->box_line_width);
1987 else
1988 x = s->x;
1990 s->char2b = char2b;
1992 for (i = 0; i < s->nchars; i++, glyph++)
1994 char buf[7], *str = NULL;
1995 int len = glyph->u.glyphless.len;
1997 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1999 if (len > 0
2000 && CHAR_TABLE_P (Vglyphless_char_display)
2001 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
2002 >= 1))
2004 Lisp_Object acronym
2005 = (! glyph->u.glyphless.for_no_font
2006 ? CHAR_TABLE_REF (Vglyphless_char_display,
2007 glyph->u.glyphless.ch)
2008 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
2009 if (STRINGP (acronym))
2010 str = SSDATA (acronym);
2013 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
2015 unsigned int ch = glyph->u.glyphless.ch;
2016 eassume (ch <= MAX_CHAR);
2017 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
2018 str = buf;
2021 if (str)
2023 int upper_len = (len + 1) / 2;
2024 unsigned code;
2026 /* It is assured that all LEN characters in STR is ASCII. */
2027 for (j = 0; j < len; j++)
2029 code = s->font->driver->encode_char (s->font, str[j]);
2030 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
2032 s->font->driver->draw (s, 0, upper_len,
2033 x + glyph->slice.glyphless.upper_xoff,
2034 s->ybase + glyph->slice.glyphless.upper_yoff,
2035 false);
2036 s->font->driver->draw (s, upper_len, len,
2037 x + glyph->slice.glyphless.lower_xoff,
2038 s->ybase + glyph->slice.glyphless.lower_yoff,
2039 false);
2041 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
2042 x_draw_rectangle (s->f, s->gc,
2043 x, s->ybase - glyph->ascent,
2044 glyph->pixel_width - 1,
2045 glyph->ascent + glyph->descent - 1);
2046 x += glyph->pixel_width;
2050 #ifdef USE_X_TOOLKIT
2052 #ifdef USE_LUCID
2054 /* Return the frame on which widget WIDGET is used.. Abort if frame
2055 cannot be determined. */
2057 static struct frame *
2058 x_frame_of_widget (Widget widget)
2060 struct x_display_info *dpyinfo;
2061 Lisp_Object tail, frame;
2062 struct frame *f;
2064 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2066 /* Find the top-level shell of the widget. Note that this function
2067 can be called when the widget is not yet realized, so XtWindow
2068 (widget) == 0. That's the reason we can't simply use
2069 x_any_window_to_frame. */
2070 while (!XtIsTopLevelShell (widget))
2071 widget = XtParent (widget);
2073 /* Look for a frame with that top-level widget. Allocate the color
2074 on that frame to get the right gamma correction value. */
2075 FOR_EACH_FRAME (tail, frame)
2077 f = XFRAME (frame);
2078 if (FRAME_X_P (f)
2079 && f->output_data.nothing != 1
2080 && FRAME_DISPLAY_INFO (f) == dpyinfo
2081 && f->output_data.x->widget == widget)
2082 return f;
2084 emacs_abort ();
2087 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2088 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2089 If this produces the same color as PIXEL, try a color where all RGB
2090 values have DELTA added. Return the allocated color in *PIXEL.
2091 DISPLAY is the X display, CMAP is the colormap to operate on.
2092 Value is true if successful. */
2094 bool
2095 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2096 unsigned long *pixel, double factor, int delta)
2098 struct frame *f = x_frame_of_widget (widget);
2099 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2102 #endif /* USE_LUCID */
2105 /* Structure specifying which arguments should be passed by Xt to
2106 cvt_string_to_pixel. We want the widget's screen and colormap. */
2108 static XtConvertArgRec cvt_string_to_pixel_args[] =
2110 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2111 sizeof (Screen *)},
2112 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2113 sizeof (Colormap)}
2117 /* The address of this variable is returned by
2118 cvt_string_to_pixel. */
2120 static Pixel cvt_string_to_pixel_value;
2123 /* Convert a color name to a pixel color.
2125 DPY is the display we are working on.
2127 ARGS is an array of *NARGS XrmValue structures holding additional
2128 information about the widget for which the conversion takes place.
2129 The contents of this array are determined by the specification
2130 in cvt_string_to_pixel_args.
2132 FROM is a pointer to an XrmValue which points to the color name to
2133 convert. TO is an XrmValue in which to return the pixel color.
2135 CLOSURE_RET is a pointer to user-data, in which we record if
2136 we allocated the color or not.
2138 Value is True if successful, False otherwise. */
2140 static Boolean
2141 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2142 XrmValue *from, XrmValue *to,
2143 XtPointer *closure_ret)
2145 Screen *screen;
2146 Colormap cmap;
2147 Pixel pixel;
2148 String color_name;
2149 XColor color;
2151 if (*nargs != 2)
2153 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2154 "wrongParameters", "cvt_string_to_pixel",
2155 "XtToolkitError",
2156 "Screen and colormap args required", NULL, NULL);
2157 return False;
2160 screen = *(Screen **) args[0].addr;
2161 cmap = *(Colormap *) args[1].addr;
2162 color_name = (String) from->addr;
2164 if (strcmp (color_name, XtDefaultBackground) == 0)
2166 *closure_ret = (XtPointer) False;
2167 pixel = WhitePixelOfScreen (screen);
2169 else if (strcmp (color_name, XtDefaultForeground) == 0)
2171 *closure_ret = (XtPointer) False;
2172 pixel = BlackPixelOfScreen (screen);
2174 else if (XParseColor (dpy, cmap, color_name, &color)
2175 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2177 pixel = color.pixel;
2178 *closure_ret = (XtPointer) True;
2180 else
2182 String params[1];
2183 Cardinal nparams = 1;
2185 params[0] = color_name;
2186 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2187 "badValue", "cvt_string_to_pixel",
2188 "XtToolkitError", "Invalid color '%s'",
2189 params, &nparams);
2190 return False;
2193 if (to->addr != NULL)
2195 if (to->size < sizeof (Pixel))
2197 to->size = sizeof (Pixel);
2198 return False;
2201 *(Pixel *) to->addr = pixel;
2203 else
2205 cvt_string_to_pixel_value = pixel;
2206 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2209 to->size = sizeof (Pixel);
2210 return True;
2214 /* Free a pixel color which was previously allocated via
2215 cvt_string_to_pixel. This is registered as the destructor
2216 for this type of resource via XtSetTypeConverter.
2218 APP is the application context in which we work.
2220 TO is a pointer to an XrmValue holding the color to free.
2221 CLOSURE is the value we stored in CLOSURE_RET for this color
2222 in cvt_string_to_pixel.
2224 ARGS and NARGS are like for cvt_string_to_pixel. */
2226 static void
2227 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2228 Cardinal *nargs)
2230 if (*nargs != 2)
2232 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2233 "XtToolkitError",
2234 "Screen and colormap arguments required",
2235 NULL, NULL);
2237 else if (closure != NULL)
2239 /* We did allocate the pixel, so free it. */
2240 Screen *screen = *(Screen **) args[0].addr;
2241 Colormap cmap = *(Colormap *) args[1].addr;
2242 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2243 (Pixel *) to->addr, 1);
2248 #endif /* USE_X_TOOLKIT */
2251 /* Value is an array of XColor structures for the contents of the
2252 color map of display DPY. Set *NCELLS to the size of the array.
2253 Note that this probably shouldn't be called for large color maps,
2254 say a 24-bit TrueColor map. */
2256 static const XColor *
2257 x_color_cells (Display *dpy, int *ncells)
2259 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2260 eassume (dpyinfo);
2262 if (dpyinfo->color_cells == NULL)
2264 Screen *screen = dpyinfo->screen;
2265 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2266 int i;
2268 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2269 sizeof *dpyinfo->color_cells);
2270 dpyinfo->ncolor_cells = ncolor_cells;
2272 for (i = 0; i < ncolor_cells; ++i)
2273 dpyinfo->color_cells[i].pixel = i;
2275 XQueryColors (dpy, dpyinfo->cmap,
2276 dpyinfo->color_cells, ncolor_cells);
2279 *ncells = dpyinfo->ncolor_cells;
2280 return dpyinfo->color_cells;
2284 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2285 colors in COLORS. Use cached information, if available. */
2287 void
2288 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2290 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2292 if (dpyinfo->red_bits > 0)
2294 /* For TrueColor displays, we can decompose the RGB value
2295 directly. */
2296 int i;
2297 unsigned int rmult, gmult, bmult;
2298 unsigned int rmask, gmask, bmask;
2300 rmask = (1 << dpyinfo->red_bits) - 1;
2301 gmask = (1 << dpyinfo->green_bits) - 1;
2302 bmask = (1 << dpyinfo->blue_bits) - 1;
2303 /* If we're widening, for example, 8 bits in the pixel value to
2304 16 bits for the separate-color representation, we want to
2305 extrapolate the lower bits based on those bits available --
2306 in other words, we'd like 0xff to become 0xffff instead of
2307 the 0xff00 we'd get by just zero-filling the lower bits.
2309 We generate a 32-bit scaled-up value and shift it, in case
2310 the bit count doesn't divide 16 evenly (e.g., when dealing
2311 with a 3-3-2 bit RGB display), to get more of the lower bits
2312 correct.
2314 Should we cache the multipliers in dpyinfo? Maybe
2315 special-case the 8-8-8 common case? */
2316 rmult = 0xffffffff / rmask;
2317 gmult = 0xffffffff / gmask;
2318 bmult = 0xffffffff / bmask;
2320 for (i = 0; i < ncolors; ++i)
2322 unsigned int r, g, b;
2323 unsigned long pixel = colors[i].pixel;
2325 r = (pixel >> dpyinfo->red_offset) & rmask;
2326 g = (pixel >> dpyinfo->green_offset) & gmask;
2327 b = (pixel >> dpyinfo->blue_offset) & bmask;
2329 colors[i].red = (r * rmult) >> 16;
2330 colors[i].green = (g * gmult) >> 16;
2331 colors[i].blue = (b * bmult) >> 16;
2333 return;
2336 if (dpyinfo->color_cells)
2338 int i;
2339 for (i = 0; i < ncolors; ++i)
2341 unsigned long pixel = colors[i].pixel;
2342 eassert (pixel < dpyinfo->ncolor_cells);
2343 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2344 colors[i] = dpyinfo->color_cells[pixel];
2346 return;
2349 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2353 /* On frame F, translate pixel color to RGB values for the color in
2354 COLOR. Use cached information, if available. */
2356 void
2357 x_query_color (struct frame *f, XColor *color)
2359 x_query_colors (f, color, 1);
2363 /* On frame F, translate the color name to RGB values. Use cached
2364 information, if possible.
2366 Note that there is currently no way to clean old entries out of the
2367 cache. However, it is limited to names in the server's database,
2368 and names we've actually looked up; list-colors-display is probably
2369 the most color-intensive case we're likely to hit. */
2371 Status x_parse_color (struct frame *f, const char *color_name,
2372 XColor *color)
2374 Display *dpy = FRAME_X_DISPLAY (f);
2375 Colormap cmap = FRAME_X_COLORMAP (f);
2376 struct color_name_cache_entry *cache_entry;
2378 if (color_name[0] == '#')
2380 /* The hex form is parsed directly by XParseColor without
2381 talking to the X server. No need for caching. */
2382 return XParseColor (dpy, cmap, color_name, color);
2385 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2386 cache_entry = cache_entry->next)
2388 if (!xstrcasecmp(cache_entry->name, color_name))
2390 *color = cache_entry->rgb;
2391 return 1;
2395 if (XParseColor (dpy, cmap, color_name, color) == 0)
2396 /* No caching of negative results, currently. */
2397 return 0;
2399 cache_entry = xzalloc (sizeof *cache_entry);
2400 cache_entry->rgb = *color;
2401 cache_entry->name = xstrdup (color_name);
2402 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2403 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2404 return 1;
2408 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2409 exact match can't be allocated, try the nearest color available.
2410 Value is true if successful. Set *COLOR to the color
2411 allocated. */
2413 static bool
2414 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2416 bool rc;
2418 rc = XAllocColor (dpy, cmap, color) != 0;
2419 if (rc == 0)
2421 /* If we got to this point, the colormap is full, so we're going
2422 to try to get the next closest color. The algorithm used is
2423 a least-squares matching, which is what X uses for closest
2424 color matching with StaticColor visuals. */
2425 int nearest, i;
2426 int max_color_delta = 255;
2427 int max_delta = 3 * max_color_delta;
2428 int nearest_delta = max_delta + 1;
2429 int ncells;
2430 const XColor *cells = x_color_cells (dpy, &ncells);
2432 for (nearest = i = 0; i < ncells; ++i)
2434 int dred = (color->red >> 8) - (cells[i].red >> 8);
2435 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2436 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2437 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2439 if (delta < nearest_delta)
2441 nearest = i;
2442 nearest_delta = delta;
2446 color->red = cells[nearest].red;
2447 color->green = cells[nearest].green;
2448 color->blue = cells[nearest].blue;
2449 rc = XAllocColor (dpy, cmap, color) != 0;
2451 else
2453 /* If allocation succeeded, and the allocated pixel color is not
2454 equal to a cached pixel color recorded earlier, there was a
2455 change in the colormap, so clear the color cache. */
2456 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2457 eassume (dpyinfo);
2459 if (dpyinfo->color_cells)
2461 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2462 if (cached_color->red != color->red
2463 || cached_color->blue != color->blue
2464 || cached_color->green != color->green)
2466 xfree (dpyinfo->color_cells);
2467 dpyinfo->color_cells = NULL;
2468 dpyinfo->ncolor_cells = 0;
2473 #ifdef DEBUG_X_COLORS
2474 if (rc)
2475 register_color (color->pixel);
2476 #endif /* DEBUG_X_COLORS */
2478 return rc;
2482 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2483 gamma correction. If an exact match can't be allocated, try the
2484 nearest color available. Value is true if successful. Set *COLOR
2485 to the color allocated. */
2487 bool
2488 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2490 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2492 gamma_correct (f, color);
2494 if (dpyinfo->red_bits > 0)
2496 color->pixel = x_make_truecolor_pixel (dpyinfo,
2497 color->red,
2498 color->green,
2499 color->blue);
2500 return true;
2503 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2507 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2508 It's necessary to do this instead of just using PIXEL directly to
2509 get color reference counts right. */
2511 unsigned long
2512 x_copy_color (struct frame *f, unsigned long pixel)
2514 XColor color;
2516 /* If display has an immutable color map, freeing colors is not
2517 necessary and some servers don't allow it. Since we won't free a
2518 color once we've allocated it, we don't need to re-allocate it to
2519 maintain the server's reference count. */
2520 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2521 return pixel;
2523 color.pixel = pixel;
2524 block_input ();
2525 /* The color could still be found in the color_cells array. */
2526 x_query_color (f, &color);
2527 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2528 unblock_input ();
2529 #ifdef DEBUG_X_COLORS
2530 register_color (pixel);
2531 #endif
2532 return color.pixel;
2536 /* Brightness beyond which a color won't have its highlight brightness
2537 boosted.
2539 Nominally, highlight colors for `3d' faces are calculated by
2540 brightening an object's color by a constant scale factor, but this
2541 doesn't yield good results for dark colors, so for colors who's
2542 brightness is less than this value (on a scale of 0-65535) have an
2543 use an additional additive factor.
2545 The value here is set so that the default menu-bar/mode-line color
2546 (grey75) will not have its highlights changed at all. */
2547 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2550 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2551 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2552 If this produces the same color as PIXEL, try a color where all RGB
2553 values have DELTA added. Return the allocated color in *PIXEL.
2554 DISPLAY is the X display, CMAP is the colormap to operate on.
2555 Value is non-zero if successful. */
2557 static bool
2558 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2559 unsigned long *pixel, double factor, int delta)
2561 XColor color, new;
2562 long bright;
2563 bool success_p;
2565 /* Get RGB color values. */
2566 color.pixel = *pixel;
2567 x_query_color (f, &color);
2569 /* Change RGB values by specified FACTOR. Avoid overflow! */
2570 eassert (factor >= 0);
2571 new.red = min (0xffff, factor * color.red);
2572 new.green = min (0xffff, factor * color.green);
2573 new.blue = min (0xffff, factor * color.blue);
2575 /* Calculate brightness of COLOR. */
2576 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2578 /* We only boost colors that are darker than
2579 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2580 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2581 /* Make an additive adjustment to NEW, because it's dark enough so
2582 that scaling by FACTOR alone isn't enough. */
2584 /* How far below the limit this color is (0 - 1, 1 being darker). */
2585 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2586 /* The additive adjustment. */
2587 int min_delta = delta * dimness * factor / 2;
2589 if (factor < 1)
2591 new.red = max (0, new.red - min_delta);
2592 new.green = max (0, new.green - min_delta);
2593 new.blue = max (0, new.blue - min_delta);
2595 else
2597 new.red = min (0xffff, min_delta + new.red);
2598 new.green = min (0xffff, min_delta + new.green);
2599 new.blue = min (0xffff, min_delta + new.blue);
2603 /* Try to allocate the color. */
2604 success_p = x_alloc_nearest_color (f, cmap, &new);
2605 if (success_p)
2607 if (new.pixel == *pixel)
2609 /* If we end up with the same color as before, try adding
2610 delta to the RGB values. */
2611 x_free_colors (f, &new.pixel, 1);
2613 new.red = min (0xffff, delta + color.red);
2614 new.green = min (0xffff, delta + color.green);
2615 new.blue = min (0xffff, delta + color.blue);
2616 success_p = x_alloc_nearest_color (f, cmap, &new);
2618 else
2619 success_p = true;
2620 *pixel = new.pixel;
2623 return success_p;
2627 /* Set up the foreground color for drawing relief lines of glyph
2628 string S. RELIEF is a pointer to a struct relief containing the GC
2629 with which lines will be drawn. Use a color that is FACTOR or
2630 DELTA lighter or darker than the relief's background which is found
2631 in S->f->output_data.x->relief_background. If such a color cannot
2632 be allocated, use DEFAULT_PIXEL, instead. */
2634 static void
2635 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2636 int delta, unsigned long default_pixel)
2638 XGCValues xgcv;
2639 struct x_output *di = f->output_data.x;
2640 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2641 unsigned long pixel;
2642 unsigned long background = di->relief_background;
2643 Colormap cmap = FRAME_X_COLORMAP (f);
2644 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2645 Display *dpy = FRAME_X_DISPLAY (f);
2647 xgcv.graphics_exposures = False;
2648 xgcv.line_width = 1;
2650 /* Free previously allocated color. The color cell will be reused
2651 when it has been freed as many times as it was allocated, so this
2652 doesn't affect faces using the same colors. */
2653 if (relief->gc && relief->pixel != -1)
2655 x_free_colors (f, &relief->pixel, 1);
2656 relief->pixel = -1;
2659 /* Allocate new color. */
2660 xgcv.foreground = default_pixel;
2661 pixel = background;
2662 if (dpyinfo->n_planes != 1
2663 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2664 xgcv.foreground = relief->pixel = pixel;
2666 if (relief->gc == 0)
2668 xgcv.stipple = dpyinfo->gray;
2669 mask |= GCStipple;
2670 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2672 else
2673 XChangeGC (dpy, relief->gc, mask, &xgcv);
2677 /* Set up colors for the relief lines around glyph string S. */
2679 static void
2680 x_setup_relief_colors (struct glyph_string *s)
2682 struct x_output *di = s->f->output_data.x;
2683 unsigned long color;
2685 if (s->face->use_box_color_for_shadows_p)
2686 color = s->face->box_color;
2687 else if (s->first_glyph->type == IMAGE_GLYPH
2688 && s->img->pixmap
2689 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2690 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2691 else
2693 XGCValues xgcv;
2695 /* Get the background color of the face. */
2696 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2697 color = xgcv.background;
2700 if (di->white_relief.gc == 0
2701 || color != di->relief_background)
2703 di->relief_background = color;
2704 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2705 WHITE_PIX_DEFAULT (s->f));
2706 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2707 BLACK_PIX_DEFAULT (s->f));
2712 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2713 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2714 to draw, it must be >= 0. RAISED_P means draw a raised
2715 relief. LEFT_P means draw a relief on the left side of
2716 the rectangle. RIGHT_P means draw a relief on the right
2717 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2718 when drawing. */
2720 static void
2721 x_draw_relief_rect (struct frame *f,
2722 int left_x, int top_y, int right_x, int bottom_y,
2723 int width, bool raised_p, bool top_p, bool bot_p,
2724 bool left_p, bool right_p,
2725 XRectangle *clip_rect)
2727 #ifdef USE_CAIRO
2728 GC top_left_gc, bottom_right_gc;
2729 int corners = 0;
2731 if (raised_p)
2733 top_left_gc = f->output_data.x->white_relief.gc;
2734 bottom_right_gc = f->output_data.x->black_relief.gc;
2736 else
2738 top_left_gc = f->output_data.x->black_relief.gc;
2739 bottom_right_gc = f->output_data.x->white_relief.gc;
2742 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2743 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2745 if (left_p)
2747 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2748 width, bottom_y + 1 - top_y);
2749 if (top_p)
2750 corners |= 1 << CORNER_TOP_LEFT;
2751 if (bot_p)
2752 corners |= 1 << CORNER_BOTTOM_LEFT;
2754 if (right_p)
2756 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2757 width, bottom_y + 1 - top_y);
2758 if (top_p)
2759 corners |= 1 << CORNER_TOP_RIGHT;
2760 if (bot_p)
2761 corners |= 1 << CORNER_BOTTOM_RIGHT;
2763 if (top_p)
2765 if (!right_p)
2766 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2767 right_x + 1 - left_x, width);
2768 else
2769 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2770 right_x + 1 - left_x, width, 1);
2772 if (bot_p)
2774 if (!left_p)
2775 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2776 right_x + 1 - left_x, width);
2777 else
2778 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2779 left_x, bottom_y + 1 - width,
2780 right_x + 1 - left_x, width, 0);
2782 if (left_p && width != 1)
2783 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2784 1, bottom_y + 1 - top_y);
2785 if (top_p && width != 1)
2786 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2787 right_x + 1 - left_x, 1);
2788 if (corners)
2790 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2791 FRAME_BACKGROUND_PIXEL (f));
2792 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2793 right_x - left_x + 1, bottom_y - top_y + 1,
2794 6, 1, corners);
2797 x_reset_clip_rectangles (f, top_left_gc);
2798 x_reset_clip_rectangles (f, bottom_right_gc);
2799 #else
2800 Display *dpy = FRAME_X_DISPLAY (f);
2801 Drawable drawable = FRAME_X_DRAWABLE (f);
2802 int i;
2803 GC gc;
2805 if (raised_p)
2806 gc = f->output_data.x->white_relief.gc;
2807 else
2808 gc = f->output_data.x->black_relief.gc;
2809 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2811 /* This code is more complicated than it has to be, because of two
2812 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2813 the outermost line using the black relief. (ii) Omit the four
2814 corner pixels. */
2816 /* Top. */
2817 if (top_p)
2819 if (width == 1)
2820 XDrawLine (dpy, drawable, gc,
2821 left_x + left_p, top_y,
2822 right_x + !right_p, top_y);
2824 for (i = 1; i < width; ++i)
2825 XDrawLine (dpy, drawable, gc,
2826 left_x + i * left_p, top_y + i,
2827 right_x + 1 - i * right_p, top_y + i);
2830 /* Left. */
2831 if (left_p)
2833 if (width == 1)
2834 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2836 x_clear_area(f, left_x, top_y, 1, 1);
2837 x_clear_area(f, left_x, bottom_y, 1, 1);
2839 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2840 XDrawLine (dpy, drawable, gc,
2841 left_x + i, top_y + (i + 1) * top_p,
2842 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2845 XSetClipMask (dpy, gc, None);
2846 if (raised_p)
2847 gc = f->output_data.x->black_relief.gc;
2848 else
2849 gc = f->output_data.x->white_relief.gc;
2850 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2852 if (width > 1)
2854 /* Outermost top line. */
2855 if (top_p)
2856 XDrawLine (dpy, drawable, gc,
2857 left_x + left_p, top_y,
2858 right_x + !right_p, top_y);
2860 /* Outermost left line. */
2861 if (left_p)
2862 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2865 /* Bottom. */
2866 if (bot_p)
2868 XDrawLine (dpy, drawable, gc,
2869 left_x + left_p, bottom_y,
2870 right_x + !right_p, bottom_y);
2871 for (i = 1; i < width; ++i)
2872 XDrawLine (dpy, drawable, gc,
2873 left_x + i * left_p, bottom_y - i,
2874 right_x + 1 - i * right_p, bottom_y - i);
2877 /* Right. */
2878 if (right_p)
2880 x_clear_area(f, right_x, top_y, 1, 1);
2881 x_clear_area(f, right_x, bottom_y, 1, 1);
2882 for (i = 0; i < width; ++i)
2883 XDrawLine (dpy, drawable, gc,
2884 right_x - i, top_y + (i + 1) * top_p,
2885 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2888 x_reset_clip_rectangles (f, gc);
2890 #endif
2894 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2895 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2896 draw, it must be >= 0. LEFT_P means draw a line on the
2897 left side of the rectangle. RIGHT_P means draw a line
2898 on the right side of the rectangle. CLIP_RECT is the clipping
2899 rectangle to use when drawing. */
2901 static void
2902 x_draw_box_rect (struct glyph_string *s,
2903 int left_x, int top_y, int right_x, int bottom_y, int width,
2904 bool left_p, bool right_p, XRectangle *clip_rect)
2906 XGCValues xgcv;
2908 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2909 XSetForeground (s->display, s->gc, s->face->box_color);
2910 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2912 /* Top. */
2913 x_fill_rectangle (s->f, s->gc,
2914 left_x, top_y, right_x - left_x + 1, width);
2916 /* Left. */
2917 if (left_p)
2918 x_fill_rectangle (s->f, s->gc,
2919 left_x, top_y, width, bottom_y - top_y + 1);
2921 /* Bottom. */
2922 x_fill_rectangle (s->f, s->gc,
2923 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2925 /* Right. */
2926 if (right_p)
2927 x_fill_rectangle (s->f, s->gc,
2928 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2930 XSetForeground (s->display, s->gc, xgcv.foreground);
2931 x_reset_clip_rectangles (s->f, s->gc);
2935 /* Draw a box around glyph string S. */
2937 static void
2938 x_draw_glyph_string_box (struct glyph_string *s)
2940 int width, left_x, right_x, top_y, bottom_y, last_x;
2941 bool raised_p, left_p, right_p;
2942 struct glyph *last_glyph;
2943 XRectangle clip_rect;
2945 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2946 ? WINDOW_RIGHT_EDGE_X (s->w)
2947 : window_box_right (s->w, s->area));
2949 /* The glyph that may have a right box line. */
2950 last_glyph = (s->cmp || s->img
2951 ? s->first_glyph
2952 : s->first_glyph + s->nchars - 1);
2954 width = eabs (s->face->box_line_width);
2955 raised_p = s->face->box == FACE_RAISED_BOX;
2956 left_x = s->x;
2957 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2958 ? last_x - 1
2959 : min (last_x, s->x + s->background_width) - 1);
2960 top_y = s->y;
2961 bottom_y = top_y + s->height - 1;
2963 left_p = (s->first_glyph->left_box_line_p
2964 || (s->hl == DRAW_MOUSE_FACE
2965 && (s->prev == NULL
2966 || s->prev->hl != s->hl)));
2967 right_p = (last_glyph->right_box_line_p
2968 || (s->hl == DRAW_MOUSE_FACE
2969 && (s->next == NULL
2970 || s->next->hl != s->hl)));
2972 get_glyph_string_clip_rect (s, &clip_rect);
2974 if (s->face->box == FACE_SIMPLE_BOX)
2975 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2976 left_p, right_p, &clip_rect);
2977 else
2979 x_setup_relief_colors (s);
2980 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2981 width, raised_p, true, true, left_p, right_p,
2982 &clip_rect);
2987 /* Draw foreground of image glyph string S. */
2989 static void
2990 x_draw_image_foreground (struct glyph_string *s)
2992 int x = s->x;
2993 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2995 /* If first glyph of S has a left box line, start drawing it to the
2996 right of that line. */
2997 if (s->face->box != FACE_NO_BOX
2998 && s->first_glyph->left_box_line_p
2999 && s->slice.x == 0)
3000 x += eabs (s->face->box_line_width);
3002 /* If there is a margin around the image, adjust x- and y-position
3003 by that margin. */
3004 if (s->slice.x == 0)
3005 x += s->img->hmargin;
3006 if (s->slice.y == 0)
3007 y += s->img->vmargin;
3009 if (s->img->pixmap)
3011 if (s->img->mask)
3013 /* We can't set both a clip mask and use XSetClipRectangles
3014 because the latter also sets a clip mask. We also can't
3015 trust on the shape extension to be available
3016 (XShapeCombineRegion). So, compute the rectangle to draw
3017 manually. */
3018 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3019 | GCFunction);
3020 XGCValues xgcv;
3021 XRectangle clip_rect, image_rect, r;
3023 xgcv.clip_mask = s->img->mask;
3024 xgcv.clip_x_origin = x;
3025 xgcv.clip_y_origin = y;
3026 xgcv.function = GXcopy;
3027 XChangeGC (s->display, s->gc, mask, &xgcv);
3029 get_glyph_string_clip_rect (s, &clip_rect);
3030 image_rect.x = x;
3031 image_rect.y = y;
3032 image_rect.width = s->slice.width;
3033 image_rect.height = s->slice.height;
3034 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3035 XCopyArea (s->display, s->img->pixmap,
3036 FRAME_X_DRAWABLE (s->f), s->gc,
3037 s->slice.x + r.x - x, s->slice.y + r.y - y,
3038 r.width, r.height, r.x, r.y);
3040 else
3042 XRectangle clip_rect, image_rect, r;
3044 get_glyph_string_clip_rect (s, &clip_rect);
3045 image_rect.x = x;
3046 image_rect.y = y;
3047 image_rect.width = s->slice.width;
3048 image_rect.height = s->slice.height;
3049 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3050 XCopyArea (s->display, s->img->pixmap,
3051 FRAME_X_DRAWABLE (s->f), s->gc,
3052 s->slice.x + r.x - x, s->slice.y + r.y - y,
3053 r.width, r.height, r.x, r.y);
3055 /* When the image has a mask, we can expect that at
3056 least part of a mouse highlight or a block cursor will
3057 be visible. If the image doesn't have a mask, make
3058 a block cursor visible by drawing a rectangle around
3059 the image. I believe it's looking better if we do
3060 nothing here for mouse-face. */
3061 if (s->hl == DRAW_CURSOR)
3063 int relief = eabs (s->img->relief);
3064 x_draw_rectangle (s->f, s->gc,
3065 x - relief, y - relief,
3066 s->slice.width + relief*2 - 1,
3067 s->slice.height + relief*2 - 1);
3071 else
3072 /* Draw a rectangle if image could not be loaded. */
3073 x_draw_rectangle (s->f, s->gc, x, y,
3074 s->slice.width - 1, s->slice.height - 1);
3078 /* Draw a relief around the image glyph string S. */
3080 static void
3081 x_draw_image_relief (struct glyph_string *s)
3083 int x1, y1, thick;
3084 bool raised_p, top_p, bot_p, left_p, right_p;
3085 int extra_x, extra_y;
3086 XRectangle r;
3087 int x = s->x;
3088 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3090 /* If first glyph of S has a left box line, start drawing it to the
3091 right of that line. */
3092 if (s->face->box != FACE_NO_BOX
3093 && s->first_glyph->left_box_line_p
3094 && s->slice.x == 0)
3095 x += eabs (s->face->box_line_width);
3097 /* If there is a margin around the image, adjust x- and y-position
3098 by that margin. */
3099 if (s->slice.x == 0)
3100 x += s->img->hmargin;
3101 if (s->slice.y == 0)
3102 y += s->img->vmargin;
3104 if (s->hl == DRAW_IMAGE_SUNKEN
3105 || s->hl == DRAW_IMAGE_RAISED)
3107 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3108 raised_p = s->hl == DRAW_IMAGE_RAISED;
3110 else
3112 thick = eabs (s->img->relief);
3113 raised_p = s->img->relief > 0;
3116 x1 = x + s->slice.width - 1;
3117 y1 = y + s->slice.height - 1;
3119 extra_x = extra_y = 0;
3120 if (s->face->id == TOOL_BAR_FACE_ID)
3122 if (CONSP (Vtool_bar_button_margin)
3123 && INTEGERP (XCAR (Vtool_bar_button_margin))
3124 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3126 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3127 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3129 else if (INTEGERP (Vtool_bar_button_margin))
3130 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3133 top_p = bot_p = left_p = right_p = false;
3135 if (s->slice.x == 0)
3136 x -= thick + extra_x, left_p = true;
3137 if (s->slice.y == 0)
3138 y -= thick + extra_y, top_p = true;
3139 if (s->slice.x + s->slice.width == s->img->width)
3140 x1 += thick + extra_x, right_p = true;
3141 if (s->slice.y + s->slice.height == s->img->height)
3142 y1 += thick + extra_y, bot_p = true;
3144 x_setup_relief_colors (s);
3145 get_glyph_string_clip_rect (s, &r);
3146 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3147 top_p, bot_p, left_p, right_p, &r);
3151 /* Draw the foreground of image glyph string S to PIXMAP. */
3153 static void
3154 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3156 int x = 0;
3157 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3159 /* If first glyph of S has a left box line, start drawing it to the
3160 right of that line. */
3161 if (s->face->box != FACE_NO_BOX
3162 && s->first_glyph->left_box_line_p
3163 && s->slice.x == 0)
3164 x += eabs (s->face->box_line_width);
3166 /* If there is a margin around the image, adjust x- and y-position
3167 by that margin. */
3168 if (s->slice.x == 0)
3169 x += s->img->hmargin;
3170 if (s->slice.y == 0)
3171 y += s->img->vmargin;
3173 if (s->img->pixmap)
3175 if (s->img->mask)
3177 /* We can't set both a clip mask and use XSetClipRectangles
3178 because the latter also sets a clip mask. We also can't
3179 trust on the shape extension to be available
3180 (XShapeCombineRegion). So, compute the rectangle to draw
3181 manually. */
3182 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3183 | GCFunction);
3184 XGCValues xgcv;
3186 xgcv.clip_mask = s->img->mask;
3187 xgcv.clip_x_origin = x - s->slice.x;
3188 xgcv.clip_y_origin = y - s->slice.y;
3189 xgcv.function = GXcopy;
3190 XChangeGC (s->display, s->gc, mask, &xgcv);
3192 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3193 s->slice.x, s->slice.y,
3194 s->slice.width, s->slice.height, x, y);
3195 XSetClipMask (s->display, s->gc, None);
3197 else
3199 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3200 s->slice.x, s->slice.y,
3201 s->slice.width, s->slice.height, x, y);
3203 /* When the image has a mask, we can expect that at
3204 least part of a mouse highlight or a block cursor will
3205 be visible. If the image doesn't have a mask, make
3206 a block cursor visible by drawing a rectangle around
3207 the image. I believe it's looking better if we do
3208 nothing here for mouse-face. */
3209 if (s->hl == DRAW_CURSOR)
3211 int r = eabs (s->img->relief);
3212 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3213 s->slice.width + r*2 - 1,
3214 s->slice.height + r*2 - 1);
3218 else
3219 /* Draw a rectangle if image could not be loaded. */
3220 x_draw_rectangle (s->f, s->gc, x, y,
3221 s->slice.width - 1, s->slice.height - 1);
3225 /* Draw part of the background of glyph string S. X, Y, W, and H
3226 give the rectangle to draw. */
3228 static void
3229 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3231 if (s->stippled_p)
3233 /* Fill background with a stipple pattern. */
3234 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3235 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3236 XSetFillStyle (s->display, s->gc, FillSolid);
3238 else
3239 x_clear_glyph_string_rect (s, x, y, w, h);
3243 /* Draw image glyph string S.
3245 s->y
3246 s->x +-------------------------
3247 | s->face->box
3249 | +-------------------------
3250 | | s->img->margin
3252 | | +-------------------
3253 | | | the image
3257 static void
3258 x_draw_image_glyph_string (struct glyph_string *s)
3260 int box_line_hwidth = eabs (s->face->box_line_width);
3261 int box_line_vwidth = max (s->face->box_line_width, 0);
3262 int height;
3263 Pixmap pixmap = None;
3265 height = s->height;
3266 if (s->slice.y == 0)
3267 height -= box_line_vwidth;
3268 if (s->slice.y + s->slice.height >= s->img->height)
3269 height -= box_line_vwidth;
3271 /* Fill background with face under the image. Do it only if row is
3272 taller than image or if image has a clip mask to reduce
3273 flickering. */
3274 s->stippled_p = s->face->stipple != 0;
3275 if (height > s->slice.height
3276 || s->img->hmargin
3277 || s->img->vmargin
3278 || s->img->mask
3279 || s->img->pixmap == 0
3280 || s->width != s->background_width)
3282 if (s->img->mask)
3284 /* Create a pixmap as large as the glyph string. Fill it
3285 with the background color. Copy the image to it, using
3286 its mask. Copy the temporary pixmap to the display. */
3287 Screen *screen = FRAME_X_SCREEN (s->f);
3288 int depth = DefaultDepthOfScreen (screen);
3290 /* Create a pixmap as large as the glyph string. */
3291 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3292 s->background_width,
3293 s->height, depth);
3295 /* Don't clip in the following because we're working on the
3296 pixmap. */
3297 XSetClipMask (s->display, s->gc, None);
3299 /* Fill the pixmap with the background color/stipple. */
3300 if (s->stippled_p)
3302 /* Fill background with a stipple pattern. */
3303 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3304 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3305 XFillRectangle (s->display, pixmap, s->gc,
3306 0, 0, s->background_width, s->height);
3307 XSetFillStyle (s->display, s->gc, FillSolid);
3308 XSetTSOrigin (s->display, s->gc, 0, 0);
3310 else
3312 XGCValues xgcv;
3313 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3314 &xgcv);
3315 XSetForeground (s->display, s->gc, xgcv.background);
3316 XFillRectangle (s->display, pixmap, s->gc,
3317 0, 0, s->background_width, s->height);
3318 XSetForeground (s->display, s->gc, xgcv.foreground);
3321 else
3323 int x = s->x;
3324 int y = s->y;
3325 int width = s->background_width;
3327 if (s->first_glyph->left_box_line_p
3328 && s->slice.x == 0)
3330 x += box_line_hwidth;
3331 width -= box_line_hwidth;
3334 if (s->slice.y == 0)
3335 y += box_line_vwidth;
3337 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3340 s->background_filled_p = true;
3343 /* Draw the foreground. */
3344 #ifdef USE_CAIRO
3345 if (s->img->cr_data)
3347 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3349 int x = s->x + s->img->hmargin;
3350 int y = s->y + s->img->vmargin;
3351 int width = s->background_width;
3353 cairo_set_source_surface (cr, s->img->cr_data,
3354 x - s->slice.x,
3355 y - s->slice.y);
3356 cairo_rectangle (cr, x, y, width, height);
3357 cairo_fill (cr);
3358 x_end_cr_clip (s->f);
3360 else
3361 #endif
3362 if (pixmap != None)
3364 x_draw_image_foreground_1 (s, pixmap);
3365 x_set_glyph_string_clipping (s);
3366 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3367 0, 0, s->background_width, s->height, s->x, s->y);
3368 XFreePixmap (s->display, pixmap);
3370 else
3371 x_draw_image_foreground (s);
3373 /* If we must draw a relief around the image, do it. */
3374 if (s->img->relief
3375 || s->hl == DRAW_IMAGE_RAISED
3376 || s->hl == DRAW_IMAGE_SUNKEN)
3377 x_draw_image_relief (s);
3381 /* Draw stretch glyph string S. */
3383 static void
3384 x_draw_stretch_glyph_string (struct glyph_string *s)
3386 eassert (s->first_glyph->type == STRETCH_GLYPH);
3388 if (s->hl == DRAW_CURSOR
3389 && !x_stretch_cursor_p)
3391 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3392 wide as the stretch glyph. */
3393 int width, background_width = s->background_width;
3394 int x = s->x;
3396 if (!s->row->reversed_p)
3398 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3400 if (x < left_x)
3402 background_width -= left_x - x;
3403 x = left_x;
3406 else
3408 /* In R2L rows, draw the cursor on the right edge of the
3409 stretch glyph. */
3410 int right_x = window_box_right (s->w, TEXT_AREA);
3412 if (x + background_width > right_x)
3413 background_width -= x - right_x;
3414 x += background_width;
3416 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3417 if (s->row->reversed_p)
3418 x -= width;
3420 /* Draw cursor. */
3421 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3423 /* Clear rest using the GC of the original non-cursor face. */
3424 if (width < background_width)
3426 int y = s->y;
3427 int w = background_width - width, h = s->height;
3428 XRectangle r;
3429 GC gc;
3431 if (!s->row->reversed_p)
3432 x += width;
3433 else
3434 x = s->x;
3435 if (s->row->mouse_face_p
3436 && cursor_in_mouse_face_p (s->w))
3438 x_set_mouse_face_gc (s);
3439 gc = s->gc;
3441 else
3442 gc = s->face->gc;
3444 get_glyph_string_clip_rect (s, &r);
3445 x_set_clip_rectangles (s->f, gc, &r, 1);
3447 if (s->face->stipple)
3449 /* Fill background with a stipple pattern. */
3450 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3451 x_fill_rectangle (s->f, gc, x, y, w, h);
3452 XSetFillStyle (s->display, gc, FillSolid);
3454 else
3456 XGCValues xgcv;
3457 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3458 XSetForeground (s->display, gc, xgcv.background);
3459 x_fill_rectangle (s->f, gc, x, y, w, h);
3460 XSetForeground (s->display, gc, xgcv.foreground);
3463 x_reset_clip_rectangles (s->f, gc);
3466 else if (!s->background_filled_p)
3468 int background_width = s->background_width;
3469 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3471 /* Don't draw into left margin, fringe or scrollbar area
3472 except for header line and mode line. */
3473 if (x < left_x && !s->row->mode_line_p)
3475 background_width -= left_x - x;
3476 x = left_x;
3478 if (background_width > 0)
3479 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3482 s->background_filled_p = true;
3485 static void
3486 x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
3488 const int base_res = 96;
3489 struct x_display_info * dpyinfo = x_display_info_for_display (disp);
3491 *scale_x = *scale_y = 1;
3493 if (dpyinfo)
3495 if (dpyinfo->resx > base_res)
3496 *scale_x = floor (dpyinfo->resx / base_res);
3497 if (dpyinfo->resy > base_res)
3498 *scale_y = floor (dpyinfo->resy / base_res);
3503 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3505 x0 wave_length = 2
3507 y0 * * * * *
3508 |* * * * * * * * *
3509 wave_height = 3 | * * * *
3512 static void
3513 x_draw_underwave (struct glyph_string *s)
3515 /* Adjust for scale/HiDPI. */
3516 int scale_x, scale_y;
3518 x_get_scale_factor (s->display, &scale_x, &scale_y);
3520 int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
3522 #ifdef USE_CAIRO
3523 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3524 s->width, wave_height, wave_length);
3525 #else /* not USE_CAIRO */
3526 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
3527 bool odd;
3528 XRectangle wave_clip, string_clip, final_clip;
3530 dx = wave_length;
3531 dy = wave_height - 1;
3532 x0 = s->x;
3533 y0 = s->ybase + wave_height / 2 - scale_y;
3534 width = s->width;
3535 xmax = x0 + width;
3537 /* Find and set clipping rectangle */
3539 wave_clip.x = x0;
3540 wave_clip.y = y0;
3541 wave_clip.width = width;
3542 wave_clip.height = wave_height;
3543 get_glyph_string_clip_rect (s, &string_clip);
3545 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3546 return;
3548 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3550 /* Draw the waves */
3552 x1 = x0 - (x0 % dx);
3553 x2 = x1 + dx;
3554 odd = (x1 / dx) & 1;
3555 y1 = y2 = y0;
3557 if (odd)
3558 y1 += dy;
3559 else
3560 y2 += dy;
3562 if (INT_MAX - dx < xmax)
3563 emacs_abort ();
3565 while (x1 <= xmax)
3567 XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt,
3568 JoinRound);
3569 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3570 x1 = x2, y1 = y2;
3571 x2 += dx, y2 = y0 + odd*dy;
3572 odd = !odd;
3575 /* Restore previous clipping rectangle(s) */
3576 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3577 #endif /* not USE_CAIRO */
3581 /* Draw glyph string S. */
3583 static void
3584 x_draw_glyph_string (struct glyph_string *s)
3586 bool relief_drawn_p = false;
3588 /* If S draws into the background of its successors, draw the
3589 background of the successors first so that S can draw into it.
3590 This makes S->next use XDrawString instead of XDrawImageString. */
3591 if (s->next && s->right_overhang && !s->for_overlaps)
3593 int width;
3594 struct glyph_string *next;
3596 for (width = 0, next = s->next;
3597 next && width < s->right_overhang;
3598 width += next->width, next = next->next)
3599 if (next->first_glyph->type != IMAGE_GLYPH)
3601 x_set_glyph_string_gc (next);
3602 x_set_glyph_string_clipping (next);
3603 if (next->first_glyph->type == STRETCH_GLYPH)
3604 x_draw_stretch_glyph_string (next);
3605 else
3606 x_draw_glyph_string_background (next, true);
3607 next->num_clips = 0;
3611 /* Set up S->gc, set clipping and draw S. */
3612 x_set_glyph_string_gc (s);
3614 /* Draw relief (if any) in advance for char/composition so that the
3615 glyph string can be drawn over it. */
3616 if (!s->for_overlaps
3617 && s->face->box != FACE_NO_BOX
3618 && (s->first_glyph->type == CHAR_GLYPH
3619 || s->first_glyph->type == COMPOSITE_GLYPH))
3622 x_set_glyph_string_clipping (s);
3623 x_draw_glyph_string_background (s, true);
3624 x_draw_glyph_string_box (s);
3625 x_set_glyph_string_clipping (s);
3626 relief_drawn_p = true;
3628 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3629 && !s->clip_tail
3630 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3631 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3632 /* We must clip just this glyph. left_overhang part has already
3633 drawn when s->prev was drawn, and right_overhang part will be
3634 drawn later when s->next is drawn. */
3635 x_set_glyph_string_clipping_exactly (s, s);
3636 else
3637 x_set_glyph_string_clipping (s);
3639 switch (s->first_glyph->type)
3641 case IMAGE_GLYPH:
3642 x_draw_image_glyph_string (s);
3643 break;
3645 case XWIDGET_GLYPH:
3646 x_draw_xwidget_glyph_string (s);
3647 break;
3649 case STRETCH_GLYPH:
3650 x_draw_stretch_glyph_string (s);
3651 break;
3653 case CHAR_GLYPH:
3654 if (s->for_overlaps)
3655 s->background_filled_p = true;
3656 else
3657 x_draw_glyph_string_background (s, false);
3658 x_draw_glyph_string_foreground (s);
3659 break;
3661 case COMPOSITE_GLYPH:
3662 if (s->for_overlaps || (s->cmp_from > 0
3663 && ! s->first_glyph->u.cmp.automatic))
3664 s->background_filled_p = true;
3665 else
3666 x_draw_glyph_string_background (s, true);
3667 x_draw_composite_glyph_string_foreground (s);
3668 break;
3670 case GLYPHLESS_GLYPH:
3671 if (s->for_overlaps)
3672 s->background_filled_p = true;
3673 else
3674 x_draw_glyph_string_background (s, true);
3675 x_draw_glyphless_glyph_string_foreground (s);
3676 break;
3678 default:
3679 emacs_abort ();
3682 if (!s->for_overlaps)
3684 /* Draw underline. */
3685 if (s->face->underline_p)
3687 if (s->face->underline_type == FACE_UNDER_WAVE)
3689 if (s->face->underline_defaulted_p)
3690 x_draw_underwave (s);
3691 else
3693 XGCValues xgcv;
3694 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3695 XSetForeground (s->display, s->gc, s->face->underline_color);
3696 x_draw_underwave (s);
3697 XSetForeground (s->display, s->gc, xgcv.foreground);
3700 else if (s->face->underline_type == FACE_UNDER_LINE)
3702 unsigned long thickness, position;
3703 int y;
3705 if (s->prev && s->prev->face->underline_p
3706 && s->prev->face->underline_type == FACE_UNDER_LINE)
3708 /* We use the same underline style as the previous one. */
3709 thickness = s->prev->underline_thickness;
3710 position = s->prev->underline_position;
3712 else
3714 struct font *font = font_for_underline_metrics (s);
3716 /* Get the underline thickness. Default is 1 pixel. */
3717 if (font && font->underline_thickness > 0)
3718 thickness = font->underline_thickness;
3719 else
3720 thickness = 1;
3721 if (x_underline_at_descent_line)
3722 position = (s->height - thickness) - (s->ybase - s->y);
3723 else
3725 /* Get the underline position. This is the recommended
3726 vertical offset in pixels from the baseline to the top of
3727 the underline. This is a signed value according to the
3728 specs, and its default is
3730 ROUND ((maximum descent) / 2), with
3731 ROUND(x) = floor (x + 0.5) */
3733 if (x_use_underline_position_properties
3734 && font && font->underline_position >= 0)
3735 position = font->underline_position;
3736 else if (font)
3737 position = (font->descent + 1) / 2;
3738 else
3739 position = underline_minimum_offset;
3741 position = max (position, underline_minimum_offset);
3743 /* Check the sanity of thickness and position. We should
3744 avoid drawing underline out of the current line area. */
3745 if (s->y + s->height <= s->ybase + position)
3746 position = (s->height - 1) - (s->ybase - s->y);
3747 if (s->y + s->height < s->ybase + position + thickness)
3748 thickness = (s->y + s->height) - (s->ybase + position);
3749 s->underline_thickness = thickness;
3750 s->underline_position = position;
3751 y = s->ybase + position;
3752 if (s->face->underline_defaulted_p)
3753 x_fill_rectangle (s->f, s->gc,
3754 s->x, y, s->width, thickness);
3755 else
3757 XGCValues xgcv;
3758 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3759 XSetForeground (s->display, s->gc, s->face->underline_color);
3760 x_fill_rectangle (s->f, s->gc,
3761 s->x, y, s->width, thickness);
3762 XSetForeground (s->display, s->gc, xgcv.foreground);
3766 /* Draw overline. */
3767 if (s->face->overline_p)
3769 unsigned long dy = 0, h = 1;
3771 if (s->face->overline_color_defaulted_p)
3772 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3773 s->width, h);
3774 else
3776 XGCValues xgcv;
3777 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3778 XSetForeground (s->display, s->gc, s->face->overline_color);
3779 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3780 s->width, h);
3781 XSetForeground (s->display, s->gc, xgcv.foreground);
3785 /* Draw strike-through. */
3786 if (s->face->strike_through_p)
3788 /* Y-coordinate and height of the glyph string's first
3789 glyph. We cannot use s->y and s->height because those
3790 could be larger if there are taller display elements
3791 (e.g., characters displayed with a larger font) in the
3792 same glyph row. */
3793 int glyph_y = s->ybase - s->first_glyph->ascent;
3794 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3795 /* Strike-through width and offset from the glyph string's
3796 top edge. */
3797 unsigned long h = 1;
3798 unsigned long dy = (glyph_height - h) / 2;
3800 if (s->face->strike_through_color_defaulted_p)
3801 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3802 s->width, h);
3803 else
3805 XGCValues xgcv;
3806 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3807 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3808 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3809 s->width, h);
3810 XSetForeground (s->display, s->gc, xgcv.foreground);
3814 /* Draw relief if not yet drawn. */
3815 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3816 x_draw_glyph_string_box (s);
3818 if (s->prev)
3820 struct glyph_string *prev;
3822 for (prev = s->prev; prev; prev = prev->prev)
3823 if (prev->hl != s->hl
3824 && prev->x + prev->width + prev->right_overhang > s->x)
3826 /* As prev was drawn while clipped to its own area, we
3827 must draw the right_overhang part using s->hl now. */
3828 enum draw_glyphs_face save = prev->hl;
3830 prev->hl = s->hl;
3831 x_set_glyph_string_gc (prev);
3832 x_set_glyph_string_clipping_exactly (s, prev);
3833 if (prev->first_glyph->type == CHAR_GLYPH)
3834 x_draw_glyph_string_foreground (prev);
3835 else
3836 x_draw_composite_glyph_string_foreground (prev);
3837 x_reset_clip_rectangles (prev->f, prev->gc);
3838 prev->hl = save;
3839 prev->num_clips = 0;
3843 if (s->next)
3845 struct glyph_string *next;
3847 for (next = s->next; next; next = next->next)
3848 if (next->hl != s->hl
3849 && next->x - next->left_overhang < s->x + s->width)
3851 /* As next will be drawn while clipped to its own area,
3852 we must draw the left_overhang part using s->hl now. */
3853 enum draw_glyphs_face save = next->hl;
3855 next->hl = s->hl;
3856 x_set_glyph_string_gc (next);
3857 x_set_glyph_string_clipping_exactly (s, next);
3858 if (next->first_glyph->type == CHAR_GLYPH)
3859 x_draw_glyph_string_foreground (next);
3860 else
3861 x_draw_composite_glyph_string_foreground (next);
3862 x_reset_clip_rectangles (next->f, next->gc);
3863 next->hl = save;
3864 next->num_clips = 0;
3865 next->clip_head = s->next;
3870 /* Reset clipping. */
3871 x_reset_clip_rectangles (s->f, s->gc);
3872 s->num_clips = 0;
3875 /* Shift display to make room for inserted glyphs. */
3877 static void
3878 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3880 /* Never called on a GUI frame, see
3881 https://lists.gnu.org/r/emacs-devel/2015-05/msg00456.html
3883 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3884 f->output_data.x->normal_gc,
3885 x, y, width, height,
3886 x + shift_by, y);
3889 /* Delete N glyphs at the nominal cursor position. Not implemented
3890 for X frames. */
3892 static void
3893 x_delete_glyphs (struct frame *f, register int n)
3895 emacs_abort ();
3899 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3900 If they are <= 0, this is probably an error. */
3902 static ATTRIBUTE_UNUSED void
3903 x_clear_area1 (Display *dpy, Window window,
3904 int x, int y, int width, int height, int exposures)
3906 eassert (width > 0 && height > 0);
3907 XClearArea (dpy, window, x, y, width, height, exposures);
3910 void
3911 x_clear_area (struct frame *f, int x, int y, int width, int height)
3913 #ifdef USE_CAIRO
3914 cairo_t *cr;
3916 eassert (width > 0 && height > 0);
3918 cr = x_begin_cr_clip (f, NULL);
3919 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3920 cairo_rectangle (cr, x, y, width, height);
3921 cairo_fill (cr);
3922 x_end_cr_clip (f);
3923 #else
3924 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3925 XFillRectangle (FRAME_X_DISPLAY (f),
3926 FRAME_X_DRAWABLE (f),
3927 f->output_data.x->reverse_gc,
3928 x, y, width, height);
3929 else
3930 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3931 x, y, width, height, False);
3932 #endif
3936 /* Clear an entire frame. */
3938 static void
3939 x_clear_frame (struct frame *f)
3941 /* Clearing the frame will erase any cursor, so mark them all as no
3942 longer visible. */
3943 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3945 block_input ();
3947 font_drop_xrender_surfaces (f);
3948 x_clear_window (f);
3950 /* We have to clear the scroll bars. If we have changed colors or
3951 something like that, then they should be notified. */
3952 x_scroll_bar_clear (f);
3954 XFlush (FRAME_X_DISPLAY (f));
3956 unblock_input ();
3959 /* RIF: Show hourglass cursor on frame F. */
3961 static void
3962 x_show_hourglass (struct frame *f)
3964 Display *dpy = FRAME_X_DISPLAY (f);
3966 if (dpy)
3968 struct x_output *x = FRAME_X_OUTPUT (f);
3969 #ifdef USE_X_TOOLKIT
3970 if (x->widget)
3971 #else
3972 if (FRAME_OUTER_WINDOW (f))
3973 #endif
3975 x->hourglass_p = true;
3977 if (!x->hourglass_window)
3979 unsigned long mask = CWCursor;
3980 XSetWindowAttributes attrs;
3981 #ifdef USE_GTK
3982 Window parent = FRAME_X_WINDOW (f);
3983 #else
3984 Window parent = FRAME_OUTER_WINDOW (f);
3985 #endif
3986 attrs.cursor = x->hourglass_cursor;
3988 x->hourglass_window = XCreateWindow
3989 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3990 InputOnly, CopyFromParent, mask, &attrs);
3993 XMapRaised (dpy, x->hourglass_window);
3994 XFlush (dpy);
3999 /* RIF: Cancel hourglass cursor on frame F. */
4001 static void
4002 x_hide_hourglass (struct frame *f)
4004 struct x_output *x = FRAME_X_OUTPUT (f);
4006 /* Watch out for newly created frames. */
4007 if (x->hourglass_window)
4009 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
4010 /* Sync here because XTread_socket looks at the
4011 hourglass_p flag that is reset to zero below. */
4012 XSync (FRAME_X_DISPLAY (f), False);
4013 x->hourglass_p = false;
4017 /* Invert the middle quarter of the frame for .15 sec. */
4019 static void
4020 XTflash (struct frame *f)
4022 block_input ();
4025 #ifdef USE_GTK
4026 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
4027 when the scroll bars and the edit widget share the same X window. */
4028 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4029 #ifdef HAVE_GTK3
4030 #if GTK_CHECK_VERSION (3, 22, 0)
4031 cairo_region_t *region = gdk_window_get_visible_region (window);
4032 GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
4033 cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
4034 #else
4035 cairo_t *cr = gdk_cairo_create (window);
4036 #endif
4037 cairo_set_source_rgb (cr, 1, 1, 1);
4038 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4039 #define XFillRectangle(d, win, gc, x, y, w, h) \
4040 do { \
4041 cairo_rectangle (cr, x, y, w, h); \
4042 cairo_fill (cr); \
4044 while (false)
4045 #else /* ! HAVE_GTK3 */
4046 GdkGCValues vals;
4047 GdkGC *gc;
4048 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4049 ^ FRAME_BACKGROUND_PIXEL (f));
4050 vals.function = GDK_XOR;
4051 gc = gdk_gc_new_with_values (window,
4052 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4053 #define XFillRectangle(d, win, gc, x, y, w, h) \
4054 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4055 #endif /* ! HAVE_GTK3 */
4056 #else /* ! USE_GTK */
4057 GC gc;
4059 /* Create a GC that will use the GXxor function to flip foreground
4060 pixels into background pixels. */
4062 XGCValues values;
4064 values.function = GXxor;
4065 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
4066 ^ FRAME_BACKGROUND_PIXEL (f));
4068 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4069 GCFunction | GCForeground, &values);
4071 #endif
4073 /* Get the height not including a menu bar widget. */
4074 int height = FRAME_PIXEL_HEIGHT (f);
4075 /* Height of each line to flash. */
4076 int flash_height = FRAME_LINE_HEIGHT (f);
4077 /* These will be the left and right margins of the rectangles. */
4078 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4079 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4080 int width = flash_right - flash_left;
4082 /* If window is tall, flash top and bottom line. */
4083 if (height > 3 * FRAME_LINE_HEIGHT (f))
4085 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4086 flash_left,
4087 (FRAME_INTERNAL_BORDER_WIDTH (f)
4088 + FRAME_TOP_MARGIN_HEIGHT (f)),
4089 width, flash_height);
4090 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4091 flash_left,
4092 (height - flash_height
4093 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4094 width, flash_height);
4097 else
4098 /* If it is short, flash it all. */
4099 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4100 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4101 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4103 x_flush (f);
4106 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4107 struct timespec wakeup = timespec_add (current_timespec (), delay);
4109 /* Keep waiting until past the time wakeup or any input gets
4110 available. */
4111 while (! detect_input_pending ())
4113 struct timespec current = current_timespec ();
4114 struct timespec timeout;
4116 /* Break if result would not be positive. */
4117 if (timespec_cmp (wakeup, current) <= 0)
4118 break;
4120 /* How long `select' should wait. */
4121 timeout = make_timespec (0, 10 * 1000 * 1000);
4123 /* Try to wait that long--but we might wake up sooner. */
4124 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4128 /* If window is tall, flash top and bottom line. */
4129 if (height > 3 * FRAME_LINE_HEIGHT (f))
4131 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4132 flash_left,
4133 (FRAME_INTERNAL_BORDER_WIDTH (f)
4134 + FRAME_TOP_MARGIN_HEIGHT (f)),
4135 width, flash_height);
4136 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4137 flash_left,
4138 (height - flash_height
4139 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4140 width, flash_height);
4142 else
4143 /* If it is short, flash it all. */
4144 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4145 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4146 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4148 #ifdef USE_GTK
4149 #ifdef HAVE_GTK3
4150 #if GTK_CHECK_VERSION (3, 22, 0)
4151 gdk_window_end_draw_frame (window, context);
4152 cairo_region_destroy (region);
4153 #else
4154 cairo_destroy (cr);
4155 #endif
4156 #else
4157 g_object_unref (G_OBJECT (gc));
4158 #endif
4159 #undef XFillRectangle
4160 #else
4161 XFreeGC (FRAME_X_DISPLAY (f), gc);
4162 #endif
4163 x_flush (f);
4167 unblock_input ();
4171 static void
4172 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4174 block_input ();
4175 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4176 unblock_input ();
4180 /* Make audible bell. */
4182 static void
4183 XTring_bell (struct frame *f)
4185 if (FRAME_X_DISPLAY (f))
4187 if (visible_bell)
4188 XTflash (f);
4189 else
4191 block_input ();
4192 #ifdef HAVE_XKB
4193 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4194 #else
4195 XBell (FRAME_X_DISPLAY (f), 0);
4196 #endif
4197 XFlush (FRAME_X_DISPLAY (f));
4198 unblock_input ();
4203 /***********************************************************************
4204 Line Dance
4205 ***********************************************************************/
4207 /* Perform an insert-lines or delete-lines operation, inserting N
4208 lines or deleting -N lines at vertical position VPOS. */
4210 static void
4211 x_ins_del_lines (struct frame *f, int vpos, int n)
4213 emacs_abort ();
4217 /* Scroll part of the display as described by RUN. */
4219 static void
4220 x_scroll_run (struct window *w, struct run *run)
4222 struct frame *f = XFRAME (w->frame);
4223 int x, y, width, height, from_y, to_y, bottom_y;
4225 /* Get frame-relative bounding box of the text display area of W,
4226 without mode lines. Include in this box the left and right
4227 fringe of W. */
4228 window_box (w, ANY_AREA, &x, &y, &width, &height);
4230 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4231 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4232 bottom_y = y + height;
4234 if (to_y < from_y)
4236 /* Scrolling up. Make sure we don't copy part of the mode
4237 line at the bottom. */
4238 if (from_y + run->height > bottom_y)
4239 height = bottom_y - from_y;
4240 else
4241 height = run->height;
4243 else
4245 /* Scrolling down. Make sure we don't copy over the mode line.
4246 at the bottom. */
4247 if (to_y + run->height > bottom_y)
4248 height = bottom_y - to_y;
4249 else
4250 height = run->height;
4253 block_input ();
4255 /* Cursor off. Will be switched on again in x_update_window_end. */
4256 x_clear_cursor (w);
4258 #ifdef USE_CAIRO
4259 SET_FRAME_GARBAGED (f);
4260 #else
4261 XCopyArea (FRAME_X_DISPLAY (f),
4262 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4263 f->output_data.x->normal_gc,
4264 x, from_y,
4265 width, height,
4266 x, to_y);
4267 #endif
4269 unblock_input ();
4274 /***********************************************************************
4275 Exposure Events
4276 ***********************************************************************/
4279 static void
4280 frame_highlight (struct frame *f)
4282 /* We used to only do this if Vx_no_window_manager was non-nil, but
4283 the ICCCM (section 4.1.6) says that the window's border pixmap
4284 and border pixel are window attributes which are "private to the
4285 client", so we can always change it to whatever we want. */
4286 block_input ();
4287 /* I recently started to get errors in this XSetWindowBorder, depending on
4288 the window-manager in use, tho something more is at play since I've been
4289 using that same window-manager binary for ever. Let's not crash just
4290 because of this (bug#9310). */
4291 x_catch_errors (FRAME_X_DISPLAY (f));
4292 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4293 f->output_data.x->border_pixel);
4294 x_uncatch_errors ();
4295 unblock_input ();
4296 x_update_cursor (f, true);
4297 x_set_frame_alpha (f);
4300 static void
4301 frame_unhighlight (struct frame *f)
4303 /* We used to only do this if Vx_no_window_manager was non-nil, but
4304 the ICCCM (section 4.1.6) says that the window's border pixmap
4305 and border pixel are window attributes which are "private to the
4306 client", so we can always change it to whatever we want. */
4307 block_input ();
4308 /* Same as above for XSetWindowBorder (bug#9310). */
4309 x_catch_errors (FRAME_X_DISPLAY (f));
4310 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4311 f->output_data.x->border_tile);
4312 x_uncatch_errors ();
4313 unblock_input ();
4314 x_update_cursor (f, true);
4315 x_set_frame_alpha (f);
4318 /* The focus has changed. Update the frames as necessary to reflect
4319 the new situation. Note that we can't change the selected frame
4320 here, because the Lisp code we are interrupting might become confused.
4321 Each event gets marked with the frame in which it occurred, so the
4322 Lisp code can tell when the switch took place by examining the events. */
4324 static void
4325 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4327 struct frame *old_focus = dpyinfo->x_focus_frame;
4329 if (frame != dpyinfo->x_focus_frame)
4331 /* Set this before calling other routines, so that they see
4332 the correct value of x_focus_frame. */
4333 dpyinfo->x_focus_frame = frame;
4335 if (old_focus && old_focus->auto_lower)
4336 x_lower_frame (old_focus);
4338 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4339 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4340 else
4341 dpyinfo->x_pending_autoraise_frame = NULL;
4344 x_frame_rehighlight (dpyinfo);
4347 /* Handle FocusIn and FocusOut state changes for FRAME.
4348 If FRAME has focus and there exists more than one frame, puts
4349 a FOCUS_IN_EVENT into *BUFP. */
4351 static void
4352 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4354 if (type == FocusIn)
4356 if (dpyinfo->x_focus_event_frame != frame)
4358 x_new_focus_frame (dpyinfo, frame);
4359 dpyinfo->x_focus_event_frame = frame;
4361 /* Don't stop displaying the initial startup message
4362 for a switch-frame event we don't need. */
4363 /* When run as a daemon, Vterminal_frame is always NIL. */
4364 bufp->arg = (((NILP (Vterminal_frame)
4365 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4366 || EQ (Fdaemonp (), Qt))
4367 && CONSP (Vframe_list)
4368 && !NILP (XCDR (Vframe_list)))
4369 ? Qt : Qnil);
4370 bufp->kind = FOCUS_IN_EVENT;
4371 XSETFRAME (bufp->frame_or_window, frame);
4374 frame->output_data.x->focus_state |= state;
4376 #ifdef HAVE_X_I18N
4377 if (FRAME_XIC (frame))
4378 XSetICFocus (FRAME_XIC (frame));
4379 #endif
4381 else if (type == FocusOut)
4383 frame->output_data.x->focus_state &= ~state;
4385 if (dpyinfo->x_focus_event_frame == frame)
4387 dpyinfo->x_focus_event_frame = 0;
4388 x_new_focus_frame (dpyinfo, 0);
4390 bufp->kind = FOCUS_OUT_EVENT;
4391 XSETFRAME (bufp->frame_or_window, frame);
4394 #ifdef HAVE_X_I18N
4395 if (FRAME_XIC (frame))
4396 XUnsetICFocus (FRAME_XIC (frame));
4397 #endif
4398 if (frame->pointer_invisible)
4399 XTtoggle_invisible_pointer (frame, false);
4403 /* Return the Emacs frame-object corresponding to an X window.
4404 It could be the frame's main window or an icon window. */
4406 static struct frame *
4407 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4409 Lisp_Object tail, frame;
4410 struct frame *f;
4412 if (wdesc == None)
4413 return NULL;
4415 FOR_EACH_FRAME (tail, frame)
4417 f = XFRAME (frame);
4418 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4419 continue;
4420 if (f->output_data.x->hourglass_window == wdesc)
4421 return f;
4422 #ifdef USE_X_TOOLKIT
4423 if ((f->output_data.x->edit_widget
4424 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4425 /* A tooltip frame? */
4426 || (!f->output_data.x->edit_widget
4427 && FRAME_X_WINDOW (f) == wdesc)
4428 || f->output_data.x->icon_desc == wdesc)
4429 return f;
4430 #else /* not USE_X_TOOLKIT */
4431 #ifdef USE_GTK
4432 if (f->output_data.x->edit_widget)
4434 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4435 struct x_output *x = f->output_data.x;
4436 if (gwdesc != 0 && gwdesc == x->edit_widget)
4437 return f;
4439 #endif /* USE_GTK */
4440 if (FRAME_X_WINDOW (f) == wdesc
4441 || f->output_data.x->icon_desc == wdesc)
4442 return f;
4443 #endif /* not USE_X_TOOLKIT */
4445 return 0;
4448 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4450 /* Like x_window_to_frame but also compares the window with the widget's
4451 windows. */
4453 static struct frame *
4454 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4456 Lisp_Object tail, frame;
4457 struct frame *f, *found = NULL;
4458 struct x_output *x;
4460 if (wdesc == None)
4461 return NULL;
4463 FOR_EACH_FRAME (tail, frame)
4465 if (found)
4466 break;
4467 f = XFRAME (frame);
4468 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4470 /* This frame matches if the window is any of its widgets. */
4471 x = f->output_data.x;
4472 if (x->hourglass_window == wdesc)
4473 found = f;
4474 else if (x->widget)
4476 #ifdef USE_GTK
4477 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4478 if (gwdesc != 0
4479 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4480 found = f;
4481 #else
4482 if (wdesc == XtWindow (x->widget)
4483 || wdesc == XtWindow (x->column_widget)
4484 || wdesc == XtWindow (x->edit_widget))
4485 found = f;
4486 /* Match if the window is this frame's menubar. */
4487 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4488 found = f;
4489 #endif
4491 else if (FRAME_X_WINDOW (f) == wdesc)
4492 /* A tooltip frame. */
4493 found = f;
4497 return found;
4500 /* Likewise, but consider only the menu bar widget. */
4502 static struct frame *
4503 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4504 const XEvent *event)
4506 Window wdesc = event->xany.window;
4507 Lisp_Object tail, frame;
4508 struct frame *f;
4509 struct x_output *x;
4511 if (wdesc == None)
4512 return NULL;
4514 FOR_EACH_FRAME (tail, frame)
4516 f = XFRAME (frame);
4517 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4518 continue;
4519 x = f->output_data.x;
4520 #ifdef USE_GTK
4521 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4522 return f;
4523 #else
4524 /* Match if the window is this frame's menubar. */
4525 if (x->menubar_widget
4526 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4527 return f;
4528 #endif
4530 return 0;
4533 /* Return the frame whose principal (outermost) window is WDESC.
4534 If WDESC is some other (smaller) window, we return 0. */
4536 struct frame *
4537 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4539 Lisp_Object tail, frame;
4540 struct frame *f;
4541 struct x_output *x;
4543 if (wdesc == None)
4544 return NULL;
4546 FOR_EACH_FRAME (tail, frame)
4548 f = XFRAME (frame);
4549 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4550 continue;
4551 x = f->output_data.x;
4553 if (x->widget)
4555 /* This frame matches if the window is its topmost widget. */
4556 #ifdef USE_GTK
4557 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4558 if (gwdesc == x->widget)
4559 return f;
4560 #else
4561 if (wdesc == XtWindow (x->widget))
4562 return f;
4563 #endif
4565 else if (FRAME_X_WINDOW (f) == wdesc)
4566 /* Tooltip frame. */
4567 return f;
4569 return 0;
4572 #else /* !USE_X_TOOLKIT && !USE_GTK */
4574 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4575 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4577 #endif /* USE_X_TOOLKIT || USE_GTK */
4579 /* The focus may have changed. Figure out if it is a real focus change,
4580 by checking both FocusIn/Out and Enter/LeaveNotify events.
4582 Returns FOCUS_IN_EVENT event in *BUFP. */
4584 static void
4585 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4586 const XEvent *event, struct input_event *bufp)
4588 if (!frame)
4589 return;
4591 switch (event->type)
4593 case EnterNotify:
4594 case LeaveNotify:
4596 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4597 int focus_state
4598 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4600 if (event->xcrossing.detail != NotifyInferior
4601 && event->xcrossing.focus
4602 && ! (focus_state & FOCUS_EXPLICIT))
4603 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4604 FOCUS_IMPLICIT,
4605 dpyinfo, frame, bufp);
4607 break;
4609 case FocusIn:
4610 case FocusOut:
4611 x_focus_changed (event->type,
4612 (event->xfocus.detail == NotifyPointer ?
4613 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4614 dpyinfo, frame, bufp);
4615 break;
4617 case ClientMessage:
4618 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4620 enum xembed_message msg = event->xclient.data.l[1];
4621 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4622 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4624 break;
4629 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4630 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4632 void
4633 x_mouse_leave (struct x_display_info *dpyinfo)
4635 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4637 #endif
4639 /* The focus has changed, or we have redirected a frame's focus to
4640 another frame (this happens when a frame uses a surrogate
4641 mini-buffer frame). Shift the highlight as appropriate.
4643 The FRAME argument doesn't necessarily have anything to do with which
4644 frame is being highlighted or un-highlighted; we only use it to find
4645 the appropriate X display info. */
4647 static void
4648 XTframe_rehighlight (struct frame *frame)
4650 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4653 static void
4654 x_frame_rehighlight (struct x_display_info *dpyinfo)
4656 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4658 if (dpyinfo->x_focus_frame)
4660 dpyinfo->x_highlight_frame
4661 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4662 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4663 : dpyinfo->x_focus_frame);
4664 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4666 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4667 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4670 else
4671 dpyinfo->x_highlight_frame = 0;
4673 if (dpyinfo->x_highlight_frame != old_highlight)
4675 if (old_highlight)
4676 frame_unhighlight (old_highlight);
4677 if (dpyinfo->x_highlight_frame)
4678 frame_highlight (dpyinfo->x_highlight_frame);
4684 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4686 /* Initialize mode_switch_bit and modifier_meaning. */
4687 static void
4688 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4690 int min_code, max_code;
4691 KeySym *syms;
4692 int syms_per_code;
4693 XModifierKeymap *mods;
4695 dpyinfo->meta_mod_mask = 0;
4696 dpyinfo->shift_lock_mask = 0;
4697 dpyinfo->alt_mod_mask = 0;
4698 dpyinfo->super_mod_mask = 0;
4699 dpyinfo->hyper_mod_mask = 0;
4701 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4703 syms = XGetKeyboardMapping (dpyinfo->display,
4704 min_code, max_code - min_code + 1,
4705 &syms_per_code);
4706 mods = XGetModifierMapping (dpyinfo->display);
4708 /* Scan the modifier table to see which modifier bits the Meta and
4709 Alt keysyms are on. */
4711 int row, col; /* The row and column in the modifier table. */
4712 bool found_alt_or_meta;
4714 for (row = 3; row < 8; row++)
4716 found_alt_or_meta = false;
4717 for (col = 0; col < mods->max_keypermod; col++)
4719 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4721 /* Zeroes are used for filler. Skip them. */
4722 if (code == 0)
4723 continue;
4725 /* Are any of this keycode's keysyms a meta key? */
4727 int code_col;
4729 for (code_col = 0; code_col < syms_per_code; code_col++)
4731 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4733 switch (sym)
4735 case XK_Meta_L:
4736 case XK_Meta_R:
4737 found_alt_or_meta = true;
4738 dpyinfo->meta_mod_mask |= (1 << row);
4739 break;
4741 case XK_Alt_L:
4742 case XK_Alt_R:
4743 found_alt_or_meta = true;
4744 dpyinfo->alt_mod_mask |= (1 << row);
4745 break;
4747 case XK_Hyper_L:
4748 case XK_Hyper_R:
4749 if (!found_alt_or_meta)
4750 dpyinfo->hyper_mod_mask |= (1 << row);
4751 code_col = syms_per_code;
4752 col = mods->max_keypermod;
4753 break;