Revert part of the previous change
[emacs.git] / src / xterm.c
blob3f956d950d87392b630c5276fa23b9d751dded3e
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 FRAME_CR_SURFACE (f) =
364 cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
365 FRAME_PIXEL_WIDTH (f),
366 FRAME_PIXEL_HEIGHT (f));
368 cr = cairo_create (FRAME_CR_SURFACE (f));
369 FRAME_CR_CONTEXT (f) = cr;
371 cairo_save (cr);
373 if (gc)
375 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
377 if (gc_ext && gc_ext->n_clip_rects)
379 int i;
381 for (i = 0; i < gc_ext->n_clip_rects; i++)
382 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
383 gc_ext->clip_rects[i].y,
384 gc_ext->clip_rects[i].width,
385 gc_ext->clip_rects[i].height);
386 cairo_clip (cr);
390 return cr;
393 void
394 x_end_cr_clip (struct frame *f)
396 cairo_restore (FRAME_CR_CONTEXT (f));
399 void
400 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
402 XGCValues xgcv;
403 XColor color;
405 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
406 color.pixel = xgcv.foreground;
407 x_query_color (f, &color);
408 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
409 color.green / 65535.0, color.blue / 65535.0);
412 void
413 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
415 XGCValues xgcv;
416 XColor color;
418 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
419 color.pixel = xgcv.background;
420 x_query_color (f, &color);
421 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
422 color.green / 65535.0, color.blue / 65535.0);
425 /* Fringe bitmaps. */
427 static int max_fringe_bmp = 0;
428 static cairo_pattern_t **fringe_bmp = 0;
430 static void
431 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
433 int i, stride;
434 cairo_surface_t *surface;
435 unsigned char *data;
436 cairo_pattern_t *pattern;
438 if (which >= max_fringe_bmp)
440 i = max_fringe_bmp;
441 max_fringe_bmp = which + 20;
442 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
443 while (i < max_fringe_bmp)
444 fringe_bmp[i++] = 0;
447 block_input ();
449 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
450 stride = cairo_image_surface_get_stride (surface);
451 data = cairo_image_surface_get_data (surface);
453 for (i = 0; i < h; i++)
455 *((unsigned short *) data) = bits[i];
456 data += stride;
459 cairo_surface_mark_dirty (surface);
460 pattern = cairo_pattern_create_for_surface (surface);
461 cairo_surface_destroy (surface);
463 unblock_input ();
465 fringe_bmp[which] = pattern;
468 static void
469 x_cr_destroy_fringe_bitmap (int which)
471 if (which >= max_fringe_bmp)
472 return;
474 if (fringe_bmp[which])
476 block_input ();
477 cairo_pattern_destroy (fringe_bmp[which]);
478 unblock_input ();
480 fringe_bmp[which] = 0;
483 static void
484 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
485 int src_x, int src_y, int width, int height,
486 int dest_x, int dest_y, bool overlay_p)
488 cairo_t *cr;
489 cairo_matrix_t matrix;
490 cairo_surface_t *surface;
491 cairo_format_t format;
493 cr = x_begin_cr_clip (f, gc);
494 if (overlay_p)
495 cairo_rectangle (cr, dest_x, dest_y, width, height);
496 else
498 x_set_cr_source_with_gc_background (f, gc);
499 cairo_rectangle (cr, dest_x, dest_y, width, height);
500 cairo_fill_preserve (cr);
502 cairo_clip (cr);
503 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
504 cairo_pattern_set_matrix (image, &matrix);
505 cairo_pattern_get_surface (image, &surface);
506 format = cairo_image_surface_get_format (surface);
507 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
509 cairo_set_source (cr, image);
510 cairo_fill (cr);
512 else
514 x_set_cr_source_with_gc_foreground (f, gc);
515 cairo_mask (cr, image);
517 x_end_cr_clip (f);
520 void
521 x_cr_draw_frame (cairo_t *cr, struct frame *f)
523 int width, height;
525 width = FRAME_PIXEL_WIDTH (f);
526 height = FRAME_PIXEL_HEIGHT (f);
528 x_free_cr_resources (f);
529 FRAME_CR_CONTEXT (f) = cr;
530 x_clear_area (f, 0, 0, width, height);
531 expose_frame (f, 0, 0, width, height);
532 FRAME_CR_CONTEXT (f) = NULL;
535 static cairo_status_t
536 x_cr_accumulate_data (void *closure, const unsigned char *data,
537 unsigned int length)
539 Lisp_Object *acc = (Lisp_Object *) closure;
541 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
543 return CAIRO_STATUS_SUCCESS;
546 static void
547 x_cr_destroy (Lisp_Object arg)
549 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
551 block_input ();
552 cairo_destroy (cr);
553 unblock_input ();
556 Lisp_Object
557 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
559 struct frame *f;
560 cairo_surface_t *surface;
561 cairo_t *cr;
562 int width, height;
563 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
564 Lisp_Object acc = Qnil;
565 ptrdiff_t count = SPECPDL_INDEX ();
567 specbind (Qredisplay_dont_pause, Qt);
568 redisplay_preserve_echo_area (31);
570 f = XFRAME (XCAR (frames));
571 frames = XCDR (frames);
572 width = FRAME_PIXEL_WIDTH (f);
573 height = FRAME_PIXEL_HEIGHT (f);
575 block_input ();
576 #ifdef CAIRO_HAS_PDF_SURFACE
577 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
579 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
580 width, height);
581 surface_set_size_func = cairo_pdf_surface_set_size;
583 else
584 #endif
585 #ifdef CAIRO_HAS_PNG_FUNCTIONS
586 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
587 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
588 else
589 #endif
590 #ifdef CAIRO_HAS_PS_SURFACE
591 if (surface_type == CAIRO_SURFACE_TYPE_PS)
593 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
594 width, height);
595 surface_set_size_func = cairo_ps_surface_set_size;
597 else
598 #endif
599 #ifdef CAIRO_HAS_SVG_SURFACE
600 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
601 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
602 width, height);
603 else
604 #endif
605 abort ();
607 cr = cairo_create (surface);
608 cairo_surface_destroy (surface);
609 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
611 while (1)
613 x_free_cr_resources (f);
614 FRAME_CR_CONTEXT (f) = cr;
615 x_clear_area (f, 0, 0, width, height);
616 expose_frame (f, 0, 0, width, height);
617 FRAME_CR_CONTEXT (f) = NULL;
619 if (NILP (frames))
620 break;
622 cairo_surface_show_page (surface);
623 f = XFRAME (XCAR (frames));
624 frames = XCDR (frames);
625 width = FRAME_PIXEL_WIDTH (f);
626 height = FRAME_PIXEL_HEIGHT (f);
627 if (surface_set_size_func)
628 (*surface_set_size_func) (surface, width, height);
630 unblock_input ();
631 maybe_quit ();
632 block_input ();
635 #ifdef CAIRO_HAS_PNG_FUNCTIONS
636 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
638 cairo_surface_flush (surface);
639 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
641 #endif
642 unblock_input ();
644 unbind_to (count, Qnil);
646 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
649 #endif /* USE_CAIRO */
651 static void
652 x_free_cr_resources (struct frame *f)
654 #ifdef USE_CAIRO
655 if (f == NULL)
657 Lisp_Object rest, frame;
658 FOR_EACH_FRAME (rest, frame)
659 if (FRAME_X_P (XFRAME (frame)))
660 x_free_cr_resources (XFRAME (frame));
662 else
664 cairo_t *cr = FRAME_CR_CONTEXT (f);
666 if (cr)
668 cairo_surface_t *surface = cairo_get_target (cr);
670 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
672 cairo_destroy (cr);
673 FRAME_CR_CONTEXT (f) = NULL;
677 #endif
680 static void
681 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
683 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
684 #ifdef USE_CAIRO
685 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
688 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
690 gc_ext->n_clip_rects = n;
691 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
693 #endif
696 static void
697 x_reset_clip_rectangles (struct frame *f, GC gc)
699 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
700 #ifdef USE_CAIRO
702 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
704 if (gc_ext)
705 gc_ext->n_clip_rects = 0;
707 #endif
710 static void
711 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
713 #ifdef USE_CAIRO
714 cairo_t *cr;
716 cr = x_begin_cr_clip (f, gc);
717 x_set_cr_source_with_gc_foreground (f, gc);
718 cairo_rectangle (cr, x, y, width, height);
719 cairo_fill (cr);
720 x_end_cr_clip (f);
721 #else
722 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
723 gc, x, y, width, height);
724 #endif
727 static void
728 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
730 #ifdef USE_CAIRO
731 cairo_t *cr;
733 cr = x_begin_cr_clip (f, gc);
734 x_set_cr_source_with_gc_foreground (f, gc);
735 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
736 cairo_set_line_width (cr, 1);
737 cairo_stroke (cr);
738 x_end_cr_clip (f);
739 #else
740 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
741 gc, x, y, width, height);
742 #endif
745 static void
746 x_clear_window (struct frame *f)
748 #ifdef USE_CAIRO
749 cairo_t *cr;
751 cr = x_begin_cr_clip (f, NULL);
752 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
753 cairo_paint (cr);
754 x_end_cr_clip (f);
755 #else
756 if (FRAME_X_DOUBLE_BUFFERED_P (f))
757 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
758 else
759 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
760 #endif
763 #ifdef USE_CAIRO
764 static void
765 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
766 int width, int height, int top_p)
768 cairo_t *cr;
770 cr = x_begin_cr_clip (f, gc);
771 x_set_cr_source_with_gc_foreground (f, gc);
772 cairo_move_to (cr, top_p ? x : x + height, y);
773 cairo_line_to (cr, x, y + height);
774 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
775 cairo_line_to (cr, x + width, y);
776 cairo_fill (cr);
777 x_end_cr_clip (f);
780 enum corners
782 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
783 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
784 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
785 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
786 CORNER_LAST
789 static void
790 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
791 int width, int height,
792 double radius, double margin, int corners)
794 cairo_t *cr;
795 int i;
797 cr = x_begin_cr_clip (f, gc);
798 x_set_cr_source_with_gc_background (f, gc);
799 for (i = 0; i < CORNER_LAST; i++)
800 if (corners & (1 << i))
802 double xm, ym, xc, yc;
804 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
805 xm = x - margin, xc = xm + radius;
806 else
807 xm = x + width + margin, xc = xm - radius;
808 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
809 ym = y - margin, yc = ym + radius;
810 else
811 ym = y + height + margin, yc = ym - radius;
813 cairo_move_to (cr, xm, ym);
814 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
816 cairo_clip (cr);
817 cairo_rectangle (cr, x, y, width, height);
818 cairo_fill (cr);
819 x_end_cr_clip (f);
822 static void
823 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
824 int width, int height, int wave_length)
826 cairo_t *cr;
827 double dx = wave_length, dy = height - 1;
828 int xoffset, n;
830 cr = x_begin_cr_clip (f, gc);
831 x_set_cr_source_with_gc_foreground (f, gc);
832 cairo_rectangle (cr, x, y, width, height);
833 cairo_clip (cr);
835 if (x >= 0)
837 xoffset = x % (wave_length * 2);
838 if (xoffset == 0)
839 xoffset = wave_length * 2;
841 else
842 xoffset = x % (wave_length * 2) + wave_length * 2;
843 n = (width + xoffset) / wave_length + 1;
844 if (xoffset > wave_length)
846 xoffset -= wave_length;
847 --n;
848 y += height - 1;
849 dy = -dy;
852 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
853 while (--n >= 0)
855 cairo_rel_line_to (cr, dx, dy);
856 dy = -dy;
858 cairo_set_line_width (cr, 1);
859 cairo_stroke (cr);
860 x_end_cr_clip (f);
862 #endif
865 /* Return the struct x_display_info corresponding to DPY. */
867 struct x_display_info *
868 x_display_info_for_display (Display *dpy)
870 struct x_display_info *dpyinfo;
872 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
873 if (dpyinfo->display == dpy)
874 return dpyinfo;
876 return 0;
879 static Window
880 x_find_topmost_parent (struct frame *f)
882 struct x_output *x = f->output_data.x;
883 Window win = None, wi = x->parent_desc;
884 Display *dpy = FRAME_X_DISPLAY (f);
886 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
888 Window root;
889 Window *children;
890 unsigned int nchildren;
892 win = wi;
893 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
894 XFree (children);
895 else
896 break;
899 return win;
902 #define OPAQUE 0xffffffff
904 void
905 x_set_frame_alpha (struct frame *f)
907 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
908 Display *dpy = FRAME_X_DISPLAY (f);
909 Window win = FRAME_OUTER_WINDOW (f);
910 double alpha = 1.0;
911 double alpha_min = 1.0;
912 unsigned long opac;
913 Window parent;
915 if (dpyinfo->x_highlight_frame == f)
916 alpha = f->alpha[0];
917 else
918 alpha = f->alpha[1];
920 if (FLOATP (Vframe_alpha_lower_limit))
921 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
922 else if (INTEGERP (Vframe_alpha_lower_limit))
923 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
925 if (alpha < 0.0)
926 return;
927 else if (alpha > 1.0)
928 alpha = 1.0;
929 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
930 alpha = alpha_min;
932 opac = alpha * OPAQUE;
934 x_catch_errors (dpy);
936 /* If there is a parent from the window manager, put the property there
937 also, to work around broken window managers that fail to do that.
938 Do this unconditionally as this function is called on reparent when
939 alpha has not changed on the frame. */
941 if (!FRAME_PARENT_FRAME (f))
943 parent = x_find_topmost_parent (f);
944 if (parent != None)
945 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
946 XA_CARDINAL, 32, PropModeReplace,
947 (unsigned char *) &opac, 1);
950 /* return unless necessary */
952 unsigned char *data;
953 Atom actual;
954 int rc, format;
955 unsigned long n, left;
957 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
958 0, 1, False, XA_CARDINAL,
959 &actual, &format, &n, &left,
960 &data);
962 if (rc == Success && actual != None)
964 unsigned long value = *(unsigned long *)data;
965 XFree (data);
966 if (value == opac)
968 x_uncatch_errors ();
969 return;
974 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
975 XA_CARDINAL, 32, PropModeReplace,
976 (unsigned char *) &opac, 1);
977 x_uncatch_errors ();
980 /***********************************************************************
981 Starting and ending an update
982 ***********************************************************************/
984 /* Start an update of frame F. This function is installed as a hook
985 for update_begin, i.e. it is called when update_begin is called.
986 This function is called prior to calls to x_update_window_begin for
987 each window being updated. Currently, there is nothing to do here
988 because all interesting stuff is done on a window basis. */
990 static void
991 x_update_begin (struct frame *f)
993 #ifdef USE_CAIRO
994 if (FRAME_TOOLTIP_P (f) && !FRAME_VISIBLE_P (f))
995 return;
997 if (! FRAME_CR_SURFACE (f))
999 int width, height;
1000 #ifdef USE_GTK
1001 if (FRAME_GTK_WIDGET (f))
1003 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1004 width = gdk_window_get_width (w);
1005 height = gdk_window_get_height (w);
1007 else
1008 #endif
1010 width = FRAME_PIXEL_WIDTH (f);
1011 height = FRAME_PIXEL_HEIGHT (f);
1012 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1013 height += FRAME_TOOL_BAR_HEIGHT (f);
1014 if (! FRAME_EXTERNAL_MENU_BAR (f))
1015 height += FRAME_MENU_BAR_HEIGHT (f);
1018 if (width > 0 && height > 0)
1020 block_input();
1021 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1022 (CAIRO_FORMAT_ARGB32, width, height);
1023 unblock_input();
1026 #endif /* USE_CAIRO */
1029 /* Start update of window W. */
1031 static void
1032 x_update_window_begin (struct window *w)
1034 struct frame *f = XFRAME (WINDOW_FRAME (w));
1035 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1037 w->output_cursor = w->cursor;
1039 block_input ();
1041 if (f == hlinfo->mouse_face_mouse_frame)
1043 /* Don't do highlighting for mouse motion during the update. */
1044 hlinfo->mouse_face_defer = true;
1046 /* If F needs to be redrawn, simply forget about any prior mouse
1047 highlighting. */
1048 if (FRAME_GARBAGED_P (f))
1049 hlinfo->mouse_face_window = Qnil;
1052 unblock_input ();
1056 /* Draw a vertical window border from (x,y0) to (x,y1) */
1058 static void
1059 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1061 struct frame *f = XFRAME (WINDOW_FRAME (w));
1062 struct face *face;
1064 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1065 if (face)
1066 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1067 face->foreground);
1069 #ifdef USE_CAIRO
1070 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1071 #else
1072 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1073 f->output_data.x->normal_gc, x, y0, x, y1);
1074 #endif
1077 /* Draw a window divider from (x0,y0) to (x1,y1) */
1079 static void
1080 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1082 struct frame *f = XFRAME (WINDOW_FRAME (w));
1083 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1084 struct face *face_first
1085 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1086 struct face *face_last
1087 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1088 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1089 unsigned long color_first = (face_first
1090 ? face_first->foreground
1091 : FRAME_FOREGROUND_PIXEL (f));
1092 unsigned long color_last = (face_last
1093 ? face_last->foreground
1094 : FRAME_FOREGROUND_PIXEL (f));
1095 Display *display = FRAME_X_DISPLAY (f);
1097 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
1098 /* A vertical divider, at least three pixels wide: Draw first and
1099 last pixels differently. */
1101 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1102 x_fill_rectangle (f, f->output_data.x->normal_gc,
1103 x0, y0, 1, y1 - y0);
1104 XSetForeground (display, f->output_data.x->normal_gc, color);
1105 x_fill_rectangle (f, f->output_data.x->normal_gc,
1106 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1107 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1108 x_fill_rectangle (f, f->output_data.x->normal_gc,
1109 x1 - 1, y0, 1, y1 - y0);
1111 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
1112 /* A horizontal divider, at least three pixels high: Draw first and
1113 last pixels differently. */
1115 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1116 x_fill_rectangle (f, f->output_data.x->normal_gc,
1117 x0, y0, x1 - x0, 1);
1118 XSetForeground (display, f->output_data.x->normal_gc, color);
1119 x_fill_rectangle (f, f->output_data.x->normal_gc,
1120 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1121 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1122 x_fill_rectangle (f, f->output_data.x->normal_gc,
1123 x0, y1 - 1, x1 - x0, 1);
1125 else
1127 /* In any other case do not draw the first and last pixels
1128 differently. */
1129 XSetForeground (display, f->output_data.x->normal_gc, color);
1130 x_fill_rectangle (f, f->output_data.x->normal_gc,
1131 x0, y0, x1 - x0, y1 - y0);
1135 /* End update of window W.
1137 Draw vertical borders between horizontally adjacent windows, and
1138 display W's cursor if CURSOR_ON_P is non-zero.
1140 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1141 glyphs in mouse-face were overwritten. In that case we have to
1142 make sure that the mouse-highlight is properly redrawn.
1144 W may be a menu bar pseudo-window in case we don't have X toolkit
1145 support. Such windows don't have a cursor, so don't display it
1146 here. */
1148 static void
1149 x_update_window_end (struct window *w, bool cursor_on_p,
1150 bool mouse_face_overwritten_p)
1152 if (!w->pseudo_window_p)
1154 block_input ();
1156 if (cursor_on_p)
1157 display_and_set_cursor (w, true,
1158 w->output_cursor.hpos, w->output_cursor.vpos,
1159 w->output_cursor.x, w->output_cursor.y);
1161 if (draw_window_fringes (w, true))
1163 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1164 x_draw_right_divider (w);
1165 else
1166 x_draw_vertical_border (w);
1169 unblock_input ();
1172 /* If a row with mouse-face was overwritten, arrange for
1173 XTframe_up_to_date to redisplay the mouse highlight. */
1174 if (mouse_face_overwritten_p)
1176 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1178 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1179 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1180 hlinfo->mouse_face_window = Qnil;
1184 /* Show the frame back buffer. If frame is double-buffered,
1185 atomically publish to the user's screen graphics updates made since
1186 the last call to show_back_buffer. */
1187 static void
1188 show_back_buffer (struct frame *f)
1190 block_input ();
1191 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1193 #ifdef HAVE_XDBE
1194 XdbeSwapInfo swap_info;
1195 memset (&swap_info, 0, sizeof (swap_info));
1196 swap_info.swap_window = FRAME_X_WINDOW (f);
1197 swap_info.swap_action = XdbeCopied;
1198 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1199 #else
1200 eassert (!"should have back-buffer only with XDBE");
1201 #endif
1203 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1204 unblock_input ();
1207 /* Updates back buffer and flushes changes to display. Called from
1208 minibuf read code. Note that we display the back buffer even if
1209 buffer flipping is blocked. */
1210 static void
1211 x_flip_and_flush (struct frame *f)
1213 block_input ();
1214 if (FRAME_X_NEED_BUFFER_FLIP (f))
1215 show_back_buffer (f);
1216 x_flush (f);
1217 unblock_input ();
1220 /* End update of frame F. This function is installed as a hook in
1221 update_end. */
1223 static void
1224 x_update_end (struct frame *f)
1226 /* Mouse highlight may be displayed again. */
1227 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1229 #ifdef USE_CAIRO
1230 if (FRAME_CR_SURFACE (f))
1232 cairo_t *cr;
1233 cairo_surface_t *surface;
1234 int width, height;
1236 block_input ();
1237 width = FRAME_PIXEL_WIDTH (f);
1238 height = FRAME_PIXEL_HEIGHT (f);
1239 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1240 height += FRAME_TOOL_BAR_HEIGHT (f);
1241 if (! FRAME_EXTERNAL_MENU_BAR (f))
1242 height += FRAME_MENU_BAR_HEIGHT (f);
1243 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1244 FRAME_X_DRAWABLE (f),
1245 FRAME_DISPLAY_INFO (f)->visual,
1246 width,
1247 height);
1248 cr = cairo_create (surface);
1249 cairo_surface_destroy (surface);
1251 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1252 cairo_paint (cr);
1253 cairo_destroy (cr);
1254 unblock_input ();
1256 #endif
1258 #ifndef XFlush
1259 block_input ();
1260 XFlush (FRAME_X_DISPLAY (f));
1261 unblock_input ();
1262 #endif
1265 /* This function is called from various places in xdisp.c
1266 whenever a complete update has been performed. */
1268 static void
1269 XTframe_up_to_date (struct frame *f)
1271 eassert (FRAME_X_P (f));
1272 block_input ();
1273 FRAME_MOUSE_UPDATE (f);
1274 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1275 show_back_buffer (f);
1276 unblock_input ();
1279 static void
1280 XTbuffer_flipping_unblocked_hook (struct frame *f)
1282 if (FRAME_X_NEED_BUFFER_FLIP (f))
1283 show_back_buffer (f);
1287 * x_clear_under_internal_border:
1289 * Clear area of frame F's internal border. If the internal border face
1290 * of F has been specified (is not null), fill the area with that face.
1292 void
1293 x_clear_under_internal_border (struct frame *f)
1295 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1297 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1298 int width = FRAME_PIXEL_WIDTH (f);
1299 int height = FRAME_PIXEL_HEIGHT (f);
1300 #ifdef USE_GTK
1301 int margin = 0;
1302 #else
1303 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1304 #endif
1305 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1307 block_input ();
1309 if (face)
1311 unsigned long color = face->background;
1312 Display *display = FRAME_X_DISPLAY (f);
1313 GC gc = f->output_data.x->normal_gc;
1315 XSetForeground (display, gc, color);
1316 x_fill_rectangle (f, gc, 0, margin, width, border);
1317 x_fill_rectangle (f, gc, 0, 0, border, height);
1318 x_fill_rectangle (f, gc, width - border, 0, border, height);
1319 x_fill_rectangle (f, gc, 0, height - border, width, border);
1320 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1322 else
1324 x_clear_area (f, 0, 0, border, height);
1325 x_clear_area (f, 0, margin, width, border);
1326 x_clear_area (f, width - border, 0, border, height);
1327 x_clear_area (f, 0, height - border, width, border);
1330 unblock_input ();
1334 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1335 arrow bitmaps, or clear the fringes if no bitmaps are required
1336 before DESIRED_ROW is made current. This function is called from
1337 update_window_line only if it is known that there are differences
1338 between bitmaps to be drawn between current row and DESIRED_ROW. */
1340 static void
1341 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1343 eassert (w);
1345 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1346 desired_row->redraw_fringe_bitmaps_p = true;
1348 #ifdef USE_X_TOOLKIT
1349 /* When a window has disappeared, make sure that no rest of
1350 full-width rows stays visible in the internal border. Could
1351 check here if updated window is the leftmost/rightmost window,
1352 but I guess it's not worth doing since vertically split windows
1353 are almost never used, internal border is rarely set, and the
1354 overhead is very small. */
1356 struct frame *f;
1357 int width, height;
1359 if (windows_or_buffers_changed
1360 && desired_row->full_width_p
1361 && (f = XFRAME (w->frame),
1362 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1363 width != 0)
1364 && (height = desired_row->visible_height,
1365 height > 0))
1367 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1368 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1370 block_input ();
1371 if (face)
1373 unsigned long color = face->background;
1374 Display *display = FRAME_X_DISPLAY (f);
1375 GC gc = f->output_data.x->normal_gc;
1377 XSetForeground (display, gc, color);
1378 x_fill_rectangle (f, gc, 0, y, width, height);
1379 x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
1380 width, height);
1381 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1383 else
1385 x_clear_area (f, 0, y, width, height);
1386 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1388 unblock_input ();
1391 #endif
1394 static void
1395 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1397 struct frame *f = XFRAME (WINDOW_FRAME (w));
1398 Display *display = FRAME_X_DISPLAY (f);
1399 GC gc = f->output_data.x->normal_gc;
1400 struct face *face = p->face;
1402 /* Must clip because of partially visible lines. */
1403 x_clip_to_row (w, row, ANY_AREA, gc);
1405 if (p->bx >= 0 && !p->overlay_p)
1407 /* In case the same realized face is used for fringes and
1408 for something displayed in the text (e.g. face `region' on
1409 mono-displays, the fill style may have been changed to
1410 FillSolid in x_draw_glyph_string_background. */
1411 if (face->stipple)
1412 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1413 else
1414 XSetForeground (display, face->gc, face->background);
1416 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1418 if (!face->stipple)
1419 XSetForeground (display, face->gc, face->foreground);
1422 #ifdef USE_CAIRO
1423 if (p->which && p->which < max_fringe_bmp)
1425 XGCValues gcv;
1427 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1428 XSetForeground (display, gc, (p->cursor_p
1429 ? (p->overlay_p ? face->background
1430 : f->output_data.x->cursor_pixel)
1431 : face->foreground));
1432 XSetBackground (display, gc, face->background);
1433 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1434 p->wd, p->h, p->x, p->y, p->overlay_p);
1435 XSetForeground (display, gc, gcv.foreground);
1436 XSetBackground (display, gc, gcv.background);
1438 #else /* not USE_CAIRO */
1439 if (p->which)
1441 Drawable drawable = FRAME_X_DRAWABLE (f);
1442 char *bits;
1443 Pixmap pixmap, clipmask = (Pixmap) 0;
1444 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1445 XGCValues gcv;
1447 if (p->wd > 8)
1448 bits = (char *) (p->bits + p->dh);
1449 else
1450 bits = (char *) p->bits + p->dh;
1452 /* Draw the bitmap. I believe these small pixmaps can be cached
1453 by the server. */
1454 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1455 (p->cursor_p
1456 ? (p->overlay_p ? face->background
1457 : f->output_data.x->cursor_pixel)
1458 : face->foreground),
1459 face->background, depth);
1461 if (p->overlay_p)
1463 clipmask = XCreatePixmapFromBitmapData (display,
1464 FRAME_DISPLAY_INFO (f)->root_window,
1465 bits, p->wd, p->h,
1466 1, 0, 1);
1467 gcv.clip_mask = clipmask;
1468 gcv.clip_x_origin = p->x;
1469 gcv.clip_y_origin = p->y;
1470 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1473 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1474 p->wd, p->h, p->x, p->y);
1475 XFreePixmap (display, pixmap);
1477 if (p->overlay_p)
1479 gcv.clip_mask = (Pixmap) 0;
1480 XChangeGC (display, gc, GCClipMask, &gcv);
1481 XFreePixmap (display, clipmask);
1484 #endif /* not USE_CAIRO */
1486 x_reset_clip_rectangles (f, gc);
1489 /***********************************************************************
1490 Glyph display
1491 ***********************************************************************/
1495 static void x_set_glyph_string_clipping (struct glyph_string *);
1496 static void x_set_glyph_string_gc (struct glyph_string *);
1497 static void x_draw_glyph_string_foreground (struct glyph_string *);
1498 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1499 static void x_draw_glyph_string_box (struct glyph_string *);
1500 static void x_draw_glyph_string (struct glyph_string *);
1501 static _Noreturn void x_delete_glyphs (struct frame *, int);
1502 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1503 static void x_set_cursor_gc (struct glyph_string *);
1504 static void x_set_mode_line_face_gc (struct glyph_string *);
1505 static void x_set_mouse_face_gc (struct glyph_string *);
1506 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1507 unsigned long *, double, int);
1508 static void x_setup_relief_color (struct frame *, struct relief *,
1509 double, int, unsigned long);
1510 static void x_setup_relief_colors (struct glyph_string *);
1511 static void x_draw_image_glyph_string (struct glyph_string *);
1512 static void x_draw_image_relief (struct glyph_string *);
1513 static void x_draw_image_foreground (struct glyph_string *);
1514 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1515 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1516 int, int, int);
1517 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1518 int, bool, bool, bool, bool, bool,
1519 XRectangle *);
1520 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1521 int, bool, bool, XRectangle *);
1522 static void x_scroll_bar_clear (struct frame *);
1524 #ifdef GLYPH_DEBUG
1525 static void x_check_font (struct frame *, struct font *);
1526 #endif
1529 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1530 face. */
1532 static void
1533 x_set_cursor_gc (struct glyph_string *s)
1535 if (s->font == FRAME_FONT (s->f)
1536 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1537 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1538 && !s->cmp)
1539 s->gc = s->f->output_data.x->cursor_gc;
1540 else
1542 /* Cursor on non-default face: must merge. */
1543 XGCValues xgcv;
1544 unsigned long mask;
1546 xgcv.background = s->f->output_data.x->cursor_pixel;
1547 xgcv.foreground = s->face->background;
1549 /* If the glyph would be invisible, try a different foreground. */
1550 if (xgcv.foreground == xgcv.background)
1551 xgcv.foreground = s->face->foreground;
1552 if (xgcv.foreground == xgcv.background)
1553 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1554 if (xgcv.foreground == xgcv.background)
1555 xgcv.foreground = s->face->foreground;
1557 /* Make sure the cursor is distinct from text in this face. */
1558 if (xgcv.background == s->face->background
1559 && xgcv.foreground == s->face->foreground)
1561 xgcv.background = s->face->foreground;
1562 xgcv.foreground = s->face->background;
1565 IF_DEBUG (x_check_font (s->f, s->font));
1566 xgcv.graphics_exposures = False;
1567 mask = GCForeground | GCBackground | GCGraphicsExposures;
1569 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1570 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1571 mask, &xgcv);
1572 else
1573 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1574 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1576 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1581 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1583 static void
1584 x_set_mouse_face_gc (struct glyph_string *s)
1586 int face_id;
1587 struct face *face;
1589 /* What face has to be used last for the mouse face? */
1590 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1591 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1592 if (face == NULL)
1593 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1595 if (s->first_glyph->type == CHAR_GLYPH)
1596 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1597 else
1598 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1599 s->face = FACE_FROM_ID (s->f, face_id);
1600 prepare_face_for_display (s->f, s->face);
1602 if (s->font == s->face->font)
1603 s->gc = s->face->gc;
1604 else
1606 /* Otherwise construct scratch_cursor_gc with values from FACE
1607 except for FONT. */
1608 XGCValues xgcv;
1609 unsigned long mask;
1611 xgcv.background = s->face->background;
1612 xgcv.foreground = s->face->foreground;
1613 xgcv.graphics_exposures = False;
1614 mask = GCForeground | GCBackground | GCGraphicsExposures;
1616 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1617 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1618 mask, &xgcv);
1619 else
1620 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1621 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1623 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1626 eassert (s->gc != 0);
1630 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1631 Faces to use in the mode line have already been computed when the
1632 matrix was built, so there isn't much to do, here. */
1634 static void
1635 x_set_mode_line_face_gc (struct glyph_string *s)
1637 s->gc = s->face->gc;
1641 /* Set S->gc of glyph string S for drawing that glyph string. Set
1642 S->stippled_p to a non-zero value if the face of S has a stipple
1643 pattern. */
1645 static void
1646 x_set_glyph_string_gc (struct glyph_string *s)
1648 prepare_face_for_display (s->f, s->face);
1650 if (s->hl == DRAW_NORMAL_TEXT)
1652 s->gc = s->face->gc;
1653 s->stippled_p = s->face->stipple != 0;
1655 else if (s->hl == DRAW_INVERSE_VIDEO)
1657 x_set_mode_line_face_gc (s);
1658 s->stippled_p = s->face->stipple != 0;
1660 else if (s->hl == DRAW_CURSOR)
1662 x_set_cursor_gc (s);
1663 s->stippled_p = false;
1665 else if (s->hl == DRAW_MOUSE_FACE)
1667 x_set_mouse_face_gc (s);
1668 s->stippled_p = s->face->stipple != 0;
1670 else if (s->hl == DRAW_IMAGE_RAISED
1671 || s->hl == DRAW_IMAGE_SUNKEN)
1673 s->gc = s->face->gc;
1674 s->stippled_p = s->face->stipple != 0;
1676 else
1677 emacs_abort ();
1679 /* GC must have been set. */
1680 eassert (s->gc != 0);
1684 /* Set clipping for output of glyph string S. S may be part of a mode
1685 line or menu if we don't have X toolkit support. */
1687 static void
1688 x_set_glyph_string_clipping (struct glyph_string *s)
1690 XRectangle *r = s->clip;
1691 int n = get_glyph_string_clip_rects (s, r, 2);
1693 if (n > 0)
1694 x_set_clip_rectangles (s->f, s->gc, r, n);
1695 s->num_clips = n;
1699 /* Set SRC's clipping for output of glyph string DST. This is called
1700 when we are drawing DST's left_overhang or right_overhang only in
1701 the area of SRC. */
1703 static void
1704 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1706 XRectangle r;
1708 r.x = src->x;
1709 r.width = src->width;
1710 r.y = src->y;
1711 r.height = src->height;
1712 dst->clip[0] = r;
1713 dst->num_clips = 1;
1714 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1718 /* RIF:
1719 Compute left and right overhang of glyph string S. */
1721 static void
1722 x_compute_glyph_string_overhangs (struct glyph_string *s)
1724 if (s->cmp == NULL
1725 && (s->first_glyph->type == CHAR_GLYPH
1726 || s->first_glyph->type == COMPOSITE_GLYPH))
1728 struct font_metrics metrics;
1730 if (s->first_glyph->type == CHAR_GLYPH)
1732 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1733 struct font *font = s->font;
1734 int i;
1736 for (i = 0; i < s->nchars; i++)
1737 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1738 font->driver->text_extents (font, code, s->nchars, &metrics);
1740 else
1742 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1744 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1746 s->right_overhang = (metrics.rbearing > metrics.width
1747 ? metrics.rbearing - metrics.width : 0);
1748 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1750 else if (s->cmp)
1752 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1753 s->left_overhang = - s->cmp->lbearing;
1758 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1760 static void
1761 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1763 XGCValues xgcv;
1764 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1765 XSetForeground (s->display, s->gc, xgcv.background);
1766 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1767 XSetForeground (s->display, s->gc, xgcv.foreground);
1771 /* Draw the background of glyph_string S. If S->background_filled_p
1772 is non-zero don't draw it. FORCE_P non-zero means draw the
1773 background even if it wouldn't be drawn normally. This is used
1774 when a string preceding S draws into the background of S, or S
1775 contains the first component of a composition. */
1777 static void
1778 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1780 /* Nothing to do if background has already been drawn or if it
1781 shouldn't be drawn in the first place. */
1782 if (!s->background_filled_p)
1784 int box_line_width = max (s->face->box_line_width, 0);
1786 if (s->stippled_p)
1788 /* Fill background with a stipple pattern. */
1789 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1790 x_fill_rectangle (s->f, s->gc, s->x,
1791 s->y + box_line_width,
1792 s->background_width,
1793 s->height - 2 * box_line_width);
1794 XSetFillStyle (s->display, s->gc, FillSolid);
1795 s->background_filled_p = true;
1797 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1798 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1799 font dimensions, since the actual glyphs might be
1800 much smaller. So in that case we always clear the
1801 rectangle with background color. */
1802 || FONT_TOO_HIGH (s->font)
1803 || s->font_not_found_p
1804 || s->extends_to_end_of_line_p
1805 || force_p)
1807 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1808 s->background_width,
1809 s->height - 2 * box_line_width);
1810 s->background_filled_p = true;
1816 /* Draw the foreground of glyph string S. */
1818 static void
1819 x_draw_glyph_string_foreground (struct glyph_string *s)
1821 int i, x;
1823 /* If first glyph of S has a left box line, start drawing the text
1824 of S to the right of that box line. */
1825 if (s->face->box != FACE_NO_BOX
1826 && s->first_glyph->left_box_line_p)
1827 x = s->x + eabs (s->face->box_line_width);
1828 else
1829 x = s->x;
1831 /* Draw characters of S as rectangles if S's font could not be
1832 loaded. */
1833 if (s->font_not_found_p)
1835 for (i = 0; i < s->nchars; ++i)
1837 struct glyph *g = s->first_glyph + i;
1838 x_draw_rectangle (s->f,
1839 s->gc, x, s->y, g->pixel_width - 1,
1840 s->height - 1);
1841 x += g->pixel_width;
1844 else
1846 struct font *font = s->font;
1847 int boff = font->baseline_offset;
1848 int y;
1850 if (font->vertical_centering)
1851 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1853 y = s->ybase - boff;
1854 if (s->for_overlaps
1855 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1856 font->driver->draw (s, 0, s->nchars, x, y, false);
1857 else
1858 font->driver->draw (s, 0, s->nchars, x, y, true);
1859 if (s->face->overstrike)
1860 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1864 /* Draw the foreground of composite glyph string S. */
1866 static void
1867 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1869 int i, j, x;
1870 struct font *font = s->font;
1872 /* If first glyph of S has a left box line, start drawing the text
1873 of S to the right of that box line. */
1874 if (s->face && s->face->box != FACE_NO_BOX
1875 && s->first_glyph->left_box_line_p)
1876 x = s->x + eabs (s->face->box_line_width);
1877 else
1878 x = s->x;
1880 /* S is a glyph string for a composition. S->cmp_from is the index
1881 of the first character drawn for glyphs of this composition.
1882 S->cmp_from == 0 means we are drawing the very first character of
1883 this composition. */
1885 /* Draw a rectangle for the composition if the font for the very
1886 first character of the composition could not be loaded. */
1887 if (s->font_not_found_p)
1889 if (s->cmp_from == 0)
1890 x_draw_rectangle (s->f, s->gc, x, s->y,
1891 s->width - 1, s->height - 1);
1893 else if (! s->first_glyph->u.cmp.automatic)
1895 int y = s->ybase;
1897 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1898 /* TAB in a composition means display glyphs with padding
1899 space on the left or right. */
1900 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1902 int xx = x + s->cmp->offsets[j * 2];
1903 int yy = y - s->cmp->offsets[j * 2 + 1];
1905 font->driver->draw (s, j, j + 1, xx, yy, false);
1906 if (s->face->overstrike)
1907 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1910 else
1912 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1913 Lisp_Object glyph;
1914 int y = s->ybase;
1915 int width = 0;
1917 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1919 glyph = LGSTRING_GLYPH (gstring, i);
1920 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1921 width += LGLYPH_WIDTH (glyph);
1922 else
1924 int xoff, yoff, wadjust;
1926 if (j < i)
1928 font->driver->draw (s, j, i, x, y, false);
1929 if (s->face->overstrike)
1930 font->driver->draw (s, j, i, x + 1, y, false);
1931 x += width;
1933 xoff = LGLYPH_XOFF (glyph);
1934 yoff = LGLYPH_YOFF (glyph);
1935 wadjust = LGLYPH_WADJUST (glyph);
1936 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1937 if (s->face->overstrike)
1938 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1939 false);
1940 x += wadjust;
1941 j = i + 1;
1942 width = 0;
1945 if (j < i)
1947 font->driver->draw (s, j, i, x, y, false);
1948 if (s->face->overstrike)
1949 font->driver->draw (s, j, i, x + 1, y, false);
1955 /* Draw the foreground of glyph string S for glyphless characters. */
1957 static void
1958 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1960 struct glyph *glyph = s->first_glyph;
1961 XChar2b char2b[8];
1962 int x, i, j;
1964 /* If first glyph of S has a left box line, start drawing the text
1965 of S to the right of that box line. */
1966 if (s->face && s->face->box != FACE_NO_BOX
1967 && s->first_glyph->left_box_line_p)
1968 x = s->x + eabs (s->face->box_line_width);
1969 else
1970 x = s->x;
1972 s->char2b = char2b;
1974 for (i = 0; i < s->nchars; i++, glyph++)
1976 char buf[7], *str = NULL;
1977 int len = glyph->u.glyphless.len;
1979 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1981 if (len > 0
1982 && CHAR_TABLE_P (Vglyphless_char_display)
1983 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1984 >= 1))
1986 Lisp_Object acronym
1987 = (! glyph->u.glyphless.for_no_font
1988 ? CHAR_TABLE_REF (Vglyphless_char_display,
1989 glyph->u.glyphless.ch)
1990 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1991 if (STRINGP (acronym))
1992 str = SSDATA (acronym);
1995 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1997 unsigned int ch = glyph->u.glyphless.ch;
1998 eassume (ch <= MAX_CHAR);
1999 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
2000 str = buf;
2003 if (str)
2005 int upper_len = (len + 1) / 2;
2006 unsigned code;
2008 /* It is assured that all LEN characters in STR is ASCII. */
2009 for (j = 0; j < len; j++)
2011 code = s->font->driver->encode_char (s->font, str[j]);
2012 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
2014 s->font->driver->draw (s, 0, upper_len,
2015 x + glyph->slice.glyphless.upper_xoff,
2016 s->ybase + glyph->slice.glyphless.upper_yoff,
2017 false);
2018 s->font->driver->draw (s, upper_len, len,
2019 x + glyph->slice.glyphless.lower_xoff,
2020 s->ybase + glyph->slice.glyphless.lower_yoff,
2021 false);
2023 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
2024 x_draw_rectangle (s->f, s->gc,
2025 x, s->ybase - glyph->ascent,
2026 glyph->pixel_width - 1,
2027 glyph->ascent + glyph->descent - 1);
2028 x += glyph->pixel_width;
2032 #ifdef USE_X_TOOLKIT
2034 #ifdef USE_LUCID
2036 /* Return the frame on which widget WIDGET is used.. Abort if frame
2037 cannot be determined. */
2039 static struct frame *
2040 x_frame_of_widget (Widget widget)
2042 struct x_display_info *dpyinfo;
2043 Lisp_Object tail, frame;
2044 struct frame *f;
2046 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2048 /* Find the top-level shell of the widget. Note that this function
2049 can be called when the widget is not yet realized, so XtWindow
2050 (widget) == 0. That's the reason we can't simply use
2051 x_any_window_to_frame. */
2052 while (!XtIsTopLevelShell (widget))
2053 widget = XtParent (widget);
2055 /* Look for a frame with that top-level widget. Allocate the color
2056 on that frame to get the right gamma correction value. */
2057 FOR_EACH_FRAME (tail, frame)
2059 f = XFRAME (frame);
2060 if (FRAME_X_P (f)
2061 && f->output_data.nothing != 1
2062 && FRAME_DISPLAY_INFO (f) == dpyinfo
2063 && f->output_data.x->widget == widget)
2064 return f;
2066 emacs_abort ();
2069 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2070 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2071 If this produces the same color as PIXEL, try a color where all RGB
2072 values have DELTA added. Return the allocated color in *PIXEL.
2073 DISPLAY is the X display, CMAP is the colormap to operate on.
2074 Value is true if successful. */
2076 bool
2077 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2078 unsigned long *pixel, double factor, int delta)
2080 struct frame *f = x_frame_of_widget (widget);
2081 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2084 #endif /* USE_LUCID */
2087 /* Structure specifying which arguments should be passed by Xt to
2088 cvt_string_to_pixel. We want the widget's screen and colormap. */
2090 static XtConvertArgRec cvt_string_to_pixel_args[] =
2092 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2093 sizeof (Screen *)},
2094 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2095 sizeof (Colormap)}
2099 /* The address of this variable is returned by
2100 cvt_string_to_pixel. */
2102 static Pixel cvt_string_to_pixel_value;
2105 /* Convert a color name to a pixel color.
2107 DPY is the display we are working on.
2109 ARGS is an array of *NARGS XrmValue structures holding additional
2110 information about the widget for which the conversion takes place.
2111 The contents of this array are determined by the specification
2112 in cvt_string_to_pixel_args.
2114 FROM is a pointer to an XrmValue which points to the color name to
2115 convert. TO is an XrmValue in which to return the pixel color.
2117 CLOSURE_RET is a pointer to user-data, in which we record if
2118 we allocated the color or not.
2120 Value is True if successful, False otherwise. */
2122 static Boolean
2123 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2124 XrmValue *from, XrmValue *to,
2125 XtPointer *closure_ret)
2127 Screen *screen;
2128 Colormap cmap;
2129 Pixel pixel;
2130 String color_name;
2131 XColor color;
2133 if (*nargs != 2)
2135 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2136 "wrongParameters", "cvt_string_to_pixel",
2137 "XtToolkitError",
2138 "Screen and colormap args required", NULL, NULL);
2139 return False;
2142 screen = *(Screen **) args[0].addr;
2143 cmap = *(Colormap *) args[1].addr;
2144 color_name = (String) from->addr;
2146 if (strcmp (color_name, XtDefaultBackground) == 0)
2148 *closure_ret = (XtPointer) False;
2149 pixel = WhitePixelOfScreen (screen);
2151 else if (strcmp (color_name, XtDefaultForeground) == 0)
2153 *closure_ret = (XtPointer) False;
2154 pixel = BlackPixelOfScreen (screen);
2156 else if (XParseColor (dpy, cmap, color_name, &color)
2157 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2159 pixel = color.pixel;
2160 *closure_ret = (XtPointer) True;
2162 else
2164 String params[1];
2165 Cardinal nparams = 1;
2167 params[0] = color_name;
2168 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2169 "badValue", "cvt_string_to_pixel",
2170 "XtToolkitError", "Invalid color '%s'",
2171 params, &nparams);
2172 return False;
2175 if (to->addr != NULL)
2177 if (to->size < sizeof (Pixel))
2179 to->size = sizeof (Pixel);
2180 return False;
2183 *(Pixel *) to->addr = pixel;
2185 else
2187 cvt_string_to_pixel_value = pixel;
2188 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2191 to->size = sizeof (Pixel);
2192 return True;
2196 /* Free a pixel color which was previously allocated via
2197 cvt_string_to_pixel. This is registered as the destructor
2198 for this type of resource via XtSetTypeConverter.
2200 APP is the application context in which we work.
2202 TO is a pointer to an XrmValue holding the color to free.
2203 CLOSURE is the value we stored in CLOSURE_RET for this color
2204 in cvt_string_to_pixel.
2206 ARGS and NARGS are like for cvt_string_to_pixel. */
2208 static void
2209 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2210 Cardinal *nargs)
2212 if (*nargs != 2)
2214 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2215 "XtToolkitError",
2216 "Screen and colormap arguments required",
2217 NULL, NULL);
2219 else if (closure != NULL)
2221 /* We did allocate the pixel, so free it. */
2222 Screen *screen = *(Screen **) args[0].addr;
2223 Colormap cmap = *(Colormap *) args[1].addr;
2224 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2225 (Pixel *) to->addr, 1);
2230 #endif /* USE_X_TOOLKIT */
2233 /* Value is an array of XColor structures for the contents of the
2234 color map of display DPY. Set *NCELLS to the size of the array.
2235 Note that this probably shouldn't be called for large color maps,
2236 say a 24-bit TrueColor map. */
2238 static const XColor *
2239 x_color_cells (Display *dpy, int *ncells)
2241 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2242 eassume (dpyinfo);
2244 if (dpyinfo->color_cells == NULL)
2246 Screen *screen = dpyinfo->screen;
2247 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2248 int i;
2250 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2251 sizeof *dpyinfo->color_cells);
2252 dpyinfo->ncolor_cells = ncolor_cells;
2254 for (i = 0; i < ncolor_cells; ++i)
2255 dpyinfo->color_cells[i].pixel = i;
2257 XQueryColors (dpy, dpyinfo->cmap,
2258 dpyinfo->color_cells, ncolor_cells);
2261 *ncells = dpyinfo->ncolor_cells;
2262 return dpyinfo->color_cells;
2266 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2267 colors in COLORS. Use cached information, if available. */
2269 void
2270 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2272 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2274 if (dpyinfo->red_bits > 0)
2276 /* For TrueColor displays, we can decompose the RGB value
2277 directly. */
2278 int i;
2279 unsigned int rmult, gmult, bmult;
2280 unsigned int rmask, gmask, bmask;
2282 rmask = (1 << dpyinfo->red_bits) - 1;
2283 gmask = (1 << dpyinfo->green_bits) - 1;
2284 bmask = (1 << dpyinfo->blue_bits) - 1;
2285 /* If we're widening, for example, 8 bits in the pixel value to
2286 16 bits for the separate-color representation, we want to
2287 extrapolate the lower bits based on those bits available --
2288 in other words, we'd like 0xff to become 0xffff instead of
2289 the 0xff00 we'd get by just zero-filling the lower bits.
2291 We generate a 32-bit scaled-up value and shift it, in case
2292 the bit count doesn't divide 16 evenly (e.g., when dealing
2293 with a 3-3-2 bit RGB display), to get more of the lower bits
2294 correct.
2296 Should we cache the multipliers in dpyinfo? Maybe
2297 special-case the 8-8-8 common case? */
2298 rmult = 0xffffffff / rmask;
2299 gmult = 0xffffffff / gmask;
2300 bmult = 0xffffffff / bmask;
2302 for (i = 0; i < ncolors; ++i)
2304 unsigned int r, g, b;
2305 unsigned long pixel = colors[i].pixel;
2307 r = (pixel >> dpyinfo->red_offset) & rmask;
2308 g = (pixel >> dpyinfo->green_offset) & gmask;
2309 b = (pixel >> dpyinfo->blue_offset) & bmask;
2311 colors[i].red = (r * rmult) >> 16;
2312 colors[i].green = (g * gmult) >> 16;
2313 colors[i].blue = (b * bmult) >> 16;
2315 return;
2318 if (dpyinfo->color_cells)
2320 int i;
2321 for (i = 0; i < ncolors; ++i)
2323 unsigned long pixel = colors[i].pixel;
2324 eassert (pixel < dpyinfo->ncolor_cells);
2325 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2326 colors[i] = dpyinfo->color_cells[pixel];
2328 return;
2331 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2335 /* On frame F, translate pixel color to RGB values for the color in
2336 COLOR. Use cached information, if available. */
2338 void
2339 x_query_color (struct frame *f, XColor *color)
2341 x_query_colors (f, color, 1);
2345 /* On frame F, translate the color name to RGB values. Use cached
2346 information, if possible.
2348 Note that there is currently no way to clean old entries out of the
2349 cache. However, it is limited to names in the server's database,
2350 and names we've actually looked up; list-colors-display is probably
2351 the most color-intensive case we're likely to hit. */
2353 Status x_parse_color (struct frame *f, const char *color_name,
2354 XColor *color)
2356 Display *dpy = FRAME_X_DISPLAY (f);
2357 Colormap cmap = FRAME_X_COLORMAP (f);
2358 struct color_name_cache_entry *cache_entry;
2360 if (color_name[0] == '#')
2362 /* The hex form is parsed directly by XParseColor without
2363 talking to the X server. No need for caching. */
2364 return XParseColor (dpy, cmap, color_name, color);
2367 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2368 cache_entry = cache_entry->next)
2370 if (!xstrcasecmp(cache_entry->name, color_name))
2372 *color = cache_entry->rgb;
2373 return 1;
2377 if (XParseColor (dpy, cmap, color_name, color) == 0)
2378 /* No caching of negative results, currently. */
2379 return 0;
2381 cache_entry = xzalloc (sizeof *cache_entry);
2382 cache_entry->rgb = *color;
2383 cache_entry->name = xstrdup (color_name);
2384 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2385 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2386 return 1;
2390 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2391 exact match can't be allocated, try the nearest color available.
2392 Value is true if successful. Set *COLOR to the color
2393 allocated. */
2395 static bool
2396 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2398 bool rc;
2400 rc = XAllocColor (dpy, cmap, color) != 0;
2401 if (rc == 0)
2403 /* If we got to this point, the colormap is full, so we're going
2404 to try to get the next closest color. The algorithm used is
2405 a least-squares matching, which is what X uses for closest
2406 color matching with StaticColor visuals. */
2407 int nearest, i;
2408 int max_color_delta = 255;
2409 int max_delta = 3 * max_color_delta;
2410 int nearest_delta = max_delta + 1;
2411 int ncells;
2412 const XColor *cells = x_color_cells (dpy, &ncells);
2414 for (nearest = i = 0; i < ncells; ++i)
2416 int dred = (color->red >> 8) - (cells[i].red >> 8);
2417 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2418 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2419 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2421 if (delta < nearest_delta)
2423 nearest = i;
2424 nearest_delta = delta;
2428 color->red = cells[nearest].red;
2429 color->green = cells[nearest].green;
2430 color->blue = cells[nearest].blue;
2431 rc = XAllocColor (dpy, cmap, color) != 0;
2433 else
2435 /* If allocation succeeded, and the allocated pixel color is not
2436 equal to a cached pixel color recorded earlier, there was a
2437 change in the colormap, so clear the color cache. */
2438 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2439 eassume (dpyinfo);
2441 if (dpyinfo->color_cells)
2443 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2444 if (cached_color->red != color->red
2445 || cached_color->blue != color->blue
2446 || cached_color->green != color->green)
2448 xfree (dpyinfo->color_cells);
2449 dpyinfo->color_cells = NULL;
2450 dpyinfo->ncolor_cells = 0;
2455 #ifdef DEBUG_X_COLORS
2456 if (rc)
2457 register_color (color->pixel);
2458 #endif /* DEBUG_X_COLORS */
2460 return rc;
2464 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2465 gamma correction. If an exact match can't be allocated, try the
2466 nearest color available. Value is true if successful. Set *COLOR
2467 to the color allocated. */
2469 bool
2470 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2472 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2474 gamma_correct (f, color);
2476 if (dpyinfo->red_bits > 0)
2478 color->pixel = x_make_truecolor_pixel (dpyinfo,
2479 color->red,
2480 color->green,
2481 color->blue);
2482 return true;
2485 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2489 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2490 It's necessary to do this instead of just using PIXEL directly to
2491 get color reference counts right. */
2493 unsigned long
2494 x_copy_color (struct frame *f, unsigned long pixel)
2496 XColor color;
2498 /* If display has an immutable color map, freeing colors is not
2499 necessary and some servers don't allow it. Since we won't free a
2500 color once we've allocated it, we don't need to re-allocate it to
2501 maintain the server's reference count. */
2502 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2503 return pixel;
2505 color.pixel = pixel;
2506 block_input ();
2507 /* The color could still be found in the color_cells array. */
2508 x_query_color (f, &color);
2509 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2510 unblock_input ();
2511 #ifdef DEBUG_X_COLORS
2512 register_color (pixel);
2513 #endif
2514 return color.pixel;
2518 /* Brightness beyond which a color won't have its highlight brightness
2519 boosted.
2521 Nominally, highlight colors for `3d' faces are calculated by
2522 brightening an object's color by a constant scale factor, but this
2523 doesn't yield good results for dark colors, so for colors who's
2524 brightness is less than this value (on a scale of 0-65535) have an
2525 use an additional additive factor.
2527 The value here is set so that the default menu-bar/mode-line color
2528 (grey75) will not have its highlights changed at all. */
2529 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2532 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2533 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2534 If this produces the same color as PIXEL, try a color where all RGB
2535 values have DELTA added. Return the allocated color in *PIXEL.
2536 DISPLAY is the X display, CMAP is the colormap to operate on.
2537 Value is non-zero if successful. */
2539 static bool
2540 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2541 unsigned long *pixel, double factor, int delta)
2543 XColor color, new;
2544 long bright;
2545 bool success_p;
2547 /* Get RGB color values. */
2548 color.pixel = *pixel;
2549 x_query_color (f, &color);
2551 /* Change RGB values by specified FACTOR. Avoid overflow! */
2552 eassert (factor >= 0);
2553 new.red = min (0xffff, factor * color.red);
2554 new.green = min (0xffff, factor * color.green);
2555 new.blue = min (0xffff, factor * color.blue);
2557 /* Calculate brightness of COLOR. */
2558 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2560 /* We only boost colors that are darker than
2561 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2562 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2563 /* Make an additive adjustment to NEW, because it's dark enough so
2564 that scaling by FACTOR alone isn't enough. */
2566 /* How far below the limit this color is (0 - 1, 1 being darker). */
2567 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2568 /* The additive adjustment. */
2569 int min_delta = delta * dimness * factor / 2;
2571 if (factor < 1)
2573 new.red = max (0, new.red - min_delta);
2574 new.green = max (0, new.green - min_delta);
2575 new.blue = max (0, new.blue - min_delta);
2577 else
2579 new.red = min (0xffff, min_delta + new.red);
2580 new.green = min (0xffff, min_delta + new.green);
2581 new.blue = min (0xffff, min_delta + new.blue);
2585 /* Try to allocate the color. */
2586 success_p = x_alloc_nearest_color (f, cmap, &new);
2587 if (success_p)
2589 if (new.pixel == *pixel)
2591 /* If we end up with the same color as before, try adding
2592 delta to the RGB values. */
2593 x_free_colors (f, &new.pixel, 1);
2595 new.red = min (0xffff, delta + color.red);
2596 new.green = min (0xffff, delta + color.green);
2597 new.blue = min (0xffff, delta + color.blue);
2598 success_p = x_alloc_nearest_color (f, cmap, &new);
2600 else
2601 success_p = true;
2602 *pixel = new.pixel;
2605 return success_p;
2609 /* Set up the foreground color for drawing relief lines of glyph
2610 string S. RELIEF is a pointer to a struct relief containing the GC
2611 with which lines will be drawn. Use a color that is FACTOR or
2612 DELTA lighter or darker than the relief's background which is found
2613 in S->f->output_data.x->relief_background. If such a color cannot
2614 be allocated, use DEFAULT_PIXEL, instead. */
2616 static void
2617 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2618 int delta, unsigned long default_pixel)
2620 XGCValues xgcv;
2621 struct x_output *di = f->output_data.x;
2622 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2623 unsigned long pixel;
2624 unsigned long background = di->relief_background;
2625 Colormap cmap = FRAME_X_COLORMAP (f);
2626 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2627 Display *dpy = FRAME_X_DISPLAY (f);
2629 xgcv.graphics_exposures = False;
2630 xgcv.line_width = 1;
2632 /* Free previously allocated color. The color cell will be reused
2633 when it has been freed as many times as it was allocated, so this
2634 doesn't affect faces using the same colors. */
2635 if (relief->gc && relief->pixel != -1)
2637 x_free_colors (f, &relief->pixel, 1);
2638 relief->pixel = -1;
2641 /* Allocate new color. */
2642 xgcv.foreground = default_pixel;
2643 pixel = background;
2644 if (dpyinfo->n_planes != 1
2645 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2646 xgcv.foreground = relief->pixel = pixel;
2648 if (relief->gc == 0)
2650 xgcv.stipple = dpyinfo->gray;
2651 mask |= GCStipple;
2652 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2654 else
2655 XChangeGC (dpy, relief->gc, mask, &xgcv);
2659 /* Set up colors for the relief lines around glyph string S. */
2661 static void
2662 x_setup_relief_colors (struct glyph_string *s)
2664 struct x_output *di = s->f->output_data.x;
2665 unsigned long color;
2667 if (s->face->use_box_color_for_shadows_p)
2668 color = s->face->box_color;
2669 else if (s->first_glyph->type == IMAGE_GLYPH
2670 && s->img->pixmap
2671 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2672 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2673 else
2675 XGCValues xgcv;
2677 /* Get the background color of the face. */
2678 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2679 color = xgcv.background;
2682 if (di->white_relief.gc == 0
2683 || color != di->relief_background)
2685 di->relief_background = color;
2686 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2687 WHITE_PIX_DEFAULT (s->f));
2688 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2689 BLACK_PIX_DEFAULT (s->f));
2694 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2695 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2696 to draw, it must be >= 0. RAISED_P means draw a raised
2697 relief. LEFT_P means draw a relief on the left side of
2698 the rectangle. RIGHT_P means draw a relief on the right
2699 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2700 when drawing. */
2702 static void
2703 x_draw_relief_rect (struct frame *f,
2704 int left_x, int top_y, int right_x, int bottom_y,
2705 int width, bool raised_p, bool top_p, bool bot_p,
2706 bool left_p, bool right_p,
2707 XRectangle *clip_rect)
2709 #ifdef USE_CAIRO
2710 GC top_left_gc, bottom_right_gc;
2711 int corners = 0;
2713 if (raised_p)
2715 top_left_gc = f->output_data.x->white_relief.gc;
2716 bottom_right_gc = f->output_data.x->black_relief.gc;
2718 else
2720 top_left_gc = f->output_data.x->black_relief.gc;
2721 bottom_right_gc = f->output_data.x->white_relief.gc;
2724 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2725 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2727 if (left_p)
2729 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2730 width, bottom_y + 1 - top_y);
2731 if (top_p)
2732 corners |= 1 << CORNER_TOP_LEFT;
2733 if (bot_p)
2734 corners |= 1 << CORNER_BOTTOM_LEFT;
2736 if (right_p)
2738 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2739 width, bottom_y + 1 - top_y);
2740 if (top_p)
2741 corners |= 1 << CORNER_TOP_RIGHT;
2742 if (bot_p)
2743 corners |= 1 << CORNER_BOTTOM_RIGHT;
2745 if (top_p)
2747 if (!right_p)
2748 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2749 right_x + 1 - left_x, width);
2750 else
2751 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2752 right_x + 1 - left_x, width, 1);
2754 if (bot_p)
2756 if (!left_p)
2757 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2758 right_x + 1 - left_x, width);
2759 else
2760 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2761 left_x, bottom_y + 1 - width,
2762 right_x + 1 - left_x, width, 0);
2764 if (left_p && width != 1)
2765 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2766 1, bottom_y + 1 - top_y);
2767 if (top_p && width != 1)
2768 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2769 right_x + 1 - left_x, 1);
2770 if (corners)
2772 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2773 FRAME_BACKGROUND_PIXEL (f));
2774 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2775 right_x - left_x + 1, bottom_y - top_y + 1,
2776 6, 1, corners);
2779 x_reset_clip_rectangles (f, top_left_gc);
2780 x_reset_clip_rectangles (f, bottom_right_gc);
2781 #else
2782 Display *dpy = FRAME_X_DISPLAY (f);
2783 Drawable drawable = FRAME_X_DRAWABLE (f);
2784 int i;
2785 GC gc;
2787 if (raised_p)
2788 gc = f->output_data.x->white_relief.gc;
2789 else
2790 gc = f->output_data.x->black_relief.gc;
2791 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2793 /* This code is more complicated than it has to be, because of two
2794 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2795 the outermost line using the black relief. (ii) Omit the four
2796 corner pixels. */
2798 /* Top. */
2799 if (top_p)
2801 if (width == 1)
2802 XDrawLine (dpy, drawable, gc,
2803 left_x + left_p, top_y,
2804 right_x + !right_p, top_y);
2806 for (i = 1; i < width; ++i)
2807 XDrawLine (dpy, drawable, gc,
2808 left_x + i * left_p, top_y + i,
2809 right_x + 1 - i * right_p, top_y + i);
2812 /* Left. */
2813 if (left_p)
2815 if (width == 1)
2816 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2818 x_clear_area(f, left_x, top_y, 1, 1);
2819 x_clear_area(f, left_x, bottom_y, 1, 1);
2821 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2822 XDrawLine (dpy, drawable, gc,
2823 left_x + i, top_y + (i + 1) * top_p,
2824 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2827 XSetClipMask (dpy, gc, None);
2828 if (raised_p)
2829 gc = f->output_data.x->black_relief.gc;
2830 else
2831 gc = f->output_data.x->white_relief.gc;
2832 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2834 if (width > 1)
2836 /* Outermost top line. */
2837 if (top_p)
2838 XDrawLine (dpy, drawable, gc,
2839 left_x + left_p, top_y,
2840 right_x + !right_p, top_y);
2842 /* Outermost left line. */
2843 if (left_p)
2844 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2847 /* Bottom. */
2848 if (bot_p)
2850 XDrawLine (dpy, drawable, gc,
2851 left_x + left_p, bottom_y,
2852 right_x + !right_p, bottom_y);
2853 for (i = 1; i < width; ++i)
2854 XDrawLine (dpy, drawable, gc,
2855 left_x + i * left_p, bottom_y - i,
2856 right_x + 1 - i * right_p, bottom_y - i);
2859 /* Right. */
2860 if (right_p)
2862 x_clear_area(f, right_x, top_y, 1, 1);
2863 x_clear_area(f, right_x, bottom_y, 1, 1);
2864 for (i = 0; i < width; ++i)
2865 XDrawLine (dpy, drawable, gc,
2866 right_x - i, top_y + (i + 1) * top_p,
2867 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2870 x_reset_clip_rectangles (f, gc);
2872 #endif
2876 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2877 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2878 draw, it must be >= 0. LEFT_P means draw a line on the
2879 left side of the rectangle. RIGHT_P means draw a line
2880 on the right side of the rectangle. CLIP_RECT is the clipping
2881 rectangle to use when drawing. */
2883 static void
2884 x_draw_box_rect (struct glyph_string *s,
2885 int left_x, int top_y, int right_x, int bottom_y, int width,
2886 bool left_p, bool right_p, XRectangle *clip_rect)
2888 XGCValues xgcv;
2890 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2891 XSetForeground (s->display, s->gc, s->face->box_color);
2892 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2894 /* Top. */
2895 x_fill_rectangle (s->f, s->gc,
2896 left_x, top_y, right_x - left_x + 1, width);
2898 /* Left. */
2899 if (left_p)
2900 x_fill_rectangle (s->f, s->gc,
2901 left_x, top_y, width, bottom_y - top_y + 1);
2903 /* Bottom. */
2904 x_fill_rectangle (s->f, s->gc,
2905 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2907 /* Right. */
2908 if (right_p)
2909 x_fill_rectangle (s->f, s->gc,
2910 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2912 XSetForeground (s->display, s->gc, xgcv.foreground);
2913 x_reset_clip_rectangles (s->f, s->gc);
2917 /* Draw a box around glyph string S. */
2919 static void
2920 x_draw_glyph_string_box (struct glyph_string *s)
2922 int width, left_x, right_x, top_y, bottom_y, last_x;
2923 bool raised_p, left_p, right_p;
2924 struct glyph *last_glyph;
2925 XRectangle clip_rect;
2927 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2928 ? WINDOW_RIGHT_EDGE_X (s->w)
2929 : window_box_right (s->w, s->area));
2931 /* The glyph that may have a right box line. */
2932 last_glyph = (s->cmp || s->img
2933 ? s->first_glyph
2934 : s->first_glyph + s->nchars - 1);
2936 width = eabs (s->face->box_line_width);
2937 raised_p = s->face->box == FACE_RAISED_BOX;
2938 left_x = s->x;
2939 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2940 ? last_x - 1
2941 : min (last_x, s->x + s->background_width) - 1);
2942 top_y = s->y;
2943 bottom_y = top_y + s->height - 1;
2945 left_p = (s->first_glyph->left_box_line_p
2946 || (s->hl == DRAW_MOUSE_FACE
2947 && (s->prev == NULL
2948 || s->prev->hl != s->hl)));
2949 right_p = (last_glyph->right_box_line_p
2950 || (s->hl == DRAW_MOUSE_FACE
2951 && (s->next == NULL
2952 || s->next->hl != s->hl)));
2954 get_glyph_string_clip_rect (s, &clip_rect);
2956 if (s->face->box == FACE_SIMPLE_BOX)
2957 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2958 left_p, right_p, &clip_rect);
2959 else
2961 x_setup_relief_colors (s);
2962 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2963 width, raised_p, true, true, left_p, right_p,
2964 &clip_rect);
2969 /* Draw foreground of image glyph string S. */
2971 static void
2972 x_draw_image_foreground (struct glyph_string *s)
2974 int x = s->x;
2975 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2977 /* If first glyph of S has a left box line, start drawing it to the
2978 right of that line. */
2979 if (s->face->box != FACE_NO_BOX
2980 && s->first_glyph->left_box_line_p
2981 && s->slice.x == 0)
2982 x += eabs (s->face->box_line_width);
2984 /* If there is a margin around the image, adjust x- and y-position
2985 by that margin. */
2986 if (s->slice.x == 0)
2987 x += s->img->hmargin;
2988 if (s->slice.y == 0)
2989 y += s->img->vmargin;
2991 if (s->img->pixmap)
2993 if (s->img->mask)
2995 /* We can't set both a clip mask and use XSetClipRectangles
2996 because the latter also sets a clip mask. We also can't
2997 trust on the shape extension to be available
2998 (XShapeCombineRegion). So, compute the rectangle to draw
2999 manually. */
3000 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3001 | GCFunction);
3002 XGCValues xgcv;
3003 XRectangle clip_rect, image_rect, r;
3005 xgcv.clip_mask = s->img->mask;
3006 xgcv.clip_x_origin = x;
3007 xgcv.clip_y_origin = y;
3008 xgcv.function = GXcopy;
3009 XChangeGC (s->display, s->gc, mask, &xgcv);
3011 get_glyph_string_clip_rect (s, &clip_rect);
3012 image_rect.x = x;
3013 image_rect.y = y;
3014 image_rect.width = s->slice.width;
3015 image_rect.height = s->slice.height;
3016 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3017 XCopyArea (s->display, s->img->pixmap,
3018 FRAME_X_DRAWABLE (s->f), s->gc,
3019 s->slice.x + r.x - x, s->slice.y + r.y - y,
3020 r.width, r.height, r.x, r.y);
3022 else
3024 XRectangle clip_rect, image_rect, r;
3026 get_glyph_string_clip_rect (s, &clip_rect);
3027 image_rect.x = x;
3028 image_rect.y = y;
3029 image_rect.width = s->slice.width;
3030 image_rect.height = s->slice.height;
3031 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3032 XCopyArea (s->display, s->img->pixmap,
3033 FRAME_X_DRAWABLE (s->f), s->gc,
3034 s->slice.x + r.x - x, s->slice.y + r.y - y,
3035 r.width, r.height, r.x, r.y);
3037 /* When the image has a mask, we can expect that at
3038 least part of a mouse highlight or a block cursor will
3039 be visible. If the image doesn't have a mask, make
3040 a block cursor visible by drawing a rectangle around
3041 the image. I believe it's looking better if we do
3042 nothing here for mouse-face. */
3043 if (s->hl == DRAW_CURSOR)
3045 int relief = eabs (s->img->relief);
3046 x_draw_rectangle (s->f, s->gc,
3047 x - relief, y - relief,
3048 s->slice.width + relief*2 - 1,
3049 s->slice.height + relief*2 - 1);
3053 else
3054 /* Draw a rectangle if image could not be loaded. */
3055 x_draw_rectangle (s->f, s->gc, x, y,
3056 s->slice.width - 1, s->slice.height - 1);
3060 /* Draw a relief around the image glyph string S. */
3062 static void
3063 x_draw_image_relief (struct glyph_string *s)
3065 int x1, y1, thick;
3066 bool raised_p, top_p, bot_p, left_p, right_p;
3067 int extra_x, extra_y;
3068 XRectangle r;
3069 int x = s->x;
3070 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3072 /* If first glyph of S has a left box line, start drawing it to the
3073 right of that line. */
3074 if (s->face->box != FACE_NO_BOX
3075 && s->first_glyph->left_box_line_p
3076 && s->slice.x == 0)
3077 x += eabs (s->face->box_line_width);
3079 /* If there is a margin around the image, adjust x- and y-position
3080 by that margin. */
3081 if (s->slice.x == 0)
3082 x += s->img->hmargin;
3083 if (s->slice.y == 0)
3084 y += s->img->vmargin;
3086 if (s->hl == DRAW_IMAGE_SUNKEN
3087 || s->hl == DRAW_IMAGE_RAISED)
3089 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3090 raised_p = s->hl == DRAW_IMAGE_RAISED;
3092 else
3094 thick = eabs (s->img->relief);
3095 raised_p = s->img->relief > 0;
3098 x1 = x + s->slice.width - 1;
3099 y1 = y + s->slice.height - 1;
3101 extra_x = extra_y = 0;
3102 if (s->face->id == TOOL_BAR_FACE_ID)
3104 if (CONSP (Vtool_bar_button_margin)
3105 && INTEGERP (XCAR (Vtool_bar_button_margin))
3106 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3108 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3109 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3111 else if (INTEGERP (Vtool_bar_button_margin))
3112 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3115 top_p = bot_p = left_p = right_p = false;
3117 if (s->slice.x == 0)
3118 x -= thick + extra_x, left_p = true;
3119 if (s->slice.y == 0)
3120 y -= thick + extra_y, top_p = true;
3121 if (s->slice.x + s->slice.width == s->img->width)
3122 x1 += thick + extra_x, right_p = true;
3123 if (s->slice.y + s->slice.height == s->img->height)
3124 y1 += thick + extra_y, bot_p = true;
3126 x_setup_relief_colors (s);
3127 get_glyph_string_clip_rect (s, &r);
3128 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3129 top_p, bot_p, left_p, right_p, &r);
3133 /* Draw the foreground of image glyph string S to PIXMAP. */
3135 static void
3136 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3138 int x = 0;
3139 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3141 /* If first glyph of S has a left box line, start drawing it to the
3142 right of that line. */
3143 if (s->face->box != FACE_NO_BOX
3144 && s->first_glyph->left_box_line_p
3145 && s->slice.x == 0)
3146 x += eabs (s->face->box_line_width);
3148 /* If there is a margin around the image, adjust x- and y-position
3149 by that margin. */
3150 if (s->slice.x == 0)
3151 x += s->img->hmargin;
3152 if (s->slice.y == 0)
3153 y += s->img->vmargin;
3155 if (s->img->pixmap)
3157 if (s->img->mask)
3159 /* We can't set both a clip mask and use XSetClipRectangles
3160 because the latter also sets a clip mask. We also can't
3161 trust on the shape extension to be available
3162 (XShapeCombineRegion). So, compute the rectangle to draw
3163 manually. */
3164 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3165 | GCFunction);
3166 XGCValues xgcv;
3168 xgcv.clip_mask = s->img->mask;
3169 xgcv.clip_x_origin = x - s->slice.x;
3170 xgcv.clip_y_origin = y - s->slice.y;
3171 xgcv.function = GXcopy;
3172 XChangeGC (s->display, s->gc, mask, &xgcv);
3174 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3175 s->slice.x, s->slice.y,
3176 s->slice.width, s->slice.height, x, y);
3177 XSetClipMask (s->display, s->gc, None);
3179 else
3181 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3182 s->slice.x, s->slice.y,
3183 s->slice.width, s->slice.height, x, y);
3185 /* When the image has a mask, we can expect that at
3186 least part of a mouse highlight or a block cursor will
3187 be visible. If the image doesn't have a mask, make
3188 a block cursor visible by drawing a rectangle around
3189 the image. I believe it's looking better if we do
3190 nothing here for mouse-face. */
3191 if (s->hl == DRAW_CURSOR)
3193 int r = eabs (s->img->relief);
3194 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3195 s->slice.width + r*2 - 1,
3196 s->slice.height + r*2 - 1);
3200 else
3201 /* Draw a rectangle if image could not be loaded. */
3202 x_draw_rectangle (s->f, s->gc, x, y,
3203 s->slice.width - 1, s->slice.height - 1);
3207 /* Draw part of the background of glyph string S. X, Y, W, and H
3208 give the rectangle to draw. */
3210 static void
3211 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3213 if (s->stippled_p)
3215 /* Fill background with a stipple pattern. */
3216 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3217 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3218 XSetFillStyle (s->display, s->gc, FillSolid);
3220 else
3221 x_clear_glyph_string_rect (s, x, y, w, h);
3225 /* Draw image glyph string S.
3227 s->y
3228 s->x +-------------------------
3229 | s->face->box
3231 | +-------------------------
3232 | | s->img->margin
3234 | | +-------------------
3235 | | | the image
3239 static void
3240 x_draw_image_glyph_string (struct glyph_string *s)
3242 int box_line_hwidth = eabs (s->face->box_line_width);
3243 int box_line_vwidth = max (s->face->box_line_width, 0);
3244 int height;
3245 Pixmap pixmap = None;
3247 height = s->height;
3248 if (s->slice.y == 0)
3249 height -= box_line_vwidth;
3250 if (s->slice.y + s->slice.height >= s->img->height)
3251 height -= box_line_vwidth;
3253 /* Fill background with face under the image. Do it only if row is
3254 taller than image or if image has a clip mask to reduce
3255 flickering. */
3256 s->stippled_p = s->face->stipple != 0;
3257 if (height > s->slice.height
3258 || s->img->hmargin
3259 || s->img->vmargin
3260 || s->img->mask
3261 || s->img->pixmap == 0
3262 || s->width != s->background_width)
3264 if (s->img->mask)
3266 /* Create a pixmap as large as the glyph string. Fill it
3267 with the background color. Copy the image to it, using
3268 its mask. Copy the temporary pixmap to the display. */
3269 Screen *screen = FRAME_X_SCREEN (s->f);
3270 int depth = DefaultDepthOfScreen (screen);
3272 /* Create a pixmap as large as the glyph string. */
3273 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3274 s->background_width,
3275 s->height, depth);
3277 /* Don't clip in the following because we're working on the
3278 pixmap. */
3279 XSetClipMask (s->display, s->gc, None);
3281 /* Fill the pixmap with the background color/stipple. */
3282 if (s->stippled_p)
3284 /* Fill background with a stipple pattern. */
3285 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3286 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3287 XFillRectangle (s->display, pixmap, s->gc,
3288 0, 0, s->background_width, s->height);
3289 XSetFillStyle (s->display, s->gc, FillSolid);
3290 XSetTSOrigin (s->display, s->gc, 0, 0);
3292 else
3294 XGCValues xgcv;
3295 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3296 &xgcv);
3297 XSetForeground (s->display, s->gc, xgcv.background);
3298 XFillRectangle (s->display, pixmap, s->gc,
3299 0, 0, s->background_width, s->height);
3300 XSetForeground (s->display, s->gc, xgcv.foreground);
3303 else
3305 int x = s->x;
3306 int y = s->y;
3307 int width = s->background_width;
3309 if (s->first_glyph->left_box_line_p
3310 && s->slice.x == 0)
3312 x += box_line_hwidth;
3313 width -= box_line_hwidth;
3316 if (s->slice.y == 0)
3317 y += box_line_vwidth;
3319 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3322 s->background_filled_p = true;
3325 /* Draw the foreground. */
3326 #ifdef USE_CAIRO
3327 if (s->img->cr_data)
3329 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3331 int x = s->x + s->img->hmargin;
3332 int y = s->y + s->img->vmargin;
3333 int width = s->background_width;
3335 cairo_set_source_surface (cr, s->img->cr_data,
3336 x - s->slice.x,
3337 y - s->slice.y);
3338 cairo_rectangle (cr, x, y, width, height);
3339 cairo_fill (cr);
3340 x_end_cr_clip (s->f);
3342 else
3343 #endif
3344 if (pixmap != None)
3346 x_draw_image_foreground_1 (s, pixmap);
3347 x_set_glyph_string_clipping (s);
3348 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3349 0, 0, s->background_width, s->height, s->x, s->y);
3350 XFreePixmap (s->display, pixmap);
3352 else
3353 x_draw_image_foreground (s);
3355 /* If we must draw a relief around the image, do it. */
3356 if (s->img->relief
3357 || s->hl == DRAW_IMAGE_RAISED
3358 || s->hl == DRAW_IMAGE_SUNKEN)
3359 x_draw_image_relief (s);
3363 /* Draw stretch glyph string S. */
3365 static void
3366 x_draw_stretch_glyph_string (struct glyph_string *s)
3368 eassert (s->first_glyph->type == STRETCH_GLYPH);
3370 if (s->hl == DRAW_CURSOR
3371 && !x_stretch_cursor_p)
3373 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3374 wide as the stretch glyph. */
3375 int width, background_width = s->background_width;
3376 int x = s->x;
3378 if (!s->row->reversed_p)
3380 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3382 if (x < left_x)
3384 background_width -= left_x - x;
3385 x = left_x;
3388 else
3390 /* In R2L rows, draw the cursor on the right edge of the
3391 stretch glyph. */
3392 int right_x = window_box_right (s->w, TEXT_AREA);
3394 if (x + background_width > right_x)
3395 background_width -= x - right_x;
3396 x += background_width;
3398 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3399 if (s->row->reversed_p)
3400 x -= width;
3402 /* Draw cursor. */
3403 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3405 /* Clear rest using the GC of the original non-cursor face. */
3406 if (width < background_width)
3408 int y = s->y;
3409 int w = background_width - width, h = s->height;
3410 XRectangle r;
3411 GC gc;
3413 if (!s->row->reversed_p)
3414 x += width;
3415 else
3416 x = s->x;
3417 if (s->row->mouse_face_p
3418 && cursor_in_mouse_face_p (s->w))
3420 x_set_mouse_face_gc (s);
3421 gc = s->gc;
3423 else
3424 gc = s->face->gc;
3426 get_glyph_string_clip_rect (s, &r);
3427 x_set_clip_rectangles (s->f, gc, &r, 1);
3429 if (s->face->stipple)
3431 /* Fill background with a stipple pattern. */
3432 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3433 x_fill_rectangle (s->f, gc, x, y, w, h);
3434 XSetFillStyle (s->display, gc, FillSolid);
3436 else
3438 XGCValues xgcv;
3439 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3440 XSetForeground (s->display, gc, xgcv.background);
3441 x_fill_rectangle (s->f, gc, x, y, w, h);
3442 XSetForeground (s->display, gc, xgcv.foreground);
3445 x_reset_clip_rectangles (s->f, gc);
3448 else if (!s->background_filled_p)
3450 int background_width = s->background_width;
3451 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3453 /* Don't draw into left margin, fringe or scrollbar area
3454 except for header line and mode line. */
3455 if (x < left_x && !s->row->mode_line_p)
3457 background_width -= left_x - x;
3458 x = left_x;
3460 if (background_width > 0)
3461 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3464 s->background_filled_p = true;
3467 static void
3468 x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
3470 const int base_res = 96;
3471 struct x_display_info * dpyinfo = x_display_info_for_display (disp);
3473 *scale_x = *scale_y = 1;
3475 if (dpyinfo)
3477 if (dpyinfo->resx > base_res)
3478 *scale_x = floor (dpyinfo->resx / base_res);
3479 if (dpyinfo->resy > base_res)
3480 *scale_y = floor (dpyinfo->resy / base_res);
3485 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3487 x0 wave_length = 2
3489 y0 * * * * *
3490 |* * * * * * * * *
3491 wave_height = 3 | * * * *
3494 static void
3495 x_draw_underwave (struct glyph_string *s)
3497 /* Adjust for scale/HiDPI. */
3498 int scale_x, scale_y;
3500 x_get_scale_factor (s->display, &scale_x, &scale_y);
3502 int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
3504 #ifdef USE_CAIRO
3505 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3506 s->width, wave_height, wave_length);
3507 #else /* not USE_CAIRO */
3508 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
3509 bool odd;
3510 XRectangle wave_clip, string_clip, final_clip;
3512 dx = wave_length;
3513 dy = wave_height - 1;
3514 x0 = s->x;
3515 y0 = s->ybase + wave_height / 2 - scale_y;
3516 width = s->width;
3517 xmax = x0 + width;
3519 /* Find and set clipping rectangle */
3521 wave_clip.x = x0;
3522 wave_clip.y = y0;
3523 wave_clip.width = width;
3524 wave_clip.height = wave_height;
3525 get_glyph_string_clip_rect (s, &string_clip);
3527 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3528 return;
3530 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3532 /* Draw the waves */
3534 x1 = x0 - (x0 % dx);
3535 x2 = x1 + dx;
3536 odd = (x1 / dx) & 1;
3537 y1 = y2 = y0;
3539 if (odd)
3540 y1 += dy;
3541 else
3542 y2 += dy;
3544 if (INT_MAX - dx < xmax)
3545 emacs_abort ();
3547 while (x1 <= xmax)
3549 XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt,
3550 JoinRound);
3551 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3552 x1 = x2, y1 = y2;
3553 x2 += dx, y2 = y0 + odd*dy;
3554 odd = !odd;
3557 /* Restore previous clipping rectangle(s) */
3558 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3559 #endif /* not USE_CAIRO */
3563 /* Draw glyph string S. */
3565 static void
3566 x_draw_glyph_string (struct glyph_string *s)
3568 bool relief_drawn_p = false;
3570 /* If S draws into the background of its successors, draw the
3571 background of the successors first so that S can draw into it.
3572 This makes S->next use XDrawString instead of XDrawImageString. */
3573 if (s->next && s->right_overhang && !s->for_overlaps)
3575 int width;
3576 struct glyph_string *next;
3578 for (width = 0, next = s->next;
3579 next && width < s->right_overhang;
3580 width += next->width, next = next->next)
3581 if (next->first_glyph->type != IMAGE_GLYPH)
3583 x_set_glyph_string_gc (next);
3584 x_set_glyph_string_clipping (next);
3585 if (next->first_glyph->type == STRETCH_GLYPH)
3586 x_draw_stretch_glyph_string (next);
3587 else
3588 x_draw_glyph_string_background (next, true);
3589 next->num_clips = 0;
3593 /* Set up S->gc, set clipping and draw S. */
3594 x_set_glyph_string_gc (s);
3596 /* Draw relief (if any) in advance for char/composition so that the
3597 glyph string can be drawn over it. */
3598 if (!s->for_overlaps
3599 && s->face->box != FACE_NO_BOX
3600 && (s->first_glyph->type == CHAR_GLYPH
3601 || s->first_glyph->type == COMPOSITE_GLYPH))
3604 x_set_glyph_string_clipping (s);
3605 x_draw_glyph_string_background (s, true);
3606 x_draw_glyph_string_box (s);
3607 x_set_glyph_string_clipping (s);
3608 relief_drawn_p = true;
3610 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3611 && !s->clip_tail
3612 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3613 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3614 /* We must clip just this glyph. left_overhang part has already
3615 drawn when s->prev was drawn, and right_overhang part will be
3616 drawn later when s->next is drawn. */
3617 x_set_glyph_string_clipping_exactly (s, s);
3618 else
3619 x_set_glyph_string_clipping (s);
3621 switch (s->first_glyph->type)
3623 case IMAGE_GLYPH:
3624 x_draw_image_glyph_string (s);
3625 break;
3627 case XWIDGET_GLYPH:
3628 x_draw_xwidget_glyph_string (s);
3629 break;
3631 case STRETCH_GLYPH:
3632 x_draw_stretch_glyph_string (s);
3633 break;
3635 case CHAR_GLYPH:
3636 if (s->for_overlaps)
3637 s->background_filled_p = true;
3638 else
3639 x_draw_glyph_string_background (s, false);
3640 x_draw_glyph_string_foreground (s);
3641 break;
3643 case COMPOSITE_GLYPH:
3644 if (s->for_overlaps || (s->cmp_from > 0
3645 && ! s->first_glyph->u.cmp.automatic))
3646 s->background_filled_p = true;
3647 else
3648 x_draw_glyph_string_background (s, true);
3649 x_draw_composite_glyph_string_foreground (s);
3650 break;
3652 case GLYPHLESS_GLYPH:
3653 if (s->for_overlaps)
3654 s->background_filled_p = true;
3655 else
3656 x_draw_glyph_string_background (s, true);
3657 x_draw_glyphless_glyph_string_foreground (s);
3658 break;
3660 default:
3661 emacs_abort ();
3664 if (!s->for_overlaps)
3666 /* Draw underline. */
3667 if (s->face->underline_p)
3669 if (s->face->underline_type == FACE_UNDER_WAVE)
3671 if (s->face->underline_defaulted_p)
3672 x_draw_underwave (s);
3673 else
3675 XGCValues xgcv;
3676 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3677 XSetForeground (s->display, s->gc, s->face->underline_color);
3678 x_draw_underwave (s);
3679 XSetForeground (s->display, s->gc, xgcv.foreground);
3682 else if (s->face->underline_type == FACE_UNDER_LINE)
3684 unsigned long thickness, position;
3685 int y;
3687 if (s->prev && s->prev->face->underline_p
3688 && s->prev->face->underline_type == FACE_UNDER_LINE)
3690 /* We use the same underline style as the previous one. */
3691 thickness = s->prev->underline_thickness;
3692 position = s->prev->underline_position;
3694 else
3696 struct font *font = font_for_underline_metrics (s);
3697 unsigned long minimum_offset;
3698 bool underline_at_descent_line;
3699 bool use_underline_position_properties;
3700 Lisp_Object val
3701 = buffer_local_value (Qunderline_minimum_offset,
3702 s->w->contents);
3703 if (INTEGERP (val))
3704 minimum_offset = XFASTINT (val);
3705 else
3706 minimum_offset = 1;
3707 val = buffer_local_value (Qx_underline_at_descent_line,
3708 s->w->contents);
3709 underline_at_descent_line
3710 = !(NILP (val) || EQ (val, Qunbound));
3712 = buffer_local_value (Qx_use_underline_position_properties,
3713 s->w->contents);
3714 use_underline_position_properties
3715 = !(NILP (val) || EQ (val, Qunbound));
3717 /* Get the underline thickness. Default is 1 pixel. */
3718 if (font && font->underline_thickness > 0)
3719 thickness = font->underline_thickness;
3720 else
3721 thickness = 1;
3722 if (underline_at_descent_line)
3723 position = (s->height - thickness) - (s->ybase - s->y);
3724 else
3726 /* Get the underline position. This is the
3727 recommended vertical offset in pixels from
3728 the baseline to the top of the underline.
3729 This is a signed value according to the
3730 specs, and its default is
3732 ROUND ((maximum descent) / 2), with
3733 ROUND(x) = floor (x + 0.5) */
3735 if (use_underline_position_properties
3736 && font && font->underline_position >= 0)
3737 position = font->underline_position;
3738 else if (font)
3739 position = (font->descent + 1) / 2;
3740 else
3741 position = minimum_offset;
3743 position = max (position, minimum_offset);
3745 /* Check the sanity of thickness and position. We should
3746 avoid drawing underline out of the current line area. */
3747 if (s->y + s->height <= s->ybase + position)
3748 position = (s->height - 1) - (s->ybase - s->y);
3749 if (s->y + s->height < s->ybase + position + thickness)
3750 thickness = (s->y + s->height) - (s->ybase + position);
3751 s->underline_thickness = thickness;
3752 s->underline_position = position;
3753 y = s->ybase + position;
3754 if (s->face->underline_defaulted_p)
3755 x_fill_rectangle (s->f, s->gc,
3756 s->x, y, s->width, thickness);
3757 else
3759 XGCValues xgcv;
3760 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3761 XSetForeground (s->display, s->gc, s->face->underline_color);
3762 x_fill_rectangle (s->f, s->gc,
3763 s->x, y, s->width, thickness);
3764 XSetForeground (s->display, s->gc, xgcv.foreground);
3768 /* Draw overline. */
3769 if (s->face->overline_p)
3771 unsigned long dy = 0, h = 1;
3773 if (s->face->overline_color_defaulted_p)
3774 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3775 s->width, h);
3776 else
3778 XGCValues xgcv;
3779 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3780 XSetForeground (s->display, s->gc, s->face->overline_color);
3781 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3782 s->width, h);
3783 XSetForeground (s->display, s->gc, xgcv.foreground);
3787 /* Draw strike-through. */
3788 if (s->face->strike_through_p)
3790 /* Y-coordinate and height of the glyph string's first
3791 glyph. We cannot use s->y and s->height because those
3792 could be larger if there are taller display elements
3793 (e.g., characters displayed with a larger font) in the
3794 same glyph row. */
3795 int glyph_y = s->ybase - s->first_glyph->ascent;
3796 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3797 /* Strike-through width and offset from the glyph string's
3798 top edge. */
3799 unsigned long h = 1;
3800 unsigned long dy = (glyph_height - h) / 2;
3802 if (s->face->strike_through_color_defaulted_p)
3803 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3804 s->width, h);
3805 else
3807 XGCValues xgcv;
3808 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3809 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3810 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3811 s->width, h);
3812 XSetForeground (s->display, s->gc, xgcv.foreground);
3816 /* Draw relief if not yet drawn. */
3817 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3818 x_draw_glyph_string_box (s);
3820 if (s->prev)
3822 struct glyph_string *prev;
3824 for (prev = s->prev; prev; prev = prev->prev)
3825 if (prev->hl != s->hl
3826 && prev->x + prev->width + prev->right_overhang > s->x)
3828 /* As prev was drawn while clipped to its own area, we
3829 must draw the right_overhang part using s->hl now. */
3830 enum draw_glyphs_face save = prev->hl;
3832 prev->hl = s->hl;
3833 x_set_glyph_string_gc (prev);
3834 x_set_glyph_string_clipping_exactly (s, prev);
3835 if (prev->first_glyph->type == CHAR_GLYPH)
3836 x_draw_glyph_string_foreground (prev);
3837 else
3838 x_draw_composite_glyph_string_foreground (prev);
3839 x_reset_clip_rectangles (prev->f, prev->gc);
3840 prev->hl = save;
3841 prev->num_clips = 0;
3845 if (s->next)
3847 struct glyph_string *next;
3849 for (next = s->next; next; next = next->next)
3850 if (next->hl != s->hl
3851 && next->x - next->left_overhang < s->x + s->width)
3853 /* As next will be drawn while clipped to its own area,
3854 we must draw the left_overhang part using s->hl now. */
3855 enum draw_glyphs_face save = next->hl;
3857 next->hl = s->hl;
3858 x_set_glyph_string_gc (next);
3859 x_set_glyph_string_clipping_exactly (s, next);
3860 if (next->first_glyph->type == CHAR_GLYPH)
3861 x_draw_glyph_string_foreground (next);
3862 else
3863 x_draw_composite_glyph_string_foreground (next);
3864 x_reset_clip_rectangles (next->f, next->gc);
3865 next->hl = save;
3866 next->num_clips = 0;
3867 next->clip_head = s->next;
3872 /* Reset clipping. */
3873 x_reset_clip_rectangles (s->f, s->gc);
3874 s->num_clips = 0;
3877 /* Shift display to make room for inserted glyphs. */
3879 static void
3880 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3882 /* Never called on a GUI frame, see
3883 https://lists.gnu.org/r/emacs-devel/2015-05/msg00456.html
3885 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3886 f->output_data.x->normal_gc,
3887 x, y, width, height,
3888 x + shift_by, y);
3891 /* Delete N glyphs at the nominal cursor position. Not implemented
3892 for X frames. */
3894 static void
3895 x_delete_glyphs (struct frame *f, register int n)
3897 emacs_abort ();
3901 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3902 If they are <= 0, this is probably an error. */
3904 static ATTRIBUTE_UNUSED void
3905 x_clear_area1 (Display *dpy, Window window,
3906 int x, int y, int width, int height, int exposures)
3908 eassert (width > 0 && height > 0);
3909 XClearArea (dpy, window, x, y, width, height, exposures);
3912 void
3913 x_clear_area (struct frame *f, int x, int y, int width, int height)
3915 #ifdef USE_CAIRO
3916 cairo_t *cr;
3918 eassert (width > 0 && height > 0);
3920 cr = x_begin_cr_clip (f, NULL);
3921 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3922 cairo_rectangle (cr, x, y, width, height);
3923 cairo_fill (cr);
3924 x_end_cr_clip (f);
3925 #else
3926 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3927 XFillRectangle (FRAME_X_DISPLAY (f),
3928 FRAME_X_DRAWABLE (f),
3929 f->output_data.x->reverse_gc,
3930 x, y, width, height);
3931 else
3932 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3933 x, y, width, height, False);
3934 #endif
3938 /* Clear an entire frame. */
3940 static void
3941 x_clear_frame (struct frame *f)
3943 /* Clearing the frame will erase any cursor, so mark them all as no
3944 longer visible. */
3945 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3947 block_input ();
3949 font_drop_xrender_surfaces (f);
3950 x_clear_window (f);
3952 /* We have to clear the scroll bars. If we have changed colors or
3953 something like that, then they should be notified. */
3954 x_scroll_bar_clear (f);
3956 XFlush (FRAME_X_DISPLAY (f));
3958 unblock_input ();
3961 /* RIF: Show hourglass cursor on frame F. */
3963 static void
3964 x_show_hourglass (struct frame *f)
3966 Display *dpy = FRAME_X_DISPLAY (f);
3968 if (dpy)
3970 struct x_output *x = FRAME_X_OUTPUT (f);
3971 #ifdef USE_X_TOOLKIT
3972 if (x->widget)
3973 #else
3974 if (FRAME_OUTER_WINDOW (f))
3975 #endif
3977 x->hourglass_p = true;
3979 if (!x->hourglass_window)
3981 unsigned long mask = CWCursor;
3982 XSetWindowAttributes attrs;
3983 #ifdef USE_GTK
3984 Window parent = FRAME_X_WINDOW (f);
3985 #else
3986 Window parent = FRAME_OUTER_WINDOW (f);
3987 #endif
3988 attrs.cursor = x->hourglass_cursor;
3990 x->hourglass_window = XCreateWindow
3991 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3992 InputOnly, CopyFromParent, mask, &attrs);
3995 XMapRaised (dpy, x->hourglass_window);
3996 XFlush (dpy);
4001 /* RIF: Cancel hourglass cursor on frame F. */
4003 static void
4004 x_hide_hourglass (struct frame *f)
4006 struct x_output *x = FRAME_X_OUTPUT (f);
4008 /* Watch out for newly created frames. */
4009 if (x->hourglass_window)
4011 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
4012 /* Sync here because XTread_socket looks at the
4013 hourglass_p flag that is reset to zero below. */
4014 XSync (FRAME_X_DISPLAY (f), False);
4015 x->hourglass_p = false;
4019 /* Invert the middle quarter of the frame for .15 sec. */
4021 static void
4022 XTflash (struct frame *f)
4024 block_input ();
4027 #ifdef USE_GTK
4028 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
4029 when the scroll bars and the edit widget share the same X window. */
4030 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4031 #ifdef HAVE_GTK3
4032 #if GTK_CHECK_VERSION (3, 22, 0)
4033 cairo_region_t *region = gdk_window_get_visible_region (window);
4034 GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
4035 cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
4036 #else
4037 cairo_t *cr = gdk_cairo_create (window);
4038 #endif
4039 cairo_set_source_rgb (cr, 1, 1, 1);
4040 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4041 #define XFillRectangle(d, win, gc, x, y, w, h) \
4042 do { \
4043 cairo_rectangle (cr, x, y, w, h); \
4044 cairo_fill (cr); \
4046 while (false)
4047 #else /* ! HAVE_GTK3 */
4048 GdkGCValues vals;
4049 GdkGC *gc;
4050 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4051 ^ FRAME_BACKGROUND_PIXEL (f));
4052 vals.function = GDK_XOR;
4053 gc = gdk_gc_new_with_values (window,
4054 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4055 #define XFillRectangle(d, win, gc, x, y, w, h) \
4056 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4057 #endif /* ! HAVE_GTK3 */
4058 #else /* ! USE_GTK */
4059 GC gc;
4061 /* Create a GC that will use the GXxor function to flip foreground
4062 pixels into background pixels. */
4064 XGCValues values;
4066 values.function = GXxor;
4067 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
4068 ^ FRAME_BACKGROUND_PIXEL (f));
4070 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4071 GCFunction | GCForeground, &values);
4073 #endif
4075 /* Get the height not including a menu bar widget. */
4076 int height = FRAME_PIXEL_HEIGHT (f);
4077 /* Height of each line to flash. */
4078 int flash_height = FRAME_LINE_HEIGHT (f);
4079 /* These will be the left and right margins of the rectangles. */
4080 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4081 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4082 int width = flash_right - flash_left;
4084 /* If window is tall, flash top and bottom line. */
4085 if (height > 3 * FRAME_LINE_HEIGHT (f))
4087 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4088 flash_left,
4089 (FRAME_INTERNAL_BORDER_WIDTH (f)
4090 + FRAME_TOP_MARGIN_HEIGHT (f)),
4091 width, flash_height);
4092 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4093 flash_left,
4094 (height - flash_height
4095 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4096 width, flash_height);
4099 else
4100 /* If it is short, flash it all. */
4101 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4102 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4103 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4105 x_flush (f);
4108 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4109 struct timespec wakeup = timespec_add (current_timespec (), delay);
4111 /* Keep waiting until past the time wakeup or any input gets
4112 available. */
4113 while (! detect_input_pending ())
4115 struct timespec current = current_timespec ();
4116 struct timespec timeout;
4118 /* Break if result would not be positive. */
4119 if (timespec_cmp (wakeup, current) <= 0)
4120 break;
4122 /* How long `select' should wait. */
4123 timeout = make_timespec (0, 10 * 1000 * 1000);
4125 /* Try to wait that long--but we might wake up sooner. */
4126 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4130 /* If window is tall, flash top and bottom line. */
4131 if (height > 3 * FRAME_LINE_HEIGHT (f))
4133 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4134 flash_left,
4135 (FRAME_INTERNAL_BORDER_WIDTH (f)
4136 + FRAME_TOP_MARGIN_HEIGHT (f)),
4137 width, flash_height);
4138 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4139 flash_left,
4140 (height - flash_height
4141 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4142 width, flash_height);
4144 else
4145 /* If it is short, flash it all. */
4146 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4147 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4148 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4150 #ifdef USE_GTK
4151 #ifdef HAVE_GTK3
4152 #if GTK_CHECK_VERSION (3, 22, 0)
4153 gdk_window_end_draw_frame (window, context);
4154 cairo_region_destroy (region);
4155 #else
4156 cairo_destroy (cr);
4157 #endif
4158 #else
4159 g_object_unref (G_OBJECT (gc));
4160 #endif
4161 #undef XFillRectangle
4162 #else
4163 XFreeGC (FRAME_X_DISPLAY (f), gc);
4164 #endif
4165 x_flush (f);
4169 unblock_input ();
4173 static void
4174 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4176 block_input ();
4177 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4178 unblock_input ();
4182 /* Make audible bell. */
4184 static void
4185 XTring_bell (struct frame *f)
4187 if (FRAME_X_DISPLAY (f))
4189 if (visible_bell)
4190 XTflash (f);
4191 else
4193 block_input ();
4194 #ifdef HAVE_XKB
4195 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4196 #else
4197 XBell (FRAME_X_DISPLAY (f), 0);
4198 #endif
4199 XFlush (FRAME_X_DISPLAY (f));
4200 unblock_input ();
4205 /***********************************************************************
4206 Line Dance
4207 ***********************************************************************/
4209 /* Perform an insert-lines or delete-lines operation, inserting N
4210 lines or deleting -N lines at vertical position VPOS. */
4212 static void
4213 x_ins_del_lines (struct frame *f, int vpos, int n)
4215 emacs_abort ();
4219 /* Scroll part of the display as described by RUN. */
4221 static void
4222 x_scroll_run (struct window *w, struct run *run)
4224 struct frame *f = XFRAME (w->frame);
4225 int x, y, width, height, from_y, to_y, bottom_y;
4227 /* Get frame-relative bounding box of the text display area of W,
4228 without mode lines. Include in this box the left and right
4229 fringe of W. */
4230 window_box (w, ANY_AREA, &x, &y, &width, &height);
4232 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4233 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4234 bottom_y = y + height;
4236 if (to_y < from_y)
4238 /* Scrolling up. Make sure we don't copy part of the mode
4239 line at the bottom. */
4240 if (from_y + run->height > bottom_y)
4241 height = bottom_y - from_y;
4242 else
4243 height = run->height;
4245 else
4247 /* Scrolling down. Make sure we don't copy over the mode line.
4248 at the bottom. */
4249 if (to_y + run->height > bottom_y)
4250 height = bottom_y - to_y;
4251 else
4252 height = run->height;
4255 block_input ();
4257 /* Cursor off. Will be switched on again in x_update_window_end. */
4258 x_clear_cursor (w);
4260 #ifdef USE_CAIRO
4261 if (FRAME_CR_CONTEXT (f))
4263 int wx = WINDOW_LEFT_EDGE_X (w);
4264 cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
4265 width, height);
4266 cairo_t *cr = cairo_create (s);
4267 cairo_set_source_surface (cr, cairo_get_target (FRAME_CR_CONTEXT (f)),
4268 -x, -from_y);
4269 cairo_paint (cr);
4270 cairo_destroy (cr);
4272 cr = FRAME_CR_CONTEXT (f);
4273 cairo_save (cr);
4274 cairo_set_source_surface (cr, s, wx, to_y);
4275 cairo_rectangle (cr, wx, to_y, width, height);
4276 cairo_fill (cr);
4277 cairo_restore (cr);
4278 cairo_surface_destroy (s);
4280 else
4282 SET_FRAME_GARBAGED (f);
4284 #else
4285 XCopyArea (FRAME_X_DISPLAY (f),
4286 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4287 f->output_data.x->normal_gc,
4288 x, from_y,
4289 width, height,
4290 x, to_y);
4291 #endif
4293 unblock_input ();
4298 /***********************************************************************
4299 Exposure Events
4300 ***********************************************************************/
4303 static void
4304 frame_highlight (struct frame *f)
4306 /* We used to only do this if Vx_no_window_manager was non-nil, but
4307 the ICCCM (section 4.1.6) says that the window's border pixmap
4308 and border pixel are window attributes which are "private to the
4309 client", so we can always change it to whatever we want. */
4310 block_input ();
4311 /* I recently started to get errors in this XSetWindowBorder, depending on
4312 the window-manager in use, tho something more is at play since I've been
4313 using that same window-manager binary for ever. Let's not crash just
4314 because of this (bug#9310). */
4315 x_catch_errors (FRAME_X_DISPLAY (f));
4316 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4317 f->output_data.x->border_pixel);
4318 x_uncatch_errors ();
4319 unblock_input ();
4320 x_update_cursor (f, true);
4321 x_set_frame_alpha (f);
4324 static void
4325 frame_unhighlight (struct frame *f)
4327 /* We used to only do this if Vx_no_window_manager was non-nil, but
4328 the ICCCM (section 4.1.6) says that the window's border pixmap
4329 and border pixel are window attributes which are "private to the
4330 client", so we can always change it to whatever we want. */
4331 block_input ();
4332 /* Same as above for XSetWindowBorder (bug#9310). */
4333 x_catch_errors (FRAME_X_DISPLAY (f));
4334 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4335 f->output_data.x->border_tile);
4336 x_uncatch_errors ();
4337 unblock_input ();
4338 x_update_cursor (f, true);
4339 x_set_frame_alpha (f);
4342 /* The focus has changed. Update the frames as necessary to reflect
4343 the new situation. Note that we can't change the selected frame
4344 here, because the Lisp code we are interrupting might become confused.
4345 Each event gets marked with the frame in which it occurred, so the
4346 Lisp code can tell when the switch took place by examining the events. */
4348 static void
4349 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4351 struct frame *old_focus = dpyinfo->x_focus_frame;
4353 if (frame != dpyinfo->x_focus_frame)
4355 /* Set this before calling other routines, so that they see
4356 the correct value of x_focus_frame. */
4357 dpyinfo->x_focus_frame = frame;
4359 if (old_focus && old_focus->auto_lower)
4360 x_lower_frame (old_focus);
4362 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4363 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4364 else
4365 dpyinfo->x_pending_autoraise_frame = NULL;
4368 x_frame_rehighlight (dpyinfo);
4371 /* Handle FocusIn and FocusOut state changes for FRAME.
4372 If FRAME has focus and there exists more than one frame, puts
4373 a FOCUS_IN_EVENT into *BUFP. */
4375 static void
4376 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4378 if (type == FocusIn)
4380 if (dpyinfo->x_focus_event_frame != frame)
4382 x_new_focus_frame (dpyinfo, frame);
4383 dpyinfo->x_focus_event_frame = frame;
4385 /* Don't stop displaying the initial startup message
4386 for a switch-frame event we don't need. */
4387 /* When run as a daemon, Vterminal_frame is always NIL. */
4388 bufp->arg = (((NILP (Vterminal_frame)
4389 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4390 || EQ (Fdaemonp (), Qt))
4391 && CONSP (Vframe_list)
4392 && !NILP (XCDR (Vframe_list)))
4393 ? Qt : Qnil);
4394 bufp->kind = FOCUS_IN_EVENT;
4395 XSETFRAME (bufp->frame_or_window, frame);
4398 frame->output_data.x->focus_state |= state;
4400 #ifdef HAVE_X_I18N
4401 if (FRAME_XIC (frame))
4402 XSetICFocus (FRAME_XIC (frame));
4403 #endif
4405 else if (type == FocusOut)
4407 frame->output_data.x->focus_state &= ~state;
4409 if (dpyinfo->x_focus_event_frame == frame)
4411 dpyinfo->x_focus_event_frame = 0;
4412 x_new_focus_frame (dpyinfo, 0);
4414 bufp->kind = FOCUS_OUT_EVENT;
4415 XSETFRAME (bufp->frame_or_window, frame);
4418 #ifdef HAVE_X_I18N
4419 if (FRAME_XIC (frame))
4420 XUnsetICFocus (FRAME_XIC (frame));
4421 #endif
4422 if (frame->pointer_invisible)
4423 XTtoggle_invisible_pointer (frame, false);
4427 /* Return the Emacs frame-object corresponding to an X window.
4428 It could be the frame's main window or an icon window. */
4430 static struct frame *
4431 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4433 Lisp_Object tail, frame;
4434 struct frame *f;
4436 if (wdesc == None)
4437 return NULL;
4439 FOR_EACH_FRAME (tail, frame)
4441 f = XFRAME (frame);
4442 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4443 continue;
4444 if (f->output_data.x->hourglass_window == wdesc)
4445 return f;
4446 #ifdef USE_X_TOOLKIT
4447 if ((f->output_data.x->edit_widget
4448 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4449 /* A tooltip frame? */
4450 || (!f->output_data.x->edit_widget
4451 && FRAME_X_WINDOW (f) == wdesc)
4452 || f->output_data.x->icon_desc == wdesc)
4453 return f;
4454 #else /* not USE_X_TOOLKIT */
4455 #ifdef USE_GTK
4456 if (f->output_data.x->edit_widget)
4458 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4459 struct x_output *x = f->output_data.x;
4460 if (gwdesc != 0 && gwdesc == x->edit_widget)
4461 return f;
4463 #endif /* USE_GTK */
4464 if (FRAME_X_WINDOW (f) == wdesc
4465 || f->output_data.x->icon_desc == wdesc)
4466 return f;
4467 #endif /* not USE_X_TOOLKIT */
4469 return 0;
4472 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4474 /* Like x_window_to_frame but also compares the window with the widget's
4475 windows. */
4477 static struct frame *
4478 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4480 Lisp_Object tail, frame;
4481 struct frame *f, *found = NULL;
4482 struct x_output *x;
4484 if (wdesc == None)
4485 return NULL;
4487 FOR_EACH_FRAME (tail, frame)
4489 if (found)
4490 break;
4491 f = XFRAME (frame);
4492 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4494 /* This frame matches if the window is any of its widgets. */
4495 x = f->output_data.x;
4496 if (x->hourglass_window == wdesc)
4497 found = f;
4498 else if (x->widget)
4500 #ifdef USE_GTK
4501 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4502 if (gwdesc != 0
4503 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4504 found = f;
4505 #else
4506 if (wdesc == XtWindow (x->widget)
4507 || wdesc == XtWindow (x->column_widget)
4508 || wdesc == XtWindow (x->edit_widget))
4509 found = f;
4510 /* Match if the window is this frame's menubar. */
4511 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4512 found = f;
4513 #endif
4515 else if (FRAME_X_WINDOW (f) == wdesc)
4516 /* A tooltip frame. */
4517 found = f;
4521 return found;
4524 /* Likewise, but consider only the menu bar widget. */
4526 static struct frame *
4527 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4528 const XEvent *event)
4530 Window wdesc = event->xany.window;
4531 Lisp_Object tail, frame;
4532 struct frame *f;
4533 struct x_output *x;
4535 if (wdesc == None)
4536 return NULL;
4538 FOR_EACH_FRAME (tail, frame)
4540 f = XFRAME (frame);
4541 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4542 continue;
4543 x = f->output_data.x;
4544 #ifdef USE_GTK
4545 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4546 return f;
4547 #else
4548 /* Match if the window is this frame's menubar. */
4549 if (x->menubar_widget
4550 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4551 return f;
4552 #endif
4554 return 0;
4557 /* Return the frame whose principal (outermost) window is WDESC.
4558 If WDESC is some other (smaller) window, we return 0. */
4560 struct frame *
4561 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4563 Lisp_Object tail, frame;
4564 struct frame *f;
4565 struct x_output *x;
4567 if (wdesc == None)
4568 return NULL;
4570 FOR_EACH_FRAME (tail, frame)
4572 f = XFRAME (frame);
4573 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4574 continue;
4575 x = f->output_data.x;
4577 if (x->widget)
4579 /* This frame matches if the window is its topmost widget. */
4580 #ifdef USE_GTK
4581 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4582 if (gwdesc == x->widget)
4583 return f;
4584 #else
4585 if (wdesc == XtWindow (x->widget))
4586 return f;
4587 #endif
4589 else if (FRAME_X_WINDOW (f) == wdesc)
4590 /* Tooltip frame. */
4591 return f;
4593 return 0;
4596 #else /* !USE_X_TOOLKIT && !USE_GTK */
4598 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4599 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4601 #endif /* USE_X_TOOLKIT || USE_GTK */
4603 /* The focus may have changed. Figure out if it is a real focus change,
4604 by checking both FocusIn/Out and Enter/LeaveNotify events.
4606 Returns FOCUS_IN_EVENT event in *BUFP. */
4608 static void
4609 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4610 const XEvent *event, struct input_event *bufp)
4612 if (!frame)
4613 return;
4615 switch (event->type)
4617 case EnterNotify:
4618 case LeaveNotify:
4620 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4621 int focus_state
4622 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4624 if (event->xcrossing.detail != NotifyInferior
4625 && event->xcrossing.focus
4626 && ! (focus_state & FOCUS_EXPLICIT))
4627 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4628 FOCUS_IMPLICIT,
4629 dpyinfo, frame, bufp);
4631 break;
4633 case FocusIn:
4634 case FocusOut:
4635 x_focus_changed (event->type,
4636 (event->xfocus.detail == NotifyPointer ?
4637 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4638 dpyinfo, frame, bufp);
4639 break;
4641 case ClientMessage:
4642 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4644 enum xembed_message msg = event->xclient.data.l[1];
4645 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4646 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4648 break;
4653 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4654 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4656 void
4657 x_mouse_leave (struct x_display_info *dpyinfo)
4659 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4661 #endif
4663 /* The focus has changed, or we have redirected a frame's focus to
4664 another frame (this happens when a frame uses a surrogate
4665 mini-buffer frame). Shift the highlight as appropriate.
4667 The FRAME argument doesn't necessarily have anything to do with which
4668 frame is being highlighted or un-highlighted; we only use it to find
4669 the appropriate X display info. */
4671 static void
4672 XTframe_rehighlight (struct frame *frame)
4674 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4677 static void
4678 x_frame_rehighlight (struct x_display_info *dpyinfo)
4680 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4682 if (dpyinfo->x_focus_frame)
4684 dpyinfo->x_highlight_frame
4685 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4686 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4687 : dpyinfo->x_focus_frame);
4688 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4690 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4691 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4694 else
4695 dpyinfo->x_highlight_frame = 0;
4697 if (dpyinfo->x_highlight_frame != old_highlight)
4699 if (old_highlight)
4700 frame_unhighlight (old_highlight);
4701 if (dpyinfo->x_highlight_frame)
4702 frame_highlight (dpyinfo->x_highlight_frame);
4708 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4710 /* Initialize mode_switch_bit and modifier_meaning. */
4711 static void
4712 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4714 int min_code, max_code;
4715 KeySym *syms;
4716 int syms_per_code;
4717 XModifierKeymap *mods;
4719 dpyinfo->meta_mod_mask = 0;
4720 dpyinfo->shift_lock_mask = 0;
4721 dpyinfo->alt_mod_mask = 0;
4722 dpyinfo->super_mod_mask = 0;
4723 dpyinfo->hyper_mod_mask = 0;
4725 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4727 syms = XGetKeyboardMapping (dpyinfo->display,
4728 min_code, max_code - min_code + 1,
4729 &syms_per_code);
4730 mods = XGetModifierMapping (dpyinfo->display);
4732 /* Scan the modifier table to see which modifier bits the Meta and
4733 Alt keysyms are on. */
4735 int row, col; /* The row and column in the modifier table. */
4736 bool found_alt_or_meta;
4738 for (row = 3; row < 8; row++)
4740 found_alt_or_meta = false;
4741 for (col = 0; col < mods->max_keypermod; col++)
4743 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4745 /* Zeroes are used for filler. Skip them. */
4746 if (code == 0)
4747 continue;
4749 /* Are any of this keycode's keysyms a meta key? */
4751 int code_col;