Fix a comment whitespace typo.
[emacs.git] / src / xterm.c
blob77daa22ae0d59e130385f01bdfb6e4a4df868417
1 /* X Communication module for terminals which understand the X protocol.
3 Copyright (C) 1989, 1993-2017 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
21 /* Xt features made by Fred Pierresteguy. */
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <math.h>
28 #include "lisp.h"
29 #include "blockinput.h"
31 /* This may include sys/types.h, and that somehow loses
32 if this is not done before the other system files. */
33 #include "xterm.h"
34 #include <X11/cursorfont.h>
36 /* If we have Xfixes extension, use it for pointer blanking. */
37 #ifdef HAVE_XFIXES
38 #include <X11/extensions/Xfixes.h>
39 #endif
41 /* Using Xft implies that XRender is available. */
42 #ifdef HAVE_XFT
43 #include <X11/extensions/Xrender.h>
44 #endif
46 #ifdef HAVE_XDBE
47 #include <X11/extensions/Xdbe.h>
48 #endif
50 /* Load sys/types.h if not already loaded.
51 In some systems loading it twice is suicidal. */
52 #ifndef makedev
53 #include <sys/types.h>
54 #endif /* makedev */
56 #include <sys/ioctl.h>
58 #include "systime.h"
60 #include <fcntl.h>
61 #include <errno.h>
62 #include <sys/stat.h>
63 #include "character.h"
64 #include "coding.h"
65 #include "composite.h"
66 #include "frame.h"
67 #include "dispextern.h"
68 #include "xwidget.h"
69 #include "fontset.h"
70 #include "termhooks.h"
71 #include "termopts.h"
72 #include "termchar.h"
73 #include "emacs-icon.h"
74 #include "buffer.h"
75 #include "window.h"
76 #include "keyboard.h"
77 #include "atimer.h"
78 #include "font.h"
79 #include "xsettings.h"
80 #include "sysselect.h"
81 #include "menu.h"
83 #ifdef USE_X_TOOLKIT
84 #include <X11/Shell.h>
85 #endif
87 #include <unistd.h>
89 #ifdef USE_GTK
90 #include "gtkutil.h"
91 #ifdef HAVE_GTK3
92 #include <X11/Xproto.h>
93 #endif
94 #endif
96 #if defined (USE_LUCID) || defined (USE_MOTIF)
97 #include "../lwlib/xlwmenu.h"
98 #endif
100 #ifdef USE_X_TOOLKIT
102 /* Include toolkit specific headers for the scroll bar widget. */
104 #ifdef USE_TOOLKIT_SCROLL_BARS
105 #if defined USE_MOTIF
106 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
107 #include <Xm/ScrollBar.h>
108 #else /* !USE_MOTIF i.e. use Xaw */
110 #ifdef HAVE_XAW3D
111 #include <X11/Xaw3d/Simple.h>
112 #include <X11/Xaw3d/Scrollbar.h>
113 #include <X11/Xaw3d/ThreeD.h>
114 #else /* !HAVE_XAW3D */
115 #include <X11/Xaw/Simple.h>
116 #include <X11/Xaw/Scrollbar.h>
117 #endif /* !HAVE_XAW3D */
118 #ifndef XtNpickTop
119 #define XtNpickTop "pickTop"
120 #endif /* !XtNpickTop */
121 #endif /* !USE_MOTIF */
122 #endif /* USE_TOOLKIT_SCROLL_BARS */
124 #endif /* USE_X_TOOLKIT */
126 #ifdef USE_X_TOOLKIT
127 #include "widget.h"
128 #ifndef XtNinitialState
129 #define XtNinitialState "initialState"
130 #endif
131 #endif
133 #include "bitmaps/gray.xbm"
135 #ifdef HAVE_XKB
136 #include <X11/XKBlib.h>
137 #endif
139 /* Default to using XIM if available. */
140 #ifdef USE_XIM
141 bool use_xim = true;
142 #else
143 bool use_xim = false; /* configure --without-xim */
144 #endif
146 /* Non-zero means that a HELP_EVENT has been generated since Emacs
147 start. */
149 static bool any_help_event_p;
151 /* This is a chain of structures for all the X displays currently in
152 use. */
154 struct x_display_info *x_display_list;
156 #ifdef USE_X_TOOLKIT
158 /* The application context for Xt use. */
159 XtAppContext Xt_app_con;
160 static String Xt_default_resources[] = {0};
162 /* Non-zero means user is interacting with a toolkit scroll bar. */
163 static bool toolkit_scroll_bar_interaction;
165 #endif /* USE_X_TOOLKIT */
167 /* Non-zero timeout value means ignore next mouse click if it arrives
168 before that timeout elapses (i.e. as part of the same sequence of
169 events resulting from clicking on a frame to select it). */
171 static Time ignore_next_mouse_click_timeout;
173 /* Used locally within XTread_socket. */
175 static int x_noop_count;
177 #ifdef USE_GTK
178 /* The name of the Emacs icon file. */
179 static Lisp_Object xg_default_icon_file;
180 #endif
182 /* Some functions take this as char *, not const char *. */
183 static char emacs_class[] = EMACS_CLASS;
185 enum xembed_info
187 XEMBED_MAPPED = 1 << 0
190 enum xembed_message
192 XEMBED_EMBEDDED_NOTIFY = 0,
193 XEMBED_WINDOW_ACTIVATE = 1,
194 XEMBED_WINDOW_DEACTIVATE = 2,
195 XEMBED_REQUEST_FOCUS = 3,
196 XEMBED_FOCUS_IN = 4,
197 XEMBED_FOCUS_OUT = 5,
198 XEMBED_FOCUS_NEXT = 6,
199 XEMBED_FOCUS_PREV = 7,
201 XEMBED_MODALITY_ON = 10,
202 XEMBED_MODALITY_OFF = 11,
203 XEMBED_REGISTER_ACCELERATOR = 12,
204 XEMBED_UNREGISTER_ACCELERATOR = 13,
205 XEMBED_ACTIVATE_ACCELERATOR = 14
208 static void x_free_cr_resources (struct frame *);
209 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
210 static void x_raise_frame (struct frame *);
211 static void x_lower_frame (struct frame *);
212 static int x_io_error_quitter (Display *);
213 static struct terminal *x_create_terminal (struct x_display_info *);
214 static void x_frame_rehighlight (struct x_display_info *);
216 static void x_clip_to_row (struct window *, struct glyph_row *,
217 enum glyph_row_area, GC);
218 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
219 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
220 enum scroll_bar_part *,
221 Lisp_Object *, Lisp_Object *,
222 Time *);
223 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
224 enum scroll_bar_part *,
225 Lisp_Object *, Lisp_Object *,
226 Time *);
227 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
228 static void x_check_fullscreen (struct frame *);
229 static void x_check_expected_move (struct frame *, int, int);
230 static void x_sync_with_move (struct frame *, int, int, bool);
231 static int handle_one_xevent (struct x_display_info *,
232 const XEvent *, int *,
233 struct input_event *);
234 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
235 static int x_dispatch_event (XEvent *, Display *);
236 #endif
237 static void x_wm_set_window_state (struct frame *, int);
238 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
239 static void x_initialize (void);
241 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
243 /* Flush display of frame F. */
245 static void
246 x_flush (struct frame *f)
248 eassert (f && FRAME_X_P (f));
249 /* Don't call XFlush when it is not safe to redisplay; the X
250 connection may be broken. */
251 if (!NILP (Vinhibit_redisplay))
252 return;
254 block_input ();
255 XFlush (FRAME_X_DISPLAY (f));
256 unblock_input ();
260 /* Remove calls to XFlush by defining XFlush to an empty replacement.
261 Calls to XFlush should be unnecessary because the X output buffer
262 is flushed automatically as needed by calls to XPending,
263 XNextEvent, or XWindowEvent according to the XFlush man page.
264 XTread_socket calls XPending. Removing XFlush improves
265 performance. */
267 #define XFlush(DISPLAY) (void) 0
270 /***********************************************************************
271 Debugging
272 ***********************************************************************/
274 #if false
276 /* This is a function useful for recording debugging information about
277 the sequence of occurrences in this file. */
279 struct record
281 char *locus;
282 int type;
285 struct record event_record[100];
287 int event_record_index;
289 void
290 record_event (char *locus, int type)
292 if (event_record_index == ARRAYELTS (event_record))
293 event_record_index = 0;
295 event_record[event_record_index].locus = locus;
296 event_record[event_record_index].type = type;
297 event_record_index++;
300 #endif
302 #ifdef USE_CAIRO
304 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
305 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
307 static struct x_gc_ext_data *
308 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
310 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
311 XEDataObject object;
312 XExtData **head, *ext_data;
314 object.gc = gc;
315 head = XEHeadOfExtensionList (object);
316 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
317 if (ext_data == NULL)
319 if (!create_if_not_found_p)
320 return NULL;
321 else
323 ext_data = xzalloc (sizeof (*ext_data));
324 ext_data->number = dpyinfo->ext_codes->extension;
325 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
326 XAddToExtensionList (head, ext_data);
329 return (struct x_gc_ext_data *) ext_data->private_data;
332 static void
333 x_extension_initialize (struct x_display_info *dpyinfo)
335 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
337 dpyinfo->ext_codes = ext_codes;
340 static void
341 x_cr_destroy_surface (struct frame *f)
343 if (FRAME_CR_SURFACE (f))
345 cairo_t *cr = FRAME_CR_CONTEXT (f);
346 cairo_surface_destroy (FRAME_CR_SURFACE (f));
347 FRAME_CR_SURFACE (f) = 0;
348 if (cr) cairo_destroy (cr);
349 FRAME_CR_CONTEXT (f) = NULL;
353 cairo_t *
354 x_begin_cr_clip (struct frame *f, GC gc)
356 cairo_t *cr = FRAME_CR_CONTEXT (f);
358 if (!cr)
361 if (! FRAME_CR_SURFACE (f))
363 cairo_surface_t *surface;
364 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
365 FRAME_X_DRAWABLE (f),
366 FRAME_DISPLAY_INFO (f)->visual,
367 FRAME_PIXEL_WIDTH (f),
368 FRAME_PIXEL_HEIGHT (f));
369 cr = cairo_create (surface);
370 cairo_surface_destroy (surface);
372 else
373 cr = cairo_create (FRAME_CR_SURFACE (f));
374 FRAME_CR_CONTEXT (f) = cr;
376 cairo_save (cr);
378 if (gc)
380 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
382 if (gc_ext && gc_ext->n_clip_rects)
384 int i;
386 for (i = 0; i < gc_ext->n_clip_rects; i++)
387 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
388 gc_ext->clip_rects[i].y,
389 gc_ext->clip_rects[i].width,
390 gc_ext->clip_rects[i].height);
391 cairo_clip (cr);
395 return cr;
398 void
399 x_end_cr_clip (struct frame *f)
401 cairo_restore (FRAME_CR_CONTEXT (f));
404 void
405 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
407 XGCValues xgcv;
408 XColor color;
410 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
411 color.pixel = xgcv.foreground;
412 x_query_color (f, &color);
413 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
414 color.green / 65535.0, color.blue / 65535.0);
417 void
418 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
420 XGCValues xgcv;
421 XColor color;
423 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
424 color.pixel = xgcv.background;
425 x_query_color (f, &color);
426 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
427 color.green / 65535.0, color.blue / 65535.0);
430 /* Fringe bitmaps. */
432 static int max_fringe_bmp = 0;
433 static cairo_pattern_t **fringe_bmp = 0;
435 static void
436 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
438 int i, stride;
439 cairo_surface_t *surface;
440 unsigned char *data;
441 cairo_pattern_t *pattern;
443 if (which >= max_fringe_bmp)
445 i = max_fringe_bmp;
446 max_fringe_bmp = which + 20;
447 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
448 while (i < max_fringe_bmp)
449 fringe_bmp[i++] = 0;
452 block_input ();
454 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
455 stride = cairo_image_surface_get_stride (surface);
456 data = cairo_image_surface_get_data (surface);
458 for (i = 0; i < h; i++)
460 *((unsigned short *) data) = bits[i];
461 data += stride;
464 cairo_surface_mark_dirty (surface);
465 pattern = cairo_pattern_create_for_surface (surface);
466 cairo_surface_destroy (surface);
468 unblock_input ();
470 fringe_bmp[which] = pattern;
473 static void
474 x_cr_destroy_fringe_bitmap (int which)
476 if (which >= max_fringe_bmp)
477 return;
479 if (fringe_bmp[which])
481 block_input ();
482 cairo_pattern_destroy (fringe_bmp[which]);
483 unblock_input ();
485 fringe_bmp[which] = 0;
488 static void
489 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
490 int src_x, int src_y, int width, int height,
491 int dest_x, int dest_y, bool overlay_p)
493 cairo_t *cr;
494 cairo_matrix_t matrix;
495 cairo_surface_t *surface;
496 cairo_format_t format;
498 cr = x_begin_cr_clip (f, gc);
499 if (overlay_p)
500 cairo_rectangle (cr, dest_x, dest_y, width, height);
501 else
503 x_set_cr_source_with_gc_background (f, gc);
504 cairo_rectangle (cr, dest_x, dest_y, width, height);
505 cairo_fill_preserve (cr);
507 cairo_clip (cr);
508 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
509 cairo_pattern_set_matrix (image, &matrix);
510 cairo_pattern_get_surface (image, &surface);
511 format = cairo_image_surface_get_format (surface);
512 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
514 cairo_set_source (cr, image);
515 cairo_fill (cr);
517 else
519 x_set_cr_source_with_gc_foreground (f, gc);
520 cairo_mask (cr, image);
522 x_end_cr_clip (f);
525 void
526 x_cr_draw_frame (cairo_t *cr, struct frame *f)
528 int width, height;
530 width = FRAME_PIXEL_WIDTH (f);
531 height = FRAME_PIXEL_HEIGHT (f);
533 x_free_cr_resources (f);
534 FRAME_CR_CONTEXT (f) = cr;
535 x_clear_area (f, 0, 0, width, height);
536 expose_frame (f, 0, 0, width, height);
537 FRAME_CR_CONTEXT (f) = NULL;
540 static cairo_status_t
541 x_cr_accumulate_data (void *closure, const unsigned char *data,
542 unsigned int length)
544 Lisp_Object *acc = (Lisp_Object *) closure;
546 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
548 return CAIRO_STATUS_SUCCESS;
551 static void
552 x_cr_destroy (Lisp_Object arg)
554 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
556 block_input ();
557 cairo_destroy (cr);
558 unblock_input ();
561 Lisp_Object
562 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
564 struct frame *f;
565 cairo_surface_t *surface;
566 cairo_t *cr;
567 int width, height;
568 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
569 Lisp_Object acc = Qnil;
570 ptrdiff_t count = SPECPDL_INDEX ();
572 specbind (Qredisplay_dont_pause, Qt);
573 redisplay_preserve_echo_area (31);
575 f = XFRAME (XCAR (frames));
576 frames = XCDR (frames);
577 width = FRAME_PIXEL_WIDTH (f);
578 height = FRAME_PIXEL_HEIGHT (f);
580 block_input ();
581 #ifdef CAIRO_HAS_PDF_SURFACE
582 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
584 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
585 width, height);
586 surface_set_size_func = cairo_pdf_surface_set_size;
588 else
589 #endif
590 #ifdef CAIRO_HAS_PNG_FUNCTIONS
591 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
592 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
593 else
594 #endif
595 #ifdef CAIRO_HAS_PS_SURFACE
596 if (surface_type == CAIRO_SURFACE_TYPE_PS)
598 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
599 width, height);
600 surface_set_size_func = cairo_ps_surface_set_size;
602 else
603 #endif
604 #ifdef CAIRO_HAS_SVG_SURFACE
605 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
606 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
607 width, height);
608 else
609 #endif
610 abort ();
612 cr = cairo_create (surface);
613 cairo_surface_destroy (surface);
614 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
616 while (1)
618 x_free_cr_resources (f);
619 FRAME_CR_CONTEXT (f) = cr;
620 x_clear_area (f, 0, 0, width, height);
621 expose_frame (f, 0, 0, width, height);
622 FRAME_CR_CONTEXT (f) = NULL;
624 if (NILP (frames))
625 break;
627 cairo_surface_show_page (surface);
628 f = XFRAME (XCAR (frames));
629 frames = XCDR (frames);
630 width = FRAME_PIXEL_WIDTH (f);
631 height = FRAME_PIXEL_HEIGHT (f);
632 if (surface_set_size_func)
633 (*surface_set_size_func) (surface, width, height);
635 unblock_input ();
636 maybe_quit ();
637 block_input ();
640 #ifdef CAIRO_HAS_PNG_FUNCTIONS
641 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
643 cairo_surface_flush (surface);
644 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
646 #endif
647 unblock_input ();
649 unbind_to (count, Qnil);
651 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
654 #endif /* USE_CAIRO */
656 static void
657 x_free_cr_resources (struct frame *f)
659 #ifdef USE_CAIRO
660 if (f == NULL)
662 Lisp_Object rest, frame;
663 FOR_EACH_FRAME (rest, frame)
664 if (FRAME_X_P (XFRAME (frame)))
665 x_free_cr_resources (XFRAME (frame));
667 else
669 cairo_t *cr = FRAME_CR_CONTEXT (f);
671 if (cr)
673 cairo_surface_t *surface = cairo_get_target (cr);
675 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
677 cairo_destroy (cr);
678 FRAME_CR_CONTEXT (f) = NULL;
682 #endif
685 static void
686 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
688 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
689 #ifdef USE_CAIRO
690 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
693 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
695 gc_ext->n_clip_rects = n;
696 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
698 #endif
701 static void
702 x_reset_clip_rectangles (struct frame *f, GC gc)
704 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
705 #ifdef USE_CAIRO
707 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
709 if (gc_ext)
710 gc_ext->n_clip_rects = 0;
712 #endif
715 static void
716 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
718 #ifdef USE_CAIRO
719 cairo_t *cr;
721 cr = x_begin_cr_clip (f, gc);
722 x_set_cr_source_with_gc_foreground (f, gc);
723 cairo_rectangle (cr, x, y, width, height);
724 cairo_fill (cr);
725 x_end_cr_clip (f);
726 #else
727 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
728 gc, x, y, width, height);
729 #endif
732 static void
733 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
735 #ifdef USE_CAIRO
736 cairo_t *cr;
738 cr = x_begin_cr_clip (f, gc);
739 x_set_cr_source_with_gc_foreground (f, gc);
740 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
741 cairo_set_line_width (cr, 1);
742 cairo_stroke (cr);
743 x_end_cr_clip (f);
744 #else
745 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
746 gc, x, y, width, height);
747 #endif
750 static void
751 x_clear_window (struct frame *f)
753 #ifdef USE_CAIRO
754 cairo_t *cr;
756 cr = x_begin_cr_clip (f, NULL);
757 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
758 cairo_paint (cr);
759 x_end_cr_clip (f);
760 #else
761 if (FRAME_X_DOUBLE_BUFFERED_P (f))
762 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
763 else
764 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
765 #endif
768 #ifdef USE_CAIRO
769 static void
770 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
771 int width, int height, int top_p)
773 cairo_t *cr;
775 cr = x_begin_cr_clip (f, gc);
776 x_set_cr_source_with_gc_foreground (f, gc);
777 cairo_move_to (cr, top_p ? x : x + height, y);
778 cairo_line_to (cr, x, y + height);
779 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
780 cairo_line_to (cr, x + width, y);
781 cairo_fill (cr);
782 x_end_cr_clip (f);
785 enum corners
787 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
788 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
789 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
790 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
791 CORNER_LAST
794 static void
795 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
796 int width, int height,
797 double radius, double margin, int corners)
799 cairo_t *cr;
800 int i;
802 cr = x_begin_cr_clip (f, gc);
803 x_set_cr_source_with_gc_background (f, gc);
804 for (i = 0; i < CORNER_LAST; i++)
805 if (corners & (1 << i))
807 double xm, ym, xc, yc;
809 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
810 xm = x - margin, xc = xm + radius;
811 else
812 xm = x + width + margin, xc = xm - radius;
813 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
814 ym = y - margin, yc = ym + radius;
815 else
816 ym = y + height + margin, yc = ym - radius;
818 cairo_move_to (cr, xm, ym);
819 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
821 cairo_clip (cr);
822 cairo_rectangle (cr, x, y, width, height);
823 cairo_fill (cr);
824 x_end_cr_clip (f);
827 static void
828 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
829 int width, int height, int wave_length)
831 cairo_t *cr;
832 double dx = wave_length, dy = height - 1;
833 int xoffset, n;
835 cr = x_begin_cr_clip (f, gc);
836 x_set_cr_source_with_gc_foreground (f, gc);
837 cairo_rectangle (cr, x, y, width, height);
838 cairo_clip (cr);
840 if (x >= 0)
842 xoffset = x % (wave_length * 2);
843 if (xoffset == 0)
844 xoffset = wave_length * 2;
846 else
847 xoffset = x % (wave_length * 2) + wave_length * 2;
848 n = (width + xoffset) / wave_length + 1;
849 if (xoffset > wave_length)
851 xoffset -= wave_length;
852 --n;
853 y += height - 1;
854 dy = -dy;
857 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
858 while (--n >= 0)
860 cairo_rel_line_to (cr, dx, dy);
861 dy = -dy;
863 cairo_set_line_width (cr, 1);
864 cairo_stroke (cr);
865 x_end_cr_clip (f);
867 #endif
870 /* Return the struct x_display_info corresponding to DPY. */
872 struct x_display_info *
873 x_display_info_for_display (Display *dpy)
875 struct x_display_info *dpyinfo;
877 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
878 if (dpyinfo->display == dpy)
879 return dpyinfo;
881 return 0;
884 static Window
885 x_find_topmost_parent (struct frame *f)
887 struct x_output *x = f->output_data.x;
888 Window win = None, wi = x->parent_desc;
889 Display *dpy = FRAME_X_DISPLAY (f);
891 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
893 Window root;
894 Window *children;
895 unsigned int nchildren;
897 win = wi;
898 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
899 XFree (children);
900 else
901 break;
904 return win;
907 #define OPAQUE 0xffffffff
909 void
910 x_set_frame_alpha (struct frame *f)
912 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
913 Display *dpy = FRAME_X_DISPLAY (f);
914 Window win = FRAME_OUTER_WINDOW (f);
915 double alpha = 1.0;
916 double alpha_min = 1.0;
917 unsigned long opac;
918 Window parent;
920 if (dpyinfo->x_highlight_frame == f)
921 alpha = f->alpha[0];
922 else
923 alpha = f->alpha[1];
925 if (FLOATP (Vframe_alpha_lower_limit))
926 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
927 else if (INTEGERP (Vframe_alpha_lower_limit))
928 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
930 if (alpha < 0.0)
931 return;
932 else if (alpha > 1.0)
933 alpha = 1.0;
934 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
935 alpha = alpha_min;
937 opac = alpha * OPAQUE;
939 x_catch_errors (dpy);
941 /* If there is a parent from the window manager, put the property there
942 also, to work around broken window managers that fail to do that.
943 Do this unconditionally as this function is called on reparent when
944 alpha has not changed on the frame. */
946 if (!FRAME_PARENT_FRAME (f))
948 parent = x_find_topmost_parent (f);
949 if (parent != None)
950 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
951 XA_CARDINAL, 32, PropModeReplace,
952 (unsigned char *) &opac, 1);
955 /* return unless necessary */
957 unsigned char *data;
958 Atom actual;
959 int rc, format;
960 unsigned long n, left;
962 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
963 0, 1, False, XA_CARDINAL,
964 &actual, &format, &n, &left,
965 &data);
967 if (rc == Success && actual != None)
969 unsigned long value = *(unsigned long *)data;
970 XFree (data);
971 if (value == opac)
973 x_uncatch_errors ();
974 return;
979 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
980 XA_CARDINAL, 32, PropModeReplace,
981 (unsigned char *) &opac, 1);
982 x_uncatch_errors ();
985 /***********************************************************************
986 Starting and ending an update
987 ***********************************************************************/
989 /* Start an update of frame F. This function is installed as a hook
990 for update_begin, i.e. it is called when update_begin is called.
991 This function is called prior to calls to x_update_window_begin for
992 each window being updated. Currently, there is nothing to do here
993 because all interesting stuff is done on a window basis. */
995 static void
996 x_update_begin (struct frame *f)
998 #ifdef USE_CAIRO
999 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
1000 && ! FRAME_VISIBLE_P (f))
1001 return;
1003 if (! FRAME_CR_SURFACE (f))
1005 int width, height;
1006 #ifdef USE_GTK
1007 if (FRAME_GTK_WIDGET (f))
1009 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1010 width = gdk_window_get_width (w);
1011 height = gdk_window_get_height (w);
1013 else
1014 #endif
1016 width = FRAME_PIXEL_WIDTH (f);
1017 height = FRAME_PIXEL_HEIGHT (f);
1018 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1019 height += FRAME_TOOL_BAR_HEIGHT (f);
1020 if (! FRAME_EXTERNAL_MENU_BAR (f))
1021 height += FRAME_MENU_BAR_HEIGHT (f);
1024 if (width > 0 && height > 0)
1026 block_input();
1027 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1028 (CAIRO_FORMAT_ARGB32, width, height);
1029 unblock_input();
1032 #endif /* USE_CAIRO */
1035 /* Start update of window W. */
1037 static void
1038 x_update_window_begin (struct window *w)
1040 struct frame *f = XFRAME (WINDOW_FRAME (w));
1041 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1043 w->output_cursor = w->cursor;
1045 block_input ();
1047 if (f == hlinfo->mouse_face_mouse_frame)
1049 /* Don't do highlighting for mouse motion during the update. */
1050 hlinfo->mouse_face_defer = true;
1052 /* If F needs to be redrawn, simply forget about any prior mouse
1053 highlighting. */
1054 if (FRAME_GARBAGED_P (f))
1055 hlinfo->mouse_face_window = Qnil;
1058 unblock_input ();
1062 /* Draw a vertical window border from (x,y0) to (x,y1) */
1064 static void
1065 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1067 struct frame *f = XFRAME (WINDOW_FRAME (w));
1068 struct face *face;
1070 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1071 if (face)
1072 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1073 face->foreground);
1075 #ifdef USE_CAIRO
1076 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1077 #else
1078 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1079 f->output_data.x->normal_gc, x, y0, x, y1);
1080 #endif
1083 /* Draw a window divider from (x0,y0) to (x1,y1) */
1085 static void
1086 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1088 struct frame *f = XFRAME (WINDOW_FRAME (w));
1089 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1090 struct face *face_first
1091 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1092 struct face *face_last
1093 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1094 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1095 unsigned long color_first = (face_first
1096 ? face_first->foreground
1097 : FRAME_FOREGROUND_PIXEL (f));
1098 unsigned long color_last = (face_last
1099 ? face_last->foreground
1100 : FRAME_FOREGROUND_PIXEL (f));
1101 Display *display = FRAME_X_DISPLAY (f);
1103 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1104 /* Vertical. */
1106 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1107 x_fill_rectangle (f, f->output_data.x->normal_gc,
1108 x0, y0, 1, y1 - y0);
1109 XSetForeground (display, f->output_data.x->normal_gc, color);
1110 x_fill_rectangle (f, f->output_data.x->normal_gc,
1111 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1112 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1113 x_fill_rectangle (f, f->output_data.x->normal_gc,
1114 x1 - 1, y0, 1, y1 - y0);
1116 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1117 /* Horizontal. */
1119 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1120 x_fill_rectangle (f, f->output_data.x->normal_gc,
1121 x0, y0, x1 - x0, 1);
1122 XSetForeground (display, f->output_data.x->normal_gc, color);
1123 x_fill_rectangle (f, f->output_data.x->normal_gc,
1124 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1125 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1126 x_fill_rectangle (f, f->output_data.x->normal_gc,
1127 x0, y1 - 1, x1 - x0, 1);
1129 else
1131 XSetForeground (display, f->output_data.x->normal_gc, color);
1132 x_fill_rectangle (f, f->output_data.x->normal_gc,
1133 x0, y0, x1 - x0, y1 - y0);
1137 /* End update of window W.
1139 Draw vertical borders between horizontally adjacent windows, and
1140 display W's cursor if CURSOR_ON_P is non-zero.
1142 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1143 glyphs in mouse-face were overwritten. In that case we have to
1144 make sure that the mouse-highlight is properly redrawn.
1146 W may be a menu bar pseudo-window in case we don't have X toolkit
1147 support. Such windows don't have a cursor, so don't display it
1148 here. */
1150 static void
1151 x_update_window_end (struct window *w, bool cursor_on_p,
1152 bool mouse_face_overwritten_p)
1154 if (!w->pseudo_window_p)
1156 block_input ();
1158 if (cursor_on_p)
1159 display_and_set_cursor (w, true,
1160 w->output_cursor.hpos, w->output_cursor.vpos,
1161 w->output_cursor.x, w->output_cursor.y);
1163 if (draw_window_fringes (w, true))
1165 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1166 x_draw_right_divider (w);
1167 else
1168 x_draw_vertical_border (w);
1171 unblock_input ();
1174 /* If a row with mouse-face was overwritten, arrange for
1175 XTframe_up_to_date to redisplay the mouse highlight. */
1176 if (mouse_face_overwritten_p)
1178 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1180 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1181 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1182 hlinfo->mouse_face_window = Qnil;
1186 /* Show the frame back buffer. If frame is double-buffered,
1187 atomically publish to the user's screen graphics updates made since
1188 the last call to show_back_buffer. */
1189 static void
1190 show_back_buffer (struct frame *f)
1192 block_input ();
1193 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1195 #ifdef HAVE_XDBE
1196 XdbeSwapInfo swap_info;
1197 memset (&swap_info, 0, sizeof (swap_info));
1198 swap_info.swap_window = FRAME_X_WINDOW (f);
1199 swap_info.swap_action = XdbeCopied;
1200 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1201 #else
1202 eassert (!"should have back-buffer only with XDBE");
1203 #endif
1205 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1206 unblock_input ();
1209 /* Updates back buffer and flushes changes to display. Called from
1210 minibuf read code. Note that we display the back buffer even if
1211 buffer flipping is blocked. */
1212 static void
1213 x_flip_and_flush (struct frame *f)
1215 block_input ();
1216 if (FRAME_X_NEED_BUFFER_FLIP (f))
1217 show_back_buffer (f);
1218 x_flush (f);
1219 unblock_input ();
1222 /* End update of frame F. This function is installed as a hook in
1223 update_end. */
1225 static void
1226 x_update_end (struct frame *f)
1228 /* Mouse highlight may be displayed again. */
1229 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1231 #ifdef USE_CAIRO
1232 if (FRAME_CR_SURFACE (f))
1234 cairo_t *cr = 0;
1235 block_input();
1236 #if defined (USE_GTK) && defined (HAVE_GTK3)
1237 if (FRAME_GTK_WIDGET (f))
1239 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1240 cr = gdk_cairo_create (w);
1242 else
1243 #endif
1245 cairo_surface_t *surface;
1246 int width = FRAME_PIXEL_WIDTH (f);
1247 int height = FRAME_PIXEL_HEIGHT (f);
1248 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1249 height += FRAME_TOOL_BAR_HEIGHT (f);
1250 if (! FRAME_EXTERNAL_MENU_BAR (f))
1251 height += FRAME_MENU_BAR_HEIGHT (f);
1252 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1253 FRAME_X_DRAWABLE (f),
1254 FRAME_DISPLAY_INFO (f)->visual,
1255 width,
1256 height);
1257 cr = cairo_create (surface);
1258 cairo_surface_destroy (surface);
1261 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1262 cairo_paint (cr);
1263 cairo_destroy (cr);
1264 unblock_input ();
1266 #endif
1268 #ifndef XFlush
1269 block_input ();
1270 XFlush (FRAME_X_DISPLAY (f));
1271 unblock_input ();
1272 #endif
1275 /* This function is called from various places in xdisp.c
1276 whenever a complete update has been performed. */
1278 static void
1279 XTframe_up_to_date (struct frame *f)
1281 eassert (FRAME_X_P (f));
1282 block_input ();
1283 FRAME_MOUSE_UPDATE (f);
1284 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1285 show_back_buffer (f);
1286 unblock_input ();
1289 static void
1290 XTbuffer_flipping_unblocked_hook (struct frame *f)
1292 if (FRAME_X_NEED_BUFFER_FLIP (f))
1293 show_back_buffer (f);
1297 * x_clear_under_internal_border:
1299 * Clear area of frame F's internal border. If the internal border face
1300 * of F has been specified (is not null), fill the area with that face.
1302 void
1303 x_clear_under_internal_border (struct frame *f)
1305 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1307 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1308 int width = FRAME_PIXEL_WIDTH (f);
1309 int height = FRAME_PIXEL_HEIGHT (f);
1310 #ifdef USE_GTK
1311 int margin = 0;
1312 #else
1313 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1314 #endif
1315 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1317 block_input ();
1319 if (face)
1321 unsigned long color = face->background;
1322 Display *display = FRAME_X_DISPLAY (f);
1323 GC gc = f->output_data.x->normal_gc;
1325 XSetForeground (display, gc, color);
1326 x_fill_rectangle (f, gc, 0, margin, width, border);
1327 x_fill_rectangle (f, gc, 0, 0, border, height);
1328 x_fill_rectangle (f, gc, width - border, 0, border, height);
1329 x_fill_rectangle (f, gc, 0, height - border, width, border);
1330 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1332 else
1334 x_clear_area (f, 0, 0, border, height);
1335 x_clear_area (f, 0, margin, width, border);
1336 x_clear_area (f, width - border, 0, border, height);
1337 x_clear_area (f, 0, height - border, width, border);
1340 unblock_input ();
1344 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1345 arrow bitmaps, or clear the fringes if no bitmaps are required
1346 before DESIRED_ROW is made current. This function is called from
1347 update_window_line only if it is known that there are differences
1348 between bitmaps to be drawn between current row and DESIRED_ROW. */
1350 static void
1351 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1353 eassert (w);
1355 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1356 desired_row->redraw_fringe_bitmaps_p = true;
1358 #ifdef USE_X_TOOLKIT
1359 /* When a window has disappeared, make sure that no rest of
1360 full-width rows stays visible in the internal border. Could
1361 check here if updated window is the leftmost/rightmost window,
1362 but I guess it's not worth doing since vertically split windows
1363 are almost never used, internal border is rarely set, and the
1364 overhead is very small. */
1366 struct frame *f;
1367 int width, height;
1369 if (windows_or_buffers_changed
1370 && desired_row->full_width_p
1371 && (f = XFRAME (w->frame),
1372 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1373 width != 0)
1374 && (height = desired_row->visible_height,
1375 height > 0))
1377 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1378 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1380 block_input ();
1381 if (face)
1383 unsigned long color = face->background;
1384 Display *display = FRAME_X_DISPLAY (f);
1386 XSetForeground (display, f->output_data.x->normal_gc, color);
1387 x_fill_rectangle (f, f->output_data.x->normal_gc,
1388 0, y, width, height);
1389 x_fill_rectangle (f, f->output_data.x->normal_gc,
1390 FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1392 else
1394 x_clear_area (f, 0, y, width, height);
1395 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1397 unblock_input ();
1400 #endif
1403 static void
1404 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1406 struct frame *f = XFRAME (WINDOW_FRAME (w));
1407 Display *display = FRAME_X_DISPLAY (f);
1408 GC gc = f->output_data.x->normal_gc;
1409 struct face *face = p->face;
1411 /* Must clip because of partially visible lines. */
1412 x_clip_to_row (w, row, ANY_AREA, gc);
1414 if (p->bx >= 0 && !p->overlay_p)
1416 /* In case the same realized face is used for fringes and
1417 for something displayed in the text (e.g. face `region' on
1418 mono-displays, the fill style may have been changed to
1419 FillSolid in x_draw_glyph_string_background. */
1420 if (face->stipple)
1421 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1422 else
1423 XSetForeground (display, face->gc, face->background);
1425 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1427 if (!face->stipple)
1428 XSetForeground (display, face->gc, face->foreground);
1431 #ifdef USE_CAIRO
1432 if (p->which && p->which < max_fringe_bmp)
1434 XGCValues gcv;
1436 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1437 XSetForeground (display, gc, (p->cursor_p
1438 ? (p->overlay_p ? face->background
1439 : f->output_data.x->cursor_pixel)
1440 : face->foreground));
1441 XSetBackground (display, gc, face->background);
1442 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1443 p->wd, p->h, p->x, p->y, p->overlay_p);
1444 XSetForeground (display, gc, gcv.foreground);
1445 XSetBackground (display, gc, gcv.background);
1447 #else /* not USE_CAIRO */
1448 if (p->which)
1450 Drawable drawable = FRAME_X_DRAWABLE (f);
1451 char *bits;
1452 Pixmap pixmap, clipmask = (Pixmap) 0;
1453 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1454 XGCValues gcv;
1456 if (p->wd > 8)
1457 bits = (char *) (p->bits + p->dh);
1458 else
1459 bits = (char *) p->bits + p->dh;
1461 /* Draw the bitmap. I believe these small pixmaps can be cached
1462 by the server. */
1463 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1464 (p->cursor_p
1465 ? (p->overlay_p ? face->background
1466 : f->output_data.x->cursor_pixel)
1467 : face->foreground),
1468 face->background, depth);
1470 if (p->overlay_p)
1472 clipmask = XCreatePixmapFromBitmapData (display,
1473 FRAME_DISPLAY_INFO (f)->root_window,
1474 bits, p->wd, p->h,
1475 1, 0, 1);
1476 gcv.clip_mask = clipmask;
1477 gcv.clip_x_origin = p->x;
1478 gcv.clip_y_origin = p->y;
1479 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1482 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1483 p->wd, p->h, p->x, p->y);
1484 XFreePixmap (display, pixmap);
1486 if (p->overlay_p)
1488 gcv.clip_mask = (Pixmap) 0;
1489 XChangeGC (display, gc, GCClipMask, &gcv);
1490 XFreePixmap (display, clipmask);
1493 #endif /* not USE_CAIRO */
1495 x_reset_clip_rectangles (f, gc);
1498 /***********************************************************************
1499 Glyph display
1500 ***********************************************************************/
1504 static void x_set_glyph_string_clipping (struct glyph_string *);
1505 static void x_set_glyph_string_gc (struct glyph_string *);
1506 static void x_draw_glyph_string_foreground (struct glyph_string *);
1507 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1508 static void x_draw_glyph_string_box (struct glyph_string *);
1509 static void x_draw_glyph_string (struct glyph_string *);
1510 static _Noreturn void x_delete_glyphs (struct frame *, int);
1511 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1512 static void x_set_cursor_gc (struct glyph_string *);
1513 static void x_set_mode_line_face_gc (struct glyph_string *);
1514 static void x_set_mouse_face_gc (struct glyph_string *);
1515 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1516 unsigned long *, double, int);
1517 static void x_setup_relief_color (struct frame *, struct relief *,
1518 double, int, unsigned long);
1519 static void x_setup_relief_colors (struct glyph_string *);
1520 static void x_draw_image_glyph_string (struct glyph_string *);
1521 static void x_draw_image_relief (struct glyph_string *);
1522 static void x_draw_image_foreground (struct glyph_string *);
1523 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1524 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1525 int, int, int);
1526 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1527 int, bool, bool, bool, bool, bool,
1528 XRectangle *);
1529 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1530 int, bool, bool, XRectangle *);
1531 static void x_scroll_bar_clear (struct frame *);
1533 #ifdef GLYPH_DEBUG
1534 static void x_check_font (struct frame *, struct font *);
1535 #endif
1538 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1539 face. */
1541 static void
1542 x_set_cursor_gc (struct glyph_string *s)
1544 if (s->font == FRAME_FONT (s->f)
1545 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1546 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1547 && !s->cmp)
1548 s->gc = s->f->output_data.x->cursor_gc;
1549 else
1551 /* Cursor on non-default face: must merge. */
1552 XGCValues xgcv;
1553 unsigned long mask;
1555 xgcv.background = s->f->output_data.x->cursor_pixel;
1556 xgcv.foreground = s->face->background;
1558 /* If the glyph would be invisible, try a different foreground. */
1559 if (xgcv.foreground == xgcv.background)
1560 xgcv.foreground = s->face->foreground;
1561 if (xgcv.foreground == xgcv.background)
1562 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1563 if (xgcv.foreground == xgcv.background)
1564 xgcv.foreground = s->face->foreground;
1566 /* Make sure the cursor is distinct from text in this face. */
1567 if (xgcv.background == s->face->background
1568 && xgcv.foreground == s->face->foreground)
1570 xgcv.background = s->face->foreground;
1571 xgcv.foreground = s->face->background;
1574 IF_DEBUG (x_check_font (s->f, s->font));
1575 xgcv.graphics_exposures = False;
1576 mask = GCForeground | GCBackground | GCGraphicsExposures;
1578 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1579 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1580 mask, &xgcv);
1581 else
1582 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1583 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1585 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1590 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1592 static void
1593 x_set_mouse_face_gc (struct glyph_string *s)
1595 int face_id;
1596 struct face *face;
1598 /* What face has to be used last for the mouse face? */
1599 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1600 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1601 if (face == NULL)
1602 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1604 if (s->first_glyph->type == CHAR_GLYPH)
1605 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1606 else
1607 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1608 s->face = FACE_FROM_ID (s->f, face_id);
1609 prepare_face_for_display (s->f, s->face);
1611 if (s->font == s->face->font)
1612 s->gc = s->face->gc;
1613 else
1615 /* Otherwise construct scratch_cursor_gc with values from FACE
1616 except for FONT. */
1617 XGCValues xgcv;
1618 unsigned long mask;
1620 xgcv.background = s->face->background;
1621 xgcv.foreground = s->face->foreground;
1622 xgcv.graphics_exposures = False;
1623 mask = GCForeground | GCBackground | GCGraphicsExposures;
1625 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1626 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1627 mask, &xgcv);
1628 else
1629 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1630 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1632 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1635 eassert (s->gc != 0);
1639 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1640 Faces to use in the mode line have already been computed when the
1641 matrix was built, so there isn't much to do, here. */
1643 static void
1644 x_set_mode_line_face_gc (struct glyph_string *s)
1646 s->gc = s->face->gc;
1650 /* Set S->gc of glyph string S for drawing that glyph string. Set
1651 S->stippled_p to a non-zero value if the face of S has a stipple
1652 pattern. */
1654 static void
1655 x_set_glyph_string_gc (struct glyph_string *s)
1657 prepare_face_for_display (s->f, s->face);
1659 if (s->hl == DRAW_NORMAL_TEXT)
1661 s->gc = s->face->gc;
1662 s->stippled_p = s->face->stipple != 0;
1664 else if (s->hl == DRAW_INVERSE_VIDEO)
1666 x_set_mode_line_face_gc (s);
1667 s->stippled_p = s->face->stipple != 0;
1669 else if (s->hl == DRAW_CURSOR)
1671 x_set_cursor_gc (s);
1672 s->stippled_p = false;
1674 else if (s->hl == DRAW_MOUSE_FACE)
1676 x_set_mouse_face_gc (s);
1677 s->stippled_p = s->face->stipple != 0;
1679 else if (s->hl == DRAW_IMAGE_RAISED
1680 || s->hl == DRAW_IMAGE_SUNKEN)
1682 s->gc = s->face->gc;
1683 s->stippled_p = s->face->stipple != 0;
1685 else
1686 emacs_abort ();
1688 /* GC must have been set. */
1689 eassert (s->gc != 0);
1693 /* Set clipping for output of glyph string S. S may be part of a mode
1694 line or menu if we don't have X toolkit support. */
1696 static void
1697 x_set_glyph_string_clipping (struct glyph_string *s)
1699 XRectangle *r = s->clip;
1700 int n = get_glyph_string_clip_rects (s, r, 2);
1702 if (n > 0)
1703 x_set_clip_rectangles (s->f, s->gc, r, n);
1704 s->num_clips = n;
1708 /* Set SRC's clipping for output of glyph string DST. This is called
1709 when we are drawing DST's left_overhang or right_overhang only in
1710 the area of SRC. */
1712 static void
1713 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1715 XRectangle r;
1717 r.x = src->x;
1718 r.width = src->width;
1719 r.y = src->y;
1720 r.height = src->height;
1721 dst->clip[0] = r;
1722 dst->num_clips = 1;
1723 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1727 /* RIF:
1728 Compute left and right overhang of glyph string S. */
1730 static void
1731 x_compute_glyph_string_overhangs (struct glyph_string *s)
1733 if (s->cmp == NULL
1734 && (s->first_glyph->type == CHAR_GLYPH
1735 || s->first_glyph->type == COMPOSITE_GLYPH))
1737 struct font_metrics metrics;
1739 if (s->first_glyph->type == CHAR_GLYPH)
1741 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1742 struct font *font = s->font;
1743 int i;
1745 for (i = 0; i < s->nchars; i++)
1746 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1747 font->driver->text_extents (font, code, s->nchars, &metrics);
1749 else
1751 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1753 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1755 s->right_overhang = (metrics.rbearing > metrics.width
1756 ? metrics.rbearing - metrics.width : 0);
1757 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1759 else if (s->cmp)
1761 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1762 s->left_overhang = - s->cmp->lbearing;
1767 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1769 static void
1770 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1772 XGCValues xgcv;
1773 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1774 XSetForeground (s->display, s->gc, xgcv.background);
1775 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1776 XSetForeground (s->display, s->gc, xgcv.foreground);
1780 /* Draw the background of glyph_string S. If S->background_filled_p
1781 is non-zero don't draw it. FORCE_P non-zero means draw the
1782 background even if it wouldn't be drawn normally. This is used
1783 when a string preceding S draws into the background of S, or S
1784 contains the first component of a composition. */
1786 static void
1787 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1789 /* Nothing to do if background has already been drawn or if it
1790 shouldn't be drawn in the first place. */
1791 if (!s->background_filled_p)
1793 int box_line_width = max (s->face->box_line_width, 0);
1795 if (s->stippled_p)
1797 /* Fill background with a stipple pattern. */
1798 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1799 x_fill_rectangle (s->f, s->gc, s->x,
1800 s->y + box_line_width,
1801 s->background_width,
1802 s->height - 2 * box_line_width);
1803 XSetFillStyle (s->display, s->gc, FillSolid);
1804 s->background_filled_p = true;
1806 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1807 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1808 font dimensions, since the actual glyphs might be
1809 much smaller. So in that case we always clear the
1810 rectangle with background color. */
1811 || FONT_TOO_HIGH (s->font)
1812 || s->font_not_found_p
1813 || s->extends_to_end_of_line_p
1814 || force_p)
1816 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1817 s->background_width,
1818 s->height - 2 * box_line_width);
1819 s->background_filled_p = true;
1825 /* Draw the foreground of glyph string S. */
1827 static void
1828 x_draw_glyph_string_foreground (struct glyph_string *s)
1830 int i, x;
1832 /* If first glyph of S has a left box line, start drawing the text
1833 of S to the right of that box line. */
1834 if (s->face->box != FACE_NO_BOX
1835 && s->first_glyph->left_box_line_p)
1836 x = s->x + eabs (s->face->box_line_width);
1837 else
1838 x = s->x;
1840 /* Draw characters of S as rectangles if S's font could not be
1841 loaded. */
1842 if (s->font_not_found_p)
1844 for (i = 0; i < s->nchars; ++i)
1846 struct glyph *g = s->first_glyph + i;
1847 x_draw_rectangle (s->f,
1848 s->gc, x, s->y, g->pixel_width - 1,
1849 s->height - 1);
1850 x += g->pixel_width;
1853 else
1855 struct font *font = s->font;
1856 int boff = font->baseline_offset;
1857 int y;
1859 if (font->vertical_centering)
1860 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1862 y = s->ybase - boff;
1863 if (s->for_overlaps
1864 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1865 font->driver->draw (s, 0, s->nchars, x, y, false);
1866 else
1867 font->driver->draw (s, 0, s->nchars, x, y, true);
1868 if (s->face->overstrike)
1869 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1873 /* Draw the foreground of composite glyph string S. */
1875 static void
1876 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1878 int i, j, x;
1879 struct font *font = s->font;
1881 /* If first glyph of S has a left box line, start drawing the text
1882 of S to the right of that box line. */
1883 if (s->face && s->face->box != FACE_NO_BOX
1884 && s->first_glyph->left_box_line_p)
1885 x = s->x + eabs (s->face->box_line_width);
1886 else
1887 x = s->x;
1889 /* S is a glyph string for a composition. S->cmp_from is the index
1890 of the first character drawn for glyphs of this composition.
1891 S->cmp_from == 0 means we are drawing the very first character of
1892 this composition. */
1894 /* Draw a rectangle for the composition if the font for the very
1895 first character of the composition could not be loaded. */
1896 if (s->font_not_found_p)
1898 if (s->cmp_from == 0)
1899 x_draw_rectangle (s->f, s->gc, x, s->y,
1900 s->width - 1, s->height - 1);
1902 else if (! s->first_glyph->u.cmp.automatic)
1904 int y = s->ybase;
1906 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1907 /* TAB in a composition means display glyphs with padding
1908 space on the left or right. */
1909 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1911 int xx = x + s->cmp->offsets[j * 2];
1912 int yy = y - s->cmp->offsets[j * 2 + 1];
1914 font->driver->draw (s, j, j + 1, xx, yy, false);
1915 if (s->face->overstrike)
1916 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1919 else
1921 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1922 Lisp_Object glyph;
1923 int y = s->ybase;
1924 int width = 0;
1926 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1928 glyph = LGSTRING_GLYPH (gstring, i);
1929 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1930 width += LGLYPH_WIDTH (glyph);
1931 else
1933 int xoff, yoff, wadjust;
1935 if (j < i)
1937 font->driver->draw (s, j, i, x, y, false);
1938 if (s->face->overstrike)
1939 font->driver->draw (s, j, i, x + 1, y, false);
1940 x += width;
1942 xoff = LGLYPH_XOFF (glyph);
1943 yoff = LGLYPH_YOFF (glyph);
1944 wadjust = LGLYPH_WADJUST (glyph);
1945 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1946 if (s->face->overstrike)
1947 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1948 false);
1949 x += wadjust;
1950 j = i + 1;
1951 width = 0;
1954 if (j < i)
1956 font->driver->draw (s, j, i, x, y, false);
1957 if (s->face->overstrike)
1958 font->driver->draw (s, j, i, x + 1, y, false);
1964 /* Draw the foreground of glyph string S for glyphless characters. */
1966 static void
1967 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1969 struct glyph *glyph = s->first_glyph;
1970 XChar2b char2b[8];
1971 int x, i, j;
1973 /* If first glyph of S has a left box line, start drawing the text
1974 of S to the right of that box line. */
1975 if (s->face && s->face->box != FACE_NO_BOX
1976 && s->first_glyph->left_box_line_p)
1977 x = s->x + eabs (s->face->box_line_width);
1978 else
1979 x = s->x;
1981 s->char2b = char2b;
1983 for (i = 0; i < s->nchars; i++, glyph++)
1985 char buf[7], *str = NULL;
1986 int len = glyph->u.glyphless.len;
1988 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1990 if (len > 0
1991 && CHAR_TABLE_P (Vglyphless_char_display)
1992 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1993 >= 1))
1995 Lisp_Object acronym
1996 = (! glyph->u.glyphless.for_no_font
1997 ? CHAR_TABLE_REF (Vglyphless_char_display,
1998 glyph->u.glyphless.ch)
1999 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
2000 if (STRINGP (acronym))
2001 str = SSDATA (acronym);
2004 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
2006 unsigned int ch = glyph->u.glyphless.ch;
2007 eassume (ch <= MAX_CHAR);
2008 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
2009 str = buf;
2012 if (str)
2014 int upper_len = (len + 1) / 2;
2015 unsigned code;
2017 /* It is assured that all LEN characters in STR is ASCII. */
2018 for (j = 0; j < len; j++)
2020 code = s->font->driver->encode_char (s->font, str[j]);
2021 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
2023 s->font->driver->draw (s, 0, upper_len,
2024 x + glyph->slice.glyphless.upper_xoff,
2025 s->ybase + glyph->slice.glyphless.upper_yoff,
2026 false);
2027 s->font->driver->draw (s, upper_len, len,
2028 x + glyph->slice.glyphless.lower_xoff,
2029 s->ybase + glyph->slice.glyphless.lower_yoff,
2030 false);
2032 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
2033 x_draw_rectangle (s->f, s->gc,
2034 x, s->ybase - glyph->ascent,
2035 glyph->pixel_width - 1,
2036 glyph->ascent + glyph->descent - 1);
2037 x += glyph->pixel_width;
2041 #ifdef USE_X_TOOLKIT
2043 #ifdef USE_LUCID
2045 /* Return the frame on which widget WIDGET is used.. Abort if frame
2046 cannot be determined. */
2048 static struct frame *
2049 x_frame_of_widget (Widget widget)
2051 struct x_display_info *dpyinfo;
2052 Lisp_Object tail, frame;
2053 struct frame *f;
2055 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2057 /* Find the top-level shell of the widget. Note that this function
2058 can be called when the widget is not yet realized, so XtWindow
2059 (widget) == 0. That's the reason we can't simply use
2060 x_any_window_to_frame. */
2061 while (!XtIsTopLevelShell (widget))
2062 widget = XtParent (widget);
2064 /* Look for a frame with that top-level widget. Allocate the color
2065 on that frame to get the right gamma correction value. */
2066 FOR_EACH_FRAME (tail, frame)
2068 f = XFRAME (frame);
2069 if (FRAME_X_P (f)
2070 && f->output_data.nothing != 1
2071 && FRAME_DISPLAY_INFO (f) == dpyinfo
2072 && f->output_data.x->widget == widget)
2073 return f;
2075 emacs_abort ();
2078 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2079 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2080 If this produces the same color as PIXEL, try a color where all RGB
2081 values have DELTA added. Return the allocated color in *PIXEL.
2082 DISPLAY is the X display, CMAP is the colormap to operate on.
2083 Value is true if successful. */
2085 bool
2086 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2087 unsigned long *pixel, double factor, int delta)
2089 struct frame *f = x_frame_of_widget (widget);
2090 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2093 #endif /* USE_LUCID */
2096 /* Structure specifying which arguments should be passed by Xt to
2097 cvt_string_to_pixel. We want the widget's screen and colormap. */
2099 static XtConvertArgRec cvt_string_to_pixel_args[] =
2101 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2102 sizeof (Screen *)},
2103 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2104 sizeof (Colormap)}
2108 /* The address of this variable is returned by
2109 cvt_string_to_pixel. */
2111 static Pixel cvt_string_to_pixel_value;
2114 /* Convert a color name to a pixel color.
2116 DPY is the display we are working on.
2118 ARGS is an array of *NARGS XrmValue structures holding additional
2119 information about the widget for which the conversion takes place.
2120 The contents of this array are determined by the specification
2121 in cvt_string_to_pixel_args.
2123 FROM is a pointer to an XrmValue which points to the color name to
2124 convert. TO is an XrmValue in which to return the pixel color.
2126 CLOSURE_RET is a pointer to user-data, in which we record if
2127 we allocated the color or not.
2129 Value is True if successful, False otherwise. */
2131 static Boolean
2132 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2133 XrmValue *from, XrmValue *to,
2134 XtPointer *closure_ret)
2136 Screen *screen;
2137 Colormap cmap;
2138 Pixel pixel;
2139 String color_name;
2140 XColor color;
2142 if (*nargs != 2)
2144 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2145 "wrongParameters", "cvt_string_to_pixel",
2146 "XtToolkitError",
2147 "Screen and colormap args required", NULL, NULL);
2148 return False;
2151 screen = *(Screen **) args[0].addr;
2152 cmap = *(Colormap *) args[1].addr;
2153 color_name = (String) from->addr;
2155 if (strcmp (color_name, XtDefaultBackground) == 0)
2157 *closure_ret = (XtPointer) False;
2158 pixel = WhitePixelOfScreen (screen);
2160 else if (strcmp (color_name, XtDefaultForeground) == 0)
2162 *closure_ret = (XtPointer) False;
2163 pixel = BlackPixelOfScreen (screen);
2165 else if (XParseColor (dpy, cmap, color_name, &color)
2166 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2168 pixel = color.pixel;
2169 *closure_ret = (XtPointer) True;
2171 else
2173 String params[1];
2174 Cardinal nparams = 1;
2176 params[0] = color_name;
2177 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2178 "badValue", "cvt_string_to_pixel",
2179 "XtToolkitError", "Invalid color '%s'",
2180 params, &nparams);
2181 return False;
2184 if (to->addr != NULL)
2186 if (to->size < sizeof (Pixel))
2188 to->size = sizeof (Pixel);
2189 return False;
2192 *(Pixel *) to->addr = pixel;
2194 else
2196 cvt_string_to_pixel_value = pixel;
2197 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2200 to->size = sizeof (Pixel);
2201 return True;
2205 /* Free a pixel color which was previously allocated via
2206 cvt_string_to_pixel. This is registered as the destructor
2207 for this type of resource via XtSetTypeConverter.
2209 APP is the application context in which we work.
2211 TO is a pointer to an XrmValue holding the color to free.
2212 CLOSURE is the value we stored in CLOSURE_RET for this color
2213 in cvt_string_to_pixel.
2215 ARGS and NARGS are like for cvt_string_to_pixel. */
2217 static void
2218 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2219 Cardinal *nargs)
2221 if (*nargs != 2)
2223 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2224 "XtToolkitError",
2225 "Screen and colormap arguments required",
2226 NULL, NULL);
2228 else if (closure != NULL)
2230 /* We did allocate the pixel, so free it. */
2231 Screen *screen = *(Screen **) args[0].addr;
2232 Colormap cmap = *(Colormap *) args[1].addr;
2233 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2234 (Pixel *) to->addr, 1);
2239 #endif /* USE_X_TOOLKIT */
2242 /* Value is an array of XColor structures for the contents of the
2243 color map of display DPY. Set *NCELLS to the size of the array.
2244 Note that this probably shouldn't be called for large color maps,
2245 say a 24-bit TrueColor map. */
2247 static const XColor *
2248 x_color_cells (Display *dpy, int *ncells)
2250 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2251 eassume (dpyinfo);
2253 if (dpyinfo->color_cells == NULL)
2255 Screen *screen = dpyinfo->screen;
2256 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2257 int i;
2259 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2260 sizeof *dpyinfo->color_cells);
2261 dpyinfo->ncolor_cells = ncolor_cells;
2263 for (i = 0; i < ncolor_cells; ++i)
2264 dpyinfo->color_cells[i].pixel = i;
2266 XQueryColors (dpy, dpyinfo->cmap,
2267 dpyinfo->color_cells, ncolor_cells);
2270 *ncells = dpyinfo->ncolor_cells;
2271 return dpyinfo->color_cells;
2275 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2276 colors in COLORS. Use cached information, if available. */
2278 void
2279 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2281 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2283 if (dpyinfo->red_bits > 0)
2285 /* For TrueColor displays, we can decompose the RGB value
2286 directly. */
2287 int i;
2288 unsigned int rmult, gmult, bmult;
2289 unsigned int rmask, gmask, bmask;
2291 rmask = (1 << dpyinfo->red_bits) - 1;
2292 gmask = (1 << dpyinfo->green_bits) - 1;
2293 bmask = (1 << dpyinfo->blue_bits) - 1;
2294 /* If we're widening, for example, 8 bits in the pixel value to
2295 16 bits for the separate-color representation, we want to
2296 extrapolate the lower bits based on those bits available --
2297 in other words, we'd like 0xff to become 0xffff instead of
2298 the 0xff00 we'd get by just zero-filling the lower bits.
2300 We generate a 32-bit scaled-up value and shift it, in case
2301 the bit count doesn't divide 16 evenly (e.g., when dealing
2302 with a 3-3-2 bit RGB display), to get more of the lower bits
2303 correct.
2305 Should we cache the multipliers in dpyinfo? Maybe
2306 special-case the 8-8-8 common case? */
2307 rmult = 0xffffffff / rmask;
2308 gmult = 0xffffffff / gmask;
2309 bmult = 0xffffffff / bmask;
2311 for (i = 0; i < ncolors; ++i)
2313 unsigned int r, g, b;
2314 unsigned long pixel = colors[i].pixel;
2316 r = (pixel >> dpyinfo->red_offset) & rmask;
2317 g = (pixel >> dpyinfo->green_offset) & gmask;
2318 b = (pixel >> dpyinfo->blue_offset) & bmask;
2320 colors[i].red = (r * rmult) >> 16;
2321 colors[i].green = (g * gmult) >> 16;
2322 colors[i].blue = (b * bmult) >> 16;
2324 return;
2327 if (dpyinfo->color_cells)
2329 int i;
2330 for (i = 0; i < ncolors; ++i)
2332 unsigned long pixel = colors[i].pixel;
2333 eassert (pixel < dpyinfo->ncolor_cells);
2334 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2335 colors[i] = dpyinfo->color_cells[pixel];
2337 return;
2340 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2344 /* On frame F, translate pixel color to RGB values for the color in
2345 COLOR. Use cached information, if available. */
2347 void
2348 x_query_color (struct frame *f, XColor *color)
2350 x_query_colors (f, color, 1);
2354 /* On frame F, translate the color name to RGB values. Use cached
2355 information, if possible.
2357 Note that there is currently no way to clean old entries out of the
2358 cache. However, it is limited to names in the server's database,
2359 and names we've actually looked up; list-colors-display is probably
2360 the most color-intensive case we're likely to hit. */
2362 Status x_parse_color (struct frame *f, const char *color_name,
2363 XColor *color)
2365 Display *dpy = FRAME_X_DISPLAY (f);
2366 Colormap cmap = FRAME_X_COLORMAP (f);
2367 struct color_name_cache_entry *cache_entry;
2369 if (color_name[0] == '#')
2371 /* The hex form is parsed directly by XParseColor without
2372 talking to the X server. No need for caching. */
2373 return XParseColor (dpy, cmap, color_name, color);
2376 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2377 cache_entry = cache_entry->next)
2379 if (!xstrcasecmp(cache_entry->name, color_name))
2381 *color = cache_entry->rgb;
2382 return 1;
2386 if (XParseColor (dpy, cmap, color_name, color) == 0)
2387 /* No caching of negative results, currently. */
2388 return 0;
2390 cache_entry = xzalloc (sizeof *cache_entry);
2391 cache_entry->rgb = *color;
2392 cache_entry->name = xstrdup (color_name);
2393 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2394 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2395 return 1;
2399 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2400 exact match can't be allocated, try the nearest color available.
2401 Value is true if successful. Set *COLOR to the color
2402 allocated. */
2404 static bool
2405 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2407 bool rc;
2409 rc = XAllocColor (dpy, cmap, color) != 0;
2410 if (rc == 0)
2412 /* If we got to this point, the colormap is full, so we're going
2413 to try to get the next closest color. The algorithm used is
2414 a least-squares matching, which is what X uses for closest
2415 color matching with StaticColor visuals. */
2416 int nearest, i;
2417 int max_color_delta = 255;
2418 int max_delta = 3 * max_color_delta;
2419 int nearest_delta = max_delta + 1;
2420 int ncells;
2421 const XColor *cells = x_color_cells (dpy, &ncells);
2423 for (nearest = i = 0; i < ncells; ++i)
2425 int dred = (color->red >> 8) - (cells[i].red >> 8);
2426 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2427 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2428 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2430 if (delta < nearest_delta)
2432 nearest = i;
2433 nearest_delta = delta;
2437 color->red = cells[nearest].red;
2438 color->green = cells[nearest].green;
2439 color->blue = cells[nearest].blue;
2440 rc = XAllocColor (dpy, cmap, color) != 0;
2442 else
2444 /* If allocation succeeded, and the allocated pixel color is not
2445 equal to a cached pixel color recorded earlier, there was a
2446 change in the colormap, so clear the color cache. */
2447 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2448 eassume (dpyinfo);
2450 if (dpyinfo->color_cells)
2452 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2453 if (cached_color->red != color->red
2454 || cached_color->blue != color->blue
2455 || cached_color->green != color->green)
2457 xfree (dpyinfo->color_cells);
2458 dpyinfo->color_cells = NULL;
2459 dpyinfo->ncolor_cells = 0;
2464 #ifdef DEBUG_X_COLORS
2465 if (rc)
2466 register_color (color->pixel);
2467 #endif /* DEBUG_X_COLORS */
2469 return rc;
2473 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2474 gamma correction. If an exact match can't be allocated, try the
2475 nearest color available. Value is true if successful. Set *COLOR
2476 to the color allocated. */
2478 bool
2479 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2481 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2483 gamma_correct (f, color);
2485 if (dpyinfo->red_bits > 0)
2487 color->pixel = x_make_truecolor_pixel (dpyinfo,
2488 color->red,
2489 color->green,
2490 color->blue);
2491 return true;
2494 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2498 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2499 It's necessary to do this instead of just using PIXEL directly to
2500 get color reference counts right. */
2502 unsigned long
2503 x_copy_color (struct frame *f, unsigned long pixel)
2505 XColor color;
2507 /* If display has an immutable color map, freeing colors is not
2508 necessary and some servers don't allow it. Since we won't free a
2509 color once we've allocated it, we don't need to re-allocate it to
2510 maintain the server's reference count. */
2511 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2512 return pixel;
2514 color.pixel = pixel;
2515 block_input ();
2516 /* The color could still be found in the color_cells array. */
2517 x_query_color (f, &color);
2518 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2519 unblock_input ();
2520 #ifdef DEBUG_X_COLORS
2521 register_color (pixel);
2522 #endif
2523 return color.pixel;
2527 /* Brightness beyond which a color won't have its highlight brightness
2528 boosted.
2530 Nominally, highlight colors for `3d' faces are calculated by
2531 brightening an object's color by a constant scale factor, but this
2532 doesn't yield good results for dark colors, so for colors who's
2533 brightness is less than this value (on a scale of 0-65535) have an
2534 use an additional additive factor.
2536 The value here is set so that the default menu-bar/mode-line color
2537 (grey75) will not have its highlights changed at all. */
2538 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2541 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2542 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2543 If this produces the same color as PIXEL, try a color where all RGB
2544 values have DELTA added. Return the allocated color in *PIXEL.
2545 DISPLAY is the X display, CMAP is the colormap to operate on.
2546 Value is non-zero if successful. */
2548 static bool
2549 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2550 unsigned long *pixel, double factor, int delta)
2552 XColor color, new;
2553 long bright;
2554 bool success_p;
2556 /* Get RGB color values. */
2557 color.pixel = *pixel;
2558 x_query_color (f, &color);
2560 /* Change RGB values by specified FACTOR. Avoid overflow! */
2561 eassert (factor >= 0);
2562 new.red = min (0xffff, factor * color.red);
2563 new.green = min (0xffff, factor * color.green);
2564 new.blue = min (0xffff, factor * color.blue);
2566 /* Calculate brightness of COLOR. */
2567 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2569 /* We only boost colors that are darker than
2570 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2571 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2572 /* Make an additive adjustment to NEW, because it's dark enough so
2573 that scaling by FACTOR alone isn't enough. */
2575 /* How far below the limit this color is (0 - 1, 1 being darker). */
2576 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2577 /* The additive adjustment. */
2578 int min_delta = delta * dimness * factor / 2;
2580 if (factor < 1)
2582 new.red = max (0, new.red - min_delta);
2583 new.green = max (0, new.green - min_delta);
2584 new.blue = max (0, new.blue - min_delta);
2586 else
2588 new.red = min (0xffff, min_delta + new.red);
2589 new.green = min (0xffff, min_delta + new.green);
2590 new.blue = min (0xffff, min_delta + new.blue);
2594 /* Try to allocate the color. */
2595 success_p = x_alloc_nearest_color (f, cmap, &new);
2596 if (success_p)
2598 if (new.pixel == *pixel)
2600 /* If we end up with the same color as before, try adding
2601 delta to the RGB values. */
2602 x_free_colors (f, &new.pixel, 1);
2604 new.red = min (0xffff, delta + color.red);
2605 new.green = min (0xffff, delta + color.green);
2606 new.blue = min (0xffff, delta + color.blue);
2607 success_p = x_alloc_nearest_color (f, cmap, &new);
2609 else
2610 success_p = true;
2611 *pixel = new.pixel;
2614 return success_p;
2618 /* Set up the foreground color for drawing relief lines of glyph
2619 string S. RELIEF is a pointer to a struct relief containing the GC
2620 with which lines will be drawn. Use a color that is FACTOR or
2621 DELTA lighter or darker than the relief's background which is found
2622 in S->f->output_data.x->relief_background. If such a color cannot
2623 be allocated, use DEFAULT_PIXEL, instead. */
2625 static void
2626 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2627 int delta, unsigned long default_pixel)
2629 XGCValues xgcv;
2630 struct x_output *di = f->output_data.x;
2631 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2632 unsigned long pixel;
2633 unsigned long background = di->relief_background;
2634 Colormap cmap = FRAME_X_COLORMAP (f);
2635 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2636 Display *dpy = FRAME_X_DISPLAY (f);
2638 xgcv.graphics_exposures = False;
2639 xgcv.line_width = 1;
2641 /* Free previously allocated color. The color cell will be reused
2642 when it has been freed as many times as it was allocated, so this
2643 doesn't affect faces using the same colors. */
2644 if (relief->gc && relief->pixel != -1)
2646 x_free_colors (f, &relief->pixel, 1);
2647 relief->pixel = -1;
2650 /* Allocate new color. */
2651 xgcv.foreground = default_pixel;
2652 pixel = background;
2653 if (dpyinfo->n_planes != 1
2654 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2655 xgcv.foreground = relief->pixel = pixel;
2657 if (relief->gc == 0)
2659 xgcv.stipple = dpyinfo->gray;
2660 mask |= GCStipple;
2661 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2663 else
2664 XChangeGC (dpy, relief->gc, mask, &xgcv);
2668 /* Set up colors for the relief lines around glyph string S. */
2670 static void
2671 x_setup_relief_colors (struct glyph_string *s)
2673 struct x_output *di = s->f->output_data.x;
2674 unsigned long color;
2676 if (s->face->use_box_color_for_shadows_p)
2677 color = s->face->box_color;
2678 else if (s->first_glyph->type == IMAGE_GLYPH
2679 && s->img->pixmap
2680 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2681 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2682 else
2684 XGCValues xgcv;
2686 /* Get the background color of the face. */
2687 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2688 color = xgcv.background;
2691 if (di->white_relief.gc == 0
2692 || color != di->relief_background)
2694 di->relief_background = color;
2695 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2696 WHITE_PIX_DEFAULT (s->f));
2697 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2698 BLACK_PIX_DEFAULT (s->f));
2703 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2704 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2705 to draw, it must be >= 0. RAISED_P means draw a raised
2706 relief. LEFT_P means draw a relief on the left side of
2707 the rectangle. RIGHT_P means draw a relief on the right
2708 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2709 when drawing. */
2711 static void
2712 x_draw_relief_rect (struct frame *f,
2713 int left_x, int top_y, int right_x, int bottom_y,
2714 int width, bool raised_p, bool top_p, bool bot_p,
2715 bool left_p, bool right_p,
2716 XRectangle *clip_rect)
2718 #ifdef USE_CAIRO
2719 GC top_left_gc, bottom_right_gc;
2720 int corners = 0;
2722 if (raised_p)
2724 top_left_gc = f->output_data.x->white_relief.gc;
2725 bottom_right_gc = f->output_data.x->black_relief.gc;
2727 else
2729 top_left_gc = f->output_data.x->black_relief.gc;
2730 bottom_right_gc = f->output_data.x->white_relief.gc;
2733 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2734 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2736 if (left_p)
2738 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2739 width, bottom_y + 1 - top_y);
2740 if (top_p)
2741 corners |= 1 << CORNER_TOP_LEFT;
2742 if (bot_p)
2743 corners |= 1 << CORNER_BOTTOM_LEFT;
2745 if (right_p)
2747 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2748 width, bottom_y + 1 - top_y);
2749 if (top_p)
2750 corners |= 1 << CORNER_TOP_RIGHT;
2751 if (bot_p)
2752 corners |= 1 << CORNER_BOTTOM_RIGHT;
2754 if (top_p)
2756 if (!right_p)
2757 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2758 right_x + 1 - left_x, width);
2759 else
2760 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2761 right_x + 1 - left_x, width, 1);
2763 if (bot_p)
2765 if (!left_p)
2766 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2767 right_x + 1 - left_x, width);
2768 else
2769 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2770 left_x, bottom_y + 1 - width,
2771 right_x + 1 - left_x, width, 0);
2773 if (left_p && width != 1)
2774 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2775 1, bottom_y + 1 - top_y);
2776 if (top_p && width != 1)
2777 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2778 right_x + 1 - left_x, 1);
2779 if (corners)
2781 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2782 FRAME_BACKGROUND_PIXEL (f));
2783 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2784 right_x - left_x + 1, bottom_y - top_y + 1,
2785 6, 1, corners);
2788 x_reset_clip_rectangles (f, top_left_gc);
2789 x_reset_clip_rectangles (f, bottom_right_gc);
2790 #else
2791 Display *dpy = FRAME_X_DISPLAY (f);
2792 Drawable drawable = FRAME_X_DRAWABLE (f);
2793 int i;
2794 GC gc;
2796 if (raised_p)
2797 gc = f->output_data.x->white_relief.gc;
2798 else
2799 gc = f->output_data.x->black_relief.gc;
2800 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2802 /* This code is more complicated than it has to be, because of two
2803 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2804 the outermost line using the black relief. (ii) Omit the four
2805 corner pixels. */
2807 /* Top. */
2808 if (top_p)
2810 if (width == 1)
2811 XDrawLine (dpy, drawable, gc,
2812 left_x + left_p, top_y,
2813 right_x + !right_p, top_y);
2815 for (i = 1; i < width; ++i)
2816 XDrawLine (dpy, drawable, gc,
2817 left_x + i * left_p, top_y + i,
2818 right_x + 1 - i * right_p, top_y + i);
2821 /* Left. */
2822 if (left_p)
2824 if (width == 1)
2825 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2827 x_clear_area(f, left_x, top_y, 1, 1);
2828 x_clear_area(f, left_x, bottom_y, 1, 1);
2830 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2831 XDrawLine (dpy, drawable, gc,
2832 left_x + i, top_y + (i + 1) * top_p,
2833 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2836 XSetClipMask (dpy, gc, None);
2837 if (raised_p)
2838 gc = f->output_data.x->black_relief.gc;
2839 else
2840 gc = f->output_data.x->white_relief.gc;
2841 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2843 if (width > 1)
2845 /* Outermost top line. */
2846 if (top_p)
2847 XDrawLine (dpy, drawable, gc,
2848 left_x + left_p, top_y,
2849 right_x + !right_p, top_y);
2851 /* Outermost left line. */
2852 if (left_p)
2853 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2856 /* Bottom. */
2857 if (bot_p)
2859 XDrawLine (dpy, drawable, gc,
2860 left_x + left_p, bottom_y,
2861 right_x + !right_p, bottom_y);
2862 for (i = 1; i < width; ++i)
2863 XDrawLine (dpy, drawable, gc,
2864 left_x + i * left_p, bottom_y - i,
2865 right_x + 1 - i * right_p, bottom_y - i);
2868 /* Right. */
2869 if (right_p)
2871 x_clear_area(f, right_x, top_y, 1, 1);
2872 x_clear_area(f, right_x, bottom_y, 1, 1);
2873 for (i = 0; i < width; ++i)
2874 XDrawLine (dpy, drawable, gc,
2875 right_x - i, top_y + (i + 1) * top_p,
2876 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2879 x_reset_clip_rectangles (f, gc);
2881 #endif
2885 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2886 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2887 draw, it must be >= 0. LEFT_P means draw a line on the
2888 left side of the rectangle. RIGHT_P means draw a line
2889 on the right side of the rectangle. CLIP_RECT is the clipping
2890 rectangle to use when drawing. */
2892 static void
2893 x_draw_box_rect (struct glyph_string *s,
2894 int left_x, int top_y, int right_x, int bottom_y, int width,
2895 bool left_p, bool right_p, XRectangle *clip_rect)
2897 XGCValues xgcv;
2899 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2900 XSetForeground (s->display, s->gc, s->face->box_color);
2901 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2903 /* Top. */
2904 x_fill_rectangle (s->f, s->gc,
2905 left_x, top_y, right_x - left_x + 1, width);
2907 /* Left. */
2908 if (left_p)
2909 x_fill_rectangle (s->f, s->gc,
2910 left_x, top_y, width, bottom_y - top_y + 1);
2912 /* Bottom. */
2913 x_fill_rectangle (s->f, s->gc,
2914 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2916 /* Right. */
2917 if (right_p)
2918 x_fill_rectangle (s->f, s->gc,
2919 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2921 XSetForeground (s->display, s->gc, xgcv.foreground);
2922 x_reset_clip_rectangles (s->f, s->gc);
2926 /* Draw a box around glyph string S. */
2928 static void
2929 x_draw_glyph_string_box (struct glyph_string *s)
2931 int width, left_x, right_x, top_y, bottom_y, last_x;
2932 bool raised_p, left_p, right_p;
2933 struct glyph *last_glyph;
2934 XRectangle clip_rect;
2936 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2937 ? WINDOW_RIGHT_EDGE_X (s->w)
2938 : window_box_right (s->w, s->area));
2940 /* The glyph that may have a right box line. */
2941 last_glyph = (s->cmp || s->img
2942 ? s->first_glyph
2943 : s->first_glyph + s->nchars - 1);
2945 width = eabs (s->face->box_line_width);
2946 raised_p = s->face->box == FACE_RAISED_BOX;
2947 left_x = s->x;
2948 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2949 ? last_x - 1
2950 : min (last_x, s->x + s->background_width) - 1);
2951 top_y = s->y;
2952 bottom_y = top_y + s->height - 1;
2954 left_p = (s->first_glyph->left_box_line_p
2955 || (s->hl == DRAW_MOUSE_FACE
2956 && (s->prev == NULL
2957 || s->prev->hl != s->hl)));
2958 right_p = (last_glyph->right_box_line_p
2959 || (s->hl == DRAW_MOUSE_FACE
2960 && (s->next == NULL
2961 || s->next->hl != s->hl)));
2963 get_glyph_string_clip_rect (s, &clip_rect);
2965 if (s->face->box == FACE_SIMPLE_BOX)
2966 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2967 left_p, right_p, &clip_rect);
2968 else
2970 x_setup_relief_colors (s);
2971 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2972 width, raised_p, true, true, left_p, right_p,
2973 &clip_rect);
2978 /* Draw foreground of image glyph string S. */
2980 static void
2981 x_draw_image_foreground (struct glyph_string *s)
2983 int x = s->x;
2984 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2986 /* If first glyph of S has a left box line, start drawing it to the
2987 right of that line. */
2988 if (s->face->box != FACE_NO_BOX
2989 && s->first_glyph->left_box_line_p
2990 && s->slice.x == 0)
2991 x += eabs (s->face->box_line_width);
2993 /* If there is a margin around the image, adjust x- and y-position
2994 by that margin. */
2995 if (s->slice.x == 0)
2996 x += s->img->hmargin;
2997 if (s->slice.y == 0)
2998 y += s->img->vmargin;
3000 if (s->img->pixmap)
3002 if (s->img->mask)
3004 /* We can't set both a clip mask and use XSetClipRectangles
3005 because the latter also sets a clip mask. We also can't
3006 trust on the shape extension to be available
3007 (XShapeCombineRegion). So, compute the rectangle to draw
3008 manually. */
3009 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3010 | GCFunction);
3011 XGCValues xgcv;
3012 XRectangle clip_rect, image_rect, r;
3014 xgcv.clip_mask = s->img->mask;
3015 xgcv.clip_x_origin = x;
3016 xgcv.clip_y_origin = y;
3017 xgcv.function = GXcopy;
3018 XChangeGC (s->display, s->gc, mask, &xgcv);
3020 get_glyph_string_clip_rect (s, &clip_rect);
3021 image_rect.x = x;
3022 image_rect.y = y;
3023 image_rect.width = s->slice.width;
3024 image_rect.height = s->slice.height;
3025 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3026 XCopyArea (s->display, s->img->pixmap,
3027 FRAME_X_DRAWABLE (s->f), s->gc,
3028 s->slice.x + r.x - x, s->slice.y + r.y - y,
3029 r.width, r.height, r.x, r.y);
3031 else
3033 XRectangle clip_rect, image_rect, r;
3035 get_glyph_string_clip_rect (s, &clip_rect);
3036 image_rect.x = x;
3037 image_rect.y = y;
3038 image_rect.width = s->slice.width;
3039 image_rect.height = s->slice.height;
3040 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3041 XCopyArea (s->display, s->img->pixmap,
3042 FRAME_X_DRAWABLE (s->f), s->gc,
3043 s->slice.x + r.x - x, s->slice.y + r.y - y,
3044 r.width, r.height, r.x, r.y);
3046 /* When the image has a mask, we can expect that at
3047 least part of a mouse highlight or a block cursor will
3048 be visible. If the image doesn't have a mask, make
3049 a block cursor visible by drawing a rectangle around
3050 the image. I believe it's looking better if we do
3051 nothing here for mouse-face. */
3052 if (s->hl == DRAW_CURSOR)
3054 int relief = eabs (s->img->relief);
3055 x_draw_rectangle (s->f, s->gc,
3056 x - relief, y - relief,
3057 s->slice.width + relief*2 - 1,
3058 s->slice.height + relief*2 - 1);
3062 else
3063 /* Draw a rectangle if image could not be loaded. */
3064 x_draw_rectangle (s->f, s->gc, x, y,
3065 s->slice.width - 1, s->slice.height - 1);
3069 /* Draw a relief around the image glyph string S. */
3071 static void
3072 x_draw_image_relief (struct glyph_string *s)
3074 int x1, y1, thick;
3075 bool raised_p, top_p, bot_p, left_p, right_p;
3076 int extra_x, extra_y;
3077 XRectangle r;
3078 int x = s->x;
3079 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3081 /* If first glyph of S has a left box line, start drawing it to the
3082 right of that line. */
3083 if (s->face->box != FACE_NO_BOX
3084 && s->first_glyph->left_box_line_p
3085 && s->slice.x == 0)
3086 x += eabs (s->face->box_line_width);
3088 /* If there is a margin around the image, adjust x- and y-position
3089 by that margin. */
3090 if (s->slice.x == 0)
3091 x += s->img->hmargin;
3092 if (s->slice.y == 0)
3093 y += s->img->vmargin;
3095 if (s->hl == DRAW_IMAGE_SUNKEN
3096 || s->hl == DRAW_IMAGE_RAISED)
3098 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3099 raised_p = s->hl == DRAW_IMAGE_RAISED;
3101 else
3103 thick = eabs (s->img->relief);
3104 raised_p = s->img->relief > 0;
3107 x1 = x + s->slice.width - 1;
3108 y1 = y + s->slice.height - 1;
3110 extra_x = extra_y = 0;
3111 if (s->face->id == TOOL_BAR_FACE_ID)
3113 if (CONSP (Vtool_bar_button_margin)
3114 && INTEGERP (XCAR (Vtool_bar_button_margin))
3115 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3117 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3118 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3120 else if (INTEGERP (Vtool_bar_button_margin))
3121 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3124 top_p = bot_p = left_p = right_p = false;
3126 if (s->slice.x == 0)
3127 x -= thick + extra_x, left_p = true;
3128 if (s->slice.y == 0)
3129 y -= thick + extra_y, top_p = true;
3130 if (s->slice.x + s->slice.width == s->img->width)
3131 x1 += thick + extra_x, right_p = true;
3132 if (s->slice.y + s->slice.height == s->img->height)
3133 y1 += thick + extra_y, bot_p = true;
3135 x_setup_relief_colors (s);
3136 get_glyph_string_clip_rect (s, &r);
3137 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3138 top_p, bot_p, left_p, right_p, &r);
3142 /* Draw the foreground of image glyph string S to PIXMAP. */
3144 static void
3145 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3147 int x = 0;
3148 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3150 /* If first glyph of S has a left box line, start drawing it to the
3151 right of that line. */
3152 if (s->face->box != FACE_NO_BOX
3153 && s->first_glyph->left_box_line_p
3154 && s->slice.x == 0)
3155 x += eabs (s->face->box_line_width);
3157 /* If there is a margin around the image, adjust x- and y-position
3158 by that margin. */
3159 if (s->slice.x == 0)
3160 x += s->img->hmargin;
3161 if (s->slice.y == 0)
3162 y += s->img->vmargin;
3164 if (s->img->pixmap)
3166 if (s->img->mask)
3168 /* We can't set both a clip mask and use XSetClipRectangles
3169 because the latter also sets a clip mask. We also can't
3170 trust on the shape extension to be available
3171 (XShapeCombineRegion). So, compute the rectangle to draw
3172 manually. */
3173 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3174 | GCFunction);
3175 XGCValues xgcv;
3177 xgcv.clip_mask = s->img->mask;
3178 xgcv.clip_x_origin = x - s->slice.x;
3179 xgcv.clip_y_origin = y - s->slice.y;
3180 xgcv.function = GXcopy;
3181 XChangeGC (s->display, s->gc, mask, &xgcv);
3183 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3184 s->slice.x, s->slice.y,
3185 s->slice.width, s->slice.height, x, y);
3186 XSetClipMask (s->display, s->gc, None);
3188 else
3190 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3191 s->slice.x, s->slice.y,
3192 s->slice.width, s->slice.height, x, y);
3194 /* When the image has a mask, we can expect that at
3195 least part of a mouse highlight or a block cursor will
3196 be visible. If the image doesn't have a mask, make
3197 a block cursor visible by drawing a rectangle around
3198 the image. I believe it's looking better if we do
3199 nothing here for mouse-face. */
3200 if (s->hl == DRAW_CURSOR)
3202 int r = eabs (s->img->relief);
3203 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3204 s->slice.width + r*2 - 1,
3205 s->slice.height + r*2 - 1);
3209 else
3210 /* Draw a rectangle if image could not be loaded. */
3211 x_draw_rectangle (s->f, s->gc, x, y,
3212 s->slice.width - 1, s->slice.height - 1);
3216 /* Draw part of the background of glyph string S. X, Y, W, and H
3217 give the rectangle to draw. */
3219 static void
3220 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3222 if (s->stippled_p)
3224 /* Fill background with a stipple pattern. */
3225 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3226 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3227 XSetFillStyle (s->display, s->gc, FillSolid);
3229 else
3230 x_clear_glyph_string_rect (s, x, y, w, h);
3234 /* Draw image glyph string S.
3236 s->y
3237 s->x +-------------------------
3238 | s->face->box
3240 | +-------------------------
3241 | | s->img->margin
3243 | | +-------------------
3244 | | | the image
3248 static void
3249 x_draw_image_glyph_string (struct glyph_string *s)
3251 int box_line_hwidth = eabs (s->face->box_line_width);
3252 int box_line_vwidth = max (s->face->box_line_width, 0);
3253 int height;
3254 Pixmap pixmap = None;
3256 height = s->height;
3257 if (s->slice.y == 0)
3258 height -= box_line_vwidth;
3259 if (s->slice.y + s->slice.height >= s->img->height)
3260 height -= box_line_vwidth;
3262 /* Fill background with face under the image. Do it only if row is
3263 taller than image or if image has a clip mask to reduce
3264 flickering. */
3265 s->stippled_p = s->face->stipple != 0;
3266 if (height > s->slice.height
3267 || s->img->hmargin
3268 || s->img->vmargin
3269 || s->img->mask
3270 || s->img->pixmap == 0
3271 || s->width != s->background_width)
3273 if (s->img->mask)
3275 /* Create a pixmap as large as the glyph string. Fill it
3276 with the background color. Copy the image to it, using
3277 its mask. Copy the temporary pixmap to the display. */
3278 Screen *screen = FRAME_X_SCREEN (s->f);
3279 int depth = DefaultDepthOfScreen (screen);
3281 /* Create a pixmap as large as the glyph string. */
3282 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3283 s->background_width,
3284 s->height, depth);
3286 /* Don't clip in the following because we're working on the
3287 pixmap. */
3288 XSetClipMask (s->display, s->gc, None);
3290 /* Fill the pixmap with the background color/stipple. */
3291 if (s->stippled_p)
3293 /* Fill background with a stipple pattern. */
3294 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3295 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3296 XFillRectangle (s->display, pixmap, s->gc,
3297 0, 0, s->background_width, s->height);
3298 XSetFillStyle (s->display, s->gc, FillSolid);
3299 XSetTSOrigin (s->display, s->gc, 0, 0);
3301 else
3303 XGCValues xgcv;
3304 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3305 &xgcv);
3306 XSetForeground (s->display, s->gc, xgcv.background);
3307 XFillRectangle (s->display, pixmap, s->gc,
3308 0, 0, s->background_width, s->height);
3309 XSetForeground (s->display, s->gc, xgcv.foreground);
3312 else
3314 int x = s->x;
3315 int y = s->y;
3316 int width = s->background_width;
3318 if (s->first_glyph->left_box_line_p
3319 && s->slice.x == 0)
3321 x += box_line_hwidth;
3322 width -= box_line_hwidth;
3325 if (s->slice.y == 0)
3326 y += box_line_vwidth;
3328 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3331 s->background_filled_p = true;
3334 /* Draw the foreground. */
3335 #ifdef USE_CAIRO
3336 if (s->img->cr_data)
3338 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3340 int x = s->x + s->img->hmargin;
3341 int y = s->y + s->img->vmargin;
3342 int width = s->background_width;
3344 cairo_set_source_surface (cr, s->img->cr_data,
3345 x - s->slice.x,
3346 y - s->slice.y);
3347 cairo_rectangle (cr, x, y, width, height);
3348 cairo_fill (cr);
3349 x_end_cr_clip (s->f);
3351 else
3352 #endif
3353 if (pixmap != None)
3355 x_draw_image_foreground_1 (s, pixmap);
3356 x_set_glyph_string_clipping (s);
3357 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3358 0, 0, s->background_width, s->height, s->x, s->y);
3359 XFreePixmap (s->display, pixmap);
3361 else
3362 x_draw_image_foreground (s);
3364 /* If we must draw a relief around the image, do it. */
3365 if (s->img->relief
3366 || s->hl == DRAW_IMAGE_RAISED
3367 || s->hl == DRAW_IMAGE_SUNKEN)
3368 x_draw_image_relief (s);
3372 /* Draw stretch glyph string S. */
3374 static void
3375 x_draw_stretch_glyph_string (struct glyph_string *s)
3377 eassert (s->first_glyph->type == STRETCH_GLYPH);
3379 if (s->hl == DRAW_CURSOR
3380 && !x_stretch_cursor_p)
3382 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3383 wide as the stretch glyph. */
3384 int width, background_width = s->background_width;
3385 int x = s->x;
3387 if (!s->row->reversed_p)
3389 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3391 if (x < left_x)
3393 background_width -= left_x - x;
3394 x = left_x;
3397 else
3399 /* In R2L rows, draw the cursor on the right edge of the
3400 stretch glyph. */
3401 int right_x = window_box_right (s->w, TEXT_AREA);
3403 if (x + background_width > right_x)
3404 background_width -= x - right_x;
3405 x += background_width;
3407 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3408 if (s->row->reversed_p)
3409 x -= width;
3411 /* Draw cursor. */
3412 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3414 /* Clear rest using the GC of the original non-cursor face. */
3415 if (width < background_width)
3417 int y = s->y;
3418 int w = background_width - width, h = s->height;
3419 XRectangle r;
3420 GC gc;
3422 if (!s->row->reversed_p)
3423 x += width;
3424 else
3425 x = s->x;
3426 if (s->row->mouse_face_p
3427 && cursor_in_mouse_face_p (s->w))
3429 x_set_mouse_face_gc (s);
3430 gc = s->gc;
3432 else
3433 gc = s->face->gc;
3435 get_glyph_string_clip_rect (s, &r);
3436 x_set_clip_rectangles (s->f, gc, &r, 1);
3438 if (s->face->stipple)
3440 /* Fill background with a stipple pattern. */
3441 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3442 x_fill_rectangle (s->f, gc, x, y, w, h);
3443 XSetFillStyle (s->display, gc, FillSolid);
3445 else
3447 XGCValues xgcv;
3448 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3449 XSetForeground (s->display, gc, xgcv.background);
3450 x_fill_rectangle (s->f, gc, x, y, w, h);
3451 XSetForeground (s->display, gc, xgcv.foreground);
3454 x_reset_clip_rectangles (s->f, gc);
3457 else if (!s->background_filled_p)
3459 int background_width = s->background_width;
3460 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3462 /* Don't draw into left margin, fringe or scrollbar area
3463 except for header line and mode line. */
3464 if (x < left_x && !s->row->mode_line_p)
3466 background_width -= left_x - x;
3467 x = left_x;
3469 if (background_width > 0)
3470 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3473 s->background_filled_p = true;
3476 static void
3477 x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
3479 const int base_res = 96;
3480 struct x_display_info * dpyinfo = x_display_info_for_display (disp);
3482 *scale_x = *scale_y = 1;
3484 if (dpyinfo)
3486 if (dpyinfo->resx > base_res)
3487 *scale_x = floor (dpyinfo->resx / base_res);
3488 if (dpyinfo->resy > base_res)
3489 *scale_y = floor (dpyinfo->resy / base_res);
3494 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3496 x0 wave_length = 2
3498 y0 * * * * *
3499 |* * * * * * * * *
3500 wave_height = 3 | * * * *
3503 static void
3504 x_draw_underwave (struct glyph_string *s)
3506 /* Adjust for scale/HiDPI. */
3507 int scale_x, scale_y;
3509 x_get_scale_factor (s->display, &scale_x, &scale_y);
3511 int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
3513 #ifdef USE_CAIRO
3514 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3515 s->width, wave_height, wave_length);
3516 #else /* not USE_CAIRO */
3517 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3518 bool odd;
3519 XRectangle wave_clip, string_clip, final_clip;
3521 dx = wave_length;
3522 dy = wave_height - 1;
3523 x0 = s->x;
3524 y0 = s->ybase + wave_height / 2 - scale_y;
3525 width = s->width;
3526 xmax = x0 + width;
3528 /* Find and set clipping rectangle */
3530 wave_clip.x = x0;
3531 wave_clip.y = y0;
3532 wave_clip.width = width;
3533 wave_clip.height = wave_height;
3534 get_glyph_string_clip_rect (s, &string_clip);
3536 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3537 return;
3539 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3541 /* Draw the waves */
3543 x1 = x0 - (x0 % dx);
3544 x2 = x1 + dx;
3545 odd = (x1 / dx) & 1;
3546 y1 = y2 = y0;
3548 if (odd)
3549 y1 += dy;
3550 else
3551 y2 += dy;
3553 if (INT_MAX - dx < xmax)
3554 emacs_abort ();
3556 while (x1 <= xmax)
3558 XSetLineAttributes (s->display, s->gc, thickness, LineSolid, CapButt,
3559 JoinRound);
3560 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3561 x1 = x2, y1 = y2;
3562 x2 += dx, y2 = y0 + odd*dy;
3563 odd = !odd;
3566 /* Restore previous clipping rectangle(s) */
3567 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3568 #endif /* not USE_CAIRO */
3572 /* Draw glyph string S. */
3574 static void
3575 x_draw_glyph_string (struct glyph_string *s)
3577 bool relief_drawn_p = false;
3579 /* If S draws into the background of its successors, draw the
3580 background of the successors first so that S can draw into it.
3581 This makes S->next use XDrawString instead of XDrawImageString. */
3582 if (s->next && s->right_overhang && !s->for_overlaps)
3584 int width;
3585 struct glyph_string *next;
3587 for (width = 0, next = s->next;
3588 next && width < s->right_overhang;
3589 width += next->width, next = next->next)
3590 if (next->first_glyph->type != IMAGE_GLYPH)
3592 x_set_glyph_string_gc (next);
3593 x_set_glyph_string_clipping (next);
3594 if (next->first_glyph->type == STRETCH_GLYPH)
3595 x_draw_stretch_glyph_string (next);
3596 else
3597 x_draw_glyph_string_background (next, true);
3598 next->num_clips = 0;
3602 /* Set up S->gc, set clipping and draw S. */
3603 x_set_glyph_string_gc (s);
3605 /* Draw relief (if any) in advance for char/composition so that the
3606 glyph string can be drawn over it. */
3607 if (!s->for_overlaps
3608 && s->face->box != FACE_NO_BOX
3609 && (s->first_glyph->type == CHAR_GLYPH
3610 || s->first_glyph->type == COMPOSITE_GLYPH))
3613 x_set_glyph_string_clipping (s);
3614 x_draw_glyph_string_background (s, true);
3615 x_draw_glyph_string_box (s);
3616 x_set_glyph_string_clipping (s);
3617 relief_drawn_p = true;
3619 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3620 && !s->clip_tail
3621 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3622 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3623 /* We must clip just this glyph. left_overhang part has already
3624 drawn when s->prev was drawn, and right_overhang part will be
3625 drawn later when s->next is drawn. */
3626 x_set_glyph_string_clipping_exactly (s, s);
3627 else
3628 x_set_glyph_string_clipping (s);
3630 switch (s->first_glyph->type)
3632 case IMAGE_GLYPH:
3633 x_draw_image_glyph_string (s);
3634 break;
3636 case XWIDGET_GLYPH:
3637 x_draw_xwidget_glyph_string (s);
3638 break;
3640 case STRETCH_GLYPH:
3641 x_draw_stretch_glyph_string (s);
3642 break;
3644 case CHAR_GLYPH:
3645 if (s->for_overlaps)
3646 s->background_filled_p = true;
3647 else
3648 x_draw_glyph_string_background (s, false);
3649 x_draw_glyph_string_foreground (s);
3650 break;
3652 case COMPOSITE_GLYPH:
3653 if (s->for_overlaps || (s->cmp_from > 0
3654 && ! s->first_glyph->u.cmp.automatic))
3655 s->background_filled_p = true;
3656 else
3657 x_draw_glyph_string_background (s, true);
3658 x_draw_composite_glyph_string_foreground (s);
3659 break;
3661 case GLYPHLESS_GLYPH:
3662 if (s->for_overlaps)
3663 s->background_filled_p = true;
3664 else
3665 x_draw_glyph_string_background (s, true);
3666 x_draw_glyphless_glyph_string_foreground (s);
3667 break;
3669 default:
3670 emacs_abort ();
3673 if (!s->for_overlaps)
3675 /* Draw underline. */
3676 if (s->face->underline_p)
3678 if (s->face->underline_type == FACE_UNDER_WAVE)
3680 if (s->face->underline_defaulted_p)
3681 x_draw_underwave (s);
3682 else
3684 XGCValues xgcv;
3685 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3686 XSetForeground (s->display, s->gc, s->face->underline_color);
3687 x_draw_underwave (s);
3688 XSetForeground (s->display, s->gc, xgcv.foreground);
3691 else if (s->face->underline_type == FACE_UNDER_LINE)
3693 unsigned long thickness, position;
3694 int y;
3696 if (s->prev && s->prev->face->underline_p
3697 && s->prev->face->underline_type == FACE_UNDER_LINE)
3699 /* We use the same underline style as the previous one. */
3700 thickness = s->prev->underline_thickness;
3701 position = s->prev->underline_position;
3703 else
3705 struct font *font = font_for_underline_metrics (s);
3707 /* Get the underline thickness. Default is 1 pixel. */
3708 if (font && font->underline_thickness > 0)
3709 thickness = font->underline_thickness;
3710 else
3711 thickness = 1;
3712 if (x_underline_at_descent_line)
3713 position = (s->height - thickness) - (s->ybase - s->y);
3714 else
3716 /* Get the underline position. This is the recommended
3717 vertical offset in pixels from the baseline to the top of
3718 the underline. This is a signed value according to the
3719 specs, and its default is
3721 ROUND ((maximum descent) / 2), with
3722 ROUND(x) = floor (x + 0.5) */
3724 if (x_use_underline_position_properties
3725 && font && font->underline_position >= 0)
3726 position = font->underline_position;
3727 else if (font)
3728 position = (font->descent + 1) / 2;
3729 else
3730 position = underline_minimum_offset;
3732 position = max (position, underline_minimum_offset);
3734 /* Check the sanity of thickness and position. We should
3735 avoid drawing underline out of the current line area. */
3736 if (s->y + s->height <= s->ybase + position)
3737 position = (s->height - 1) - (s->ybase - s->y);
3738 if (s->y + s->height < s->ybase + position + thickness)
3739 thickness = (s->y + s->height) - (s->ybase + position);
3740 s->underline_thickness = thickness;
3741 s->underline_position = position;
3742 y = s->ybase + position;
3743 if (s->face->underline_defaulted_p)
3744 x_fill_rectangle (s->f, s->gc,
3745 s->x, y, s->width, thickness);
3746 else
3748 XGCValues xgcv;
3749 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3750 XSetForeground (s->display, s->gc, s->face->underline_color);
3751 x_fill_rectangle (s->f, s->gc,
3752 s->x, y, s->width, thickness);
3753 XSetForeground (s->display, s->gc, xgcv.foreground);
3757 /* Draw overline. */
3758 if (s->face->overline_p)
3760 unsigned long dy = 0, h = 1;
3762 if (s->face->overline_color_defaulted_p)
3763 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3764 s->width, h);
3765 else
3767 XGCValues xgcv;
3768 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3769 XSetForeground (s->display, s->gc, s->face->overline_color);
3770 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3771 s->width, h);
3772 XSetForeground (s->display, s->gc, xgcv.foreground);
3776 /* Draw strike-through. */
3777 if (s->face->strike_through_p)
3779 /* Y-coordinate and height of the glyph string's first
3780 glyph. We cannot use s->y and s->height because those
3781 could be larger if there are taller display elements
3782 (e.g., characters displayed with a larger font) in the
3783 same glyph row. */
3784 int glyph_y = s->ybase - s->first_glyph->ascent;
3785 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3786 /* Strike-through width and offset from the glyph string's
3787 top edge. */
3788 unsigned long h = 1;
3789 unsigned long dy = (glyph_height - h) / 2;
3791 if (s->face->strike_through_color_defaulted_p)
3792 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3793 s->width, h);
3794 else
3796 XGCValues xgcv;
3797 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3798 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3799 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3800 s->width, h);
3801 XSetForeground (s->display, s->gc, xgcv.foreground);
3805 /* Draw relief if not yet drawn. */
3806 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3807 x_draw_glyph_string_box (s);
3809 if (s->prev)
3811 struct glyph_string *prev;
3813 for (prev = s->prev; prev; prev = prev->prev)
3814 if (prev->hl != s->hl
3815 && prev->x + prev->width + prev->right_overhang > s->x)
3817 /* As prev was drawn while clipped to its own area, we
3818 must draw the right_overhang part using s->hl now. */
3819 enum draw_glyphs_face save = prev->hl;
3821 prev->hl = s->hl;
3822 x_set_glyph_string_gc (prev);
3823 x_set_glyph_string_clipping_exactly (s, prev);
3824 if (prev->first_glyph->type == CHAR_GLYPH)
3825 x_draw_glyph_string_foreground (prev);
3826 else
3827 x_draw_composite_glyph_string_foreground (prev);
3828 x_reset_clip_rectangles (prev->f, prev->gc);
3829 prev->hl = save;
3830 prev->num_clips = 0;
3834 if (s->next)
3836 struct glyph_string *next;
3838 for (next = s->next; next; next = next->next)
3839 if (next->hl != s->hl
3840 && next->x - next->left_overhang < s->x + s->width)
3842 /* As next will be drawn while clipped to its own area,
3843 we must draw the left_overhang part using s->hl now. */
3844 enum draw_glyphs_face save = next->hl;
3846 next->hl = s->hl;
3847 x_set_glyph_string_gc (next);
3848 x_set_glyph_string_clipping_exactly (s, next);
3849 if (next->first_glyph->type == CHAR_GLYPH)
3850 x_draw_glyph_string_foreground (next);
3851 else
3852 x_draw_composite_glyph_string_foreground (next);
3853 x_reset_clip_rectangles (next->f, next->gc);
3854 next->hl = save;
3855 next->num_clips = 0;
3856 next->clip_head = s->next;
3861 /* Reset clipping. */
3862 x_reset_clip_rectangles (s->f, s->gc);
3863 s->num_clips = 0;
3866 /* Shift display to make room for inserted glyphs. */
3868 static void
3869 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3871 /* Never called on a GUI frame, see
3872 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3874 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3875 f->output_data.x->normal_gc,
3876 x, y, width, height,
3877 x + shift_by, y);
3880 /* Delete N glyphs at the nominal cursor position. Not implemented
3881 for X frames. */
3883 static void
3884 x_delete_glyphs (struct frame *f, register int n)
3886 emacs_abort ();
3890 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3891 If they are <= 0, this is probably an error. */
3893 static ATTRIBUTE_UNUSED void
3894 x_clear_area1 (Display *dpy, Window window,
3895 int x, int y, int width, int height, int exposures)
3897 eassert (width > 0 && height > 0);
3898 XClearArea (dpy, window, x, y, width, height, exposures);
3901 void
3902 x_clear_area (struct frame *f, int x, int y, int width, int height)
3904 #ifdef USE_CAIRO
3905 cairo_t *cr;
3907 eassert (width > 0 && height > 0);
3909 cr = x_begin_cr_clip (f, NULL);
3910 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3911 cairo_rectangle (cr, x, y, width, height);
3912 cairo_fill (cr);
3913 x_end_cr_clip (f);
3914 #else
3915 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3916 XFillRectangle (FRAME_X_DISPLAY (f),
3917 FRAME_X_DRAWABLE (f),
3918 f->output_data.x->reverse_gc,
3919 x, y, width, height);
3920 else
3921 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3922 x, y, width, height, False);
3923 #endif
3927 /* Clear an entire frame. */
3929 static void
3930 x_clear_frame (struct frame *f)
3932 /* Clearing the frame will erase any cursor, so mark them all as no
3933 longer visible. */
3934 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3936 block_input ();
3938 font_drop_xrender_surfaces (f);
3939 x_clear_window (f);
3941 /* We have to clear the scroll bars. If we have changed colors or
3942 something like that, then they should be notified. */
3943 x_scroll_bar_clear (f);
3945 XFlush (FRAME_X_DISPLAY (f));
3947 unblock_input ();
3950 /* RIF: Show hourglass cursor on frame F. */
3952 static void
3953 x_show_hourglass (struct frame *f)
3955 Display *dpy = FRAME_X_DISPLAY (f);
3957 if (dpy)
3959 struct x_output *x = FRAME_X_OUTPUT (f);
3960 #ifdef USE_X_TOOLKIT
3961 if (x->widget)
3962 #else
3963 if (FRAME_OUTER_WINDOW (f))
3964 #endif
3966 x->hourglass_p = true;
3968 if (!x->hourglass_window)
3970 unsigned long mask = CWCursor;
3971 XSetWindowAttributes attrs;
3972 #ifdef USE_GTK
3973 Window parent = FRAME_X_WINDOW (f);
3974 #else
3975 Window parent = FRAME_OUTER_WINDOW (f);
3976 #endif
3977 attrs.cursor = x->hourglass_cursor;
3979 x->hourglass_window = XCreateWindow
3980 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3981 InputOnly, CopyFromParent, mask, &attrs);
3984 XMapRaised (dpy, x->hourglass_window);
3985 XFlush (dpy);
3990 /* RIF: Cancel hourglass cursor on frame F. */
3992 static void
3993 x_hide_hourglass (struct frame *f)
3995 struct x_output *x = FRAME_X_OUTPUT (f);
3997 /* Watch out for newly created frames. */
3998 if (x->hourglass_window)
4000 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
4001 /* Sync here because XTread_socket looks at the
4002 hourglass_p flag that is reset to zero below. */
4003 XSync (FRAME_X_DISPLAY (f), False);
4004 x->hourglass_p = false;
4008 /* Invert the middle quarter of the frame for .15 sec. */
4010 static void
4011 XTflash (struct frame *f)
4013 block_input ();
4016 #ifdef USE_GTK
4017 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
4018 when the scroll bars and the edit widget share the same X window. */
4019 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4020 #ifdef HAVE_GTK3
4021 cairo_t *cr = gdk_cairo_create (window);
4022 cairo_set_source_rgb (cr, 1, 1, 1);
4023 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4024 #define XFillRectangle(d, win, gc, x, y, w, h) \
4025 do { \
4026 cairo_rectangle (cr, x, y, w, h); \
4027 cairo_fill (cr); \
4029 while (false)
4030 #else /* ! HAVE_GTK3 */
4031 GdkGCValues vals;
4032 GdkGC *gc;
4033 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4034 ^ FRAME_BACKGROUND_PIXEL (f));
4035 vals.function = GDK_XOR;
4036 gc = gdk_gc_new_with_values (window,
4037 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4038 #define XFillRectangle(d, win, gc, x, y, w, h) \
4039 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4040 #endif /* ! HAVE_GTK3 */
4041 #else /* ! USE_GTK */
4042 GC gc;
4044 /* Create a GC that will use the GXxor function to flip foreground
4045 pixels into background pixels. */
4047 XGCValues values;
4049 values.function = GXxor;
4050 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
4051 ^ FRAME_BACKGROUND_PIXEL (f));
4053 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4054 GCFunction | GCForeground, &values);
4056 #endif
4058 /* Get the height not including a menu bar widget. */
4059 int height = FRAME_PIXEL_HEIGHT (f);
4060 /* Height of each line to flash. */
4061 int flash_height = FRAME_LINE_HEIGHT (f);
4062 /* These will be the left and right margins of the rectangles. */
4063 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4064 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4065 int width = flash_right - flash_left;
4067 /* If window is tall, flash top and bottom line. */
4068 if (height > 3 * FRAME_LINE_HEIGHT (f))
4070 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4071 flash_left,
4072 (FRAME_INTERNAL_BORDER_WIDTH (f)
4073 + FRAME_TOP_MARGIN_HEIGHT (f)),
4074 width, flash_height);
4075 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4076 flash_left,
4077 (height - flash_height
4078 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4079 width, flash_height);
4082 else
4083 /* If it is short, flash it all. */
4084 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4085 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4086 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4088 x_flush (f);
4091 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4092 struct timespec wakeup = timespec_add (current_timespec (), delay);
4094 /* Keep waiting until past the time wakeup or any input gets
4095 available. */
4096 while (! detect_input_pending ())
4098 struct timespec current = current_timespec ();
4099 struct timespec timeout;
4101 /* Break if result would not be positive. */
4102 if (timespec_cmp (wakeup, current) <= 0)
4103 break;
4105 /* How long `select' should wait. */
4106 timeout = make_timespec (0, 10 * 1000 * 1000);
4108 /* Try to wait that long--but we might wake up sooner. */
4109 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4113 /* If window is tall, flash top and bottom line. */
4114 if (height > 3 * FRAME_LINE_HEIGHT (f))
4116 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4117 flash_left,
4118 (FRAME_INTERNAL_BORDER_WIDTH (f)
4119 + FRAME_TOP_MARGIN_HEIGHT (f)),
4120 width, flash_height);
4121 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4122 flash_left,
4123 (height - flash_height
4124 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4125 width, flash_height);
4127 else
4128 /* If it is short, flash it all. */
4129 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4130 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4131 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4133 #ifdef USE_GTK
4134 #ifdef HAVE_GTK3
4135 cairo_destroy (cr);
4136 #else
4137 g_object_unref (G_OBJECT (gc));
4138 #endif
4139 #undef XFillRectangle
4140 #else
4141 XFreeGC (FRAME_X_DISPLAY (f), gc);
4142 #endif
4143 x_flush (f);
4147 unblock_input ();
4151 static void
4152 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4154 block_input ();
4155 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4156 unblock_input ();
4160 /* Make audible bell. */
4162 static void
4163 XTring_bell (struct frame *f)
4165 if (FRAME_X_DISPLAY (f))
4167 if (visible_bell)
4168 XTflash (f);
4169 else
4171 block_input ();
4172 #ifdef HAVE_XKB
4173 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4174 #else
4175 XBell (FRAME_X_DISPLAY (f), 0);
4176 #endif
4177 XFlush (FRAME_X_DISPLAY (f));
4178 unblock_input ();
4183 /***********************************************************************
4184 Line Dance
4185 ***********************************************************************/
4187 /* Perform an insert-lines or delete-lines operation, inserting N
4188 lines or deleting -N lines at vertical position VPOS. */
4190 static void
4191 x_ins_del_lines (struct frame *f, int vpos, int n)
4193 emacs_abort ();
4197 /* Scroll part of the display as described by RUN. */
4199 static void
4200 x_scroll_run (struct window *w, struct run *run)
4202 struct frame *f = XFRAME (w->frame);
4203 int x, y, width, height, from_y, to_y, bottom_y;
4205 /* Get frame-relative bounding box of the text display area of W,
4206 without mode lines. Include in this box the left and right
4207 fringe of W. */
4208 window_box (w, ANY_AREA, &x, &y, &width, &height);
4210 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4211 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4212 bottom_y = y + height;
4214 if (to_y < from_y)
4216 /* Scrolling up. Make sure we don't copy part of the mode
4217 line at the bottom. */
4218 if (from_y + run->height > bottom_y)
4219 height = bottom_y - from_y;
4220 else
4221 height = run->height;
4223 else
4225 /* Scrolling down. Make sure we don't copy over the mode line.
4226 at the bottom. */
4227 if (to_y + run->height > bottom_y)
4228 height = bottom_y - to_y;
4229 else
4230 height = run->height;
4233 block_input ();
4235 /* Cursor off. Will be switched on again in x_update_window_end. */
4236 x_clear_cursor (w);
4238 #ifdef USE_CAIRO
4239 SET_FRAME_GARBAGED (f);
4240 #else
4241 XCopyArea (FRAME_X_DISPLAY (f),
4242 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4243 f->output_data.x->normal_gc,
4244 x, from_y,
4245 width, height,
4246 x, to_y);
4247 #endif
4249 unblock_input ();
4254 /***********************************************************************
4255 Exposure Events
4256 ***********************************************************************/
4259 static void
4260 frame_highlight (struct frame *f)
4262 /* We used to only do this if Vx_no_window_manager was non-nil, but
4263 the ICCCM (section 4.1.6) says that the window's border pixmap
4264 and border pixel are window attributes which are "private to the
4265 client", so we can always change it to whatever we want. */
4266 block_input ();
4267 /* I recently started to get errors in this XSetWindowBorder, depending on
4268 the window-manager in use, tho something more is at play since I've been
4269 using that same window-manager binary for ever. Let's not crash just
4270 because of this (bug#9310). */
4271 x_catch_errors (FRAME_X_DISPLAY (f));
4272 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4273 f->output_data.x->border_pixel);
4274 x_uncatch_errors ();
4275 unblock_input ();
4276 x_update_cursor (f, true);
4277 x_set_frame_alpha (f);
4280 static void
4281 frame_unhighlight (struct frame *f)
4283 /* We used to only do this if Vx_no_window_manager was non-nil, but
4284 the ICCCM (section 4.1.6) says that the window's border pixmap
4285 and border pixel are window attributes which are "private to the
4286 client", so we can always change it to whatever we want. */
4287 block_input ();
4288 /* Same as above for XSetWindowBorder (bug#9310). */
4289 x_catch_errors (FRAME_X_DISPLAY (f));
4290 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4291 f->output_data.x->border_tile);
4292 x_uncatch_errors ();
4293 unblock_input ();
4294 x_update_cursor (f, true);
4295 x_set_frame_alpha (f);
4298 /* The focus has changed. Update the frames as necessary to reflect
4299 the new situation. Note that we can't change the selected frame
4300 here, because the Lisp code we are interrupting might become confused.
4301 Each event gets marked with the frame in which it occurred, so the
4302 Lisp code can tell when the switch took place by examining the events. */
4304 static void
4305 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4307 struct frame *old_focus = dpyinfo->x_focus_frame;
4309 if (frame != dpyinfo->x_focus_frame)
4311 /* Set this before calling other routines, so that they see
4312 the correct value of x_focus_frame. */
4313 dpyinfo->x_focus_frame = frame;
4315 if (old_focus && old_focus->auto_lower)
4316 x_lower_frame (old_focus);
4318 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4319 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4320 else
4321 dpyinfo->x_pending_autoraise_frame = NULL;
4324 x_frame_rehighlight (dpyinfo);
4327 /* Handle FocusIn and FocusOut state changes for FRAME.
4328 If FRAME has focus and there exists more than one frame, puts
4329 a FOCUS_IN_EVENT into *BUFP. */
4331 static void
4332 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4334 if (type == FocusIn)
4336 if (dpyinfo->x_focus_event_frame != frame)
4338 x_new_focus_frame (dpyinfo, frame);
4339 dpyinfo->x_focus_event_frame = frame;
4341 /* Don't stop displaying the initial startup message
4342 for a switch-frame event we don't need. */
4343 /* When run as a daemon, Vterminal_frame is always NIL. */
4344 bufp->arg = (((NILP (Vterminal_frame)
4345 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4346 || EQ (Fdaemonp (), Qt))
4347 && CONSP (Vframe_list)
4348 && !NILP (XCDR (Vframe_list)))
4349 ? Qt : Qnil);
4350 bufp->kind = FOCUS_IN_EVENT;
4351 XSETFRAME (bufp->frame_or_window, frame);
4354 frame->output_data.x->focus_state |= state;
4356 #ifdef HAVE_X_I18N
4357 if (FRAME_XIC (frame))
4358 XSetICFocus (FRAME_XIC (frame));
4359 #endif
4361 else if (type == FocusOut)
4363 frame->output_data.x->focus_state &= ~state;
4365 if (dpyinfo->x_focus_event_frame == frame)
4367 dpyinfo->x_focus_event_frame = 0;
4368 x_new_focus_frame (dpyinfo, 0);
4370 bufp->kind = FOCUS_OUT_EVENT;
4371 XSETFRAME (bufp->frame_or_window, frame);
4374 #ifdef HAVE_X_I18N
4375 if (FRAME_XIC (frame))
4376 XUnsetICFocus (FRAME_XIC (frame));
4377 #endif
4378 if (frame->pointer_invisible)
4379 XTtoggle_invisible_pointer (frame, false);
4383 /* Return the Emacs frame-object corresponding to an X window.
4384 It could be the frame's main window or an icon window. */
4386 static struct frame *
4387 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4389 Lisp_Object tail, frame;
4390 struct frame *f;
4392 if (wdesc == None)
4393 return NULL;
4395 FOR_EACH_FRAME (tail, frame)
4397 f = XFRAME (frame);
4398 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4399 continue;
4400 if (f->output_data.x->hourglass_window == wdesc)
4401 return f;
4402 #ifdef USE_X_TOOLKIT
4403 if ((f->output_data.x->edit_widget
4404 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4405 /* A tooltip frame? */
4406 || (!f->output_data.x->edit_widget
4407 && FRAME_X_WINDOW (f) == wdesc)
4408 || f->output_data.x->icon_desc == wdesc)
4409 return f;
4410 #else /* not USE_X_TOOLKIT */
4411 #ifdef USE_GTK
4412 if (f->output_data.x->edit_widget)
4414 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4415 struct x_output *x = f->output_data.x;
4416 if (gwdesc != 0 && gwdesc == x->edit_widget)
4417 return f;
4419 #endif /* USE_GTK */
4420 if (FRAME_X_WINDOW (f) == wdesc
4421 || f->output_data.x->icon_desc == wdesc)
4422 return f;
4423 #endif /* not USE_X_TOOLKIT */
4425 return 0;
4428 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4430 /* Like x_window_to_frame but also compares the window with the widget's
4431 windows. */
4433 static struct frame *
4434 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4436 Lisp_Object tail, frame;
4437 struct frame *f, *found = NULL;
4438 struct x_output *x;
4440 if (wdesc == None)
4441 return NULL;
4443 FOR_EACH_FRAME (tail, frame)
4445 if (found)
4446 break;
4447 f = XFRAME (frame);
4448 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4450 /* This frame matches if the window is any of its widgets. */
4451 x = f->output_data.x;
4452 if (x->hourglass_window == wdesc)
4453 found = f;
4454 else if (x->widget)
4456 #ifdef USE_GTK
4457 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4458 if (gwdesc != 0
4459 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4460 found = f;
4461 #else
4462 if (wdesc == XtWindow (x->widget)
4463 || wdesc == XtWindow (x->column_widget)
4464 || wdesc == XtWindow (x->edit_widget))
4465 found = f;
4466 /* Match if the window is this frame's menubar. */
4467 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4468 found = f;
4469 #endif
4471 else if (FRAME_X_WINDOW (f) == wdesc)
4472 /* A tooltip frame. */
4473 found = f;
4477 return found;
4480 /* Likewise, but consider only the menu bar widget. */
4482 static struct frame *
4483 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4484 const XEvent *event)
4486 Window wdesc = event->xany.window;
4487 Lisp_Object tail, frame;
4488 struct frame *f;
4489 struct x_output *x;
4491 if (wdesc == None)
4492 return NULL;
4494 FOR_EACH_FRAME (tail, frame)
4496 f = XFRAME (frame);
4497 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4498 continue;
4499 x = f->output_data.x;
4500 #ifdef USE_GTK
4501 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4502 return f;
4503 #else
4504 /* Match if the window is this frame's menubar. */
4505 if (x->menubar_widget
4506 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4507 return f;
4508 #endif
4510 return 0;
4513 /* Return the frame whose principal (outermost) window is WDESC.
4514 If WDESC is some other (smaller) window, we return 0. */
4516 struct frame *
4517 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4519 Lisp_Object tail, frame;
4520 struct frame *f;
4521 struct x_output *x;
4523 if (wdesc == None)
4524 return NULL;
4526 FOR_EACH_FRAME (tail, frame)
4528 f = XFRAME (frame);
4529 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4530 continue;
4531 x = f->output_data.x;
4533 if (x->widget)
4535 /* This frame matches if the window is its topmost widget. */
4536 #ifdef USE_GTK
4537 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4538 if (gwdesc == x->widget)
4539 return f;
4540 #else
4541 if (wdesc == XtWindow (x->widget))
4542 return f;
4543 #endif
4545 else if (FRAME_X_WINDOW (f) == wdesc)
4546 /* Tooltip frame. */
4547 return f;
4549 return 0;
4552 #else /* !USE_X_TOOLKIT && !USE_GTK */
4554 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4555 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4557 #endif /* USE_X_TOOLKIT || USE_GTK */
4559 /* The focus may have changed. Figure out if it is a real focus change,
4560 by checking both FocusIn/Out and Enter/LeaveNotify events.
4562 Returns FOCUS_IN_EVENT event in *BUFP. */
4564 static void
4565 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4566 const XEvent *event, struct input_event *bufp)
4568 if (!frame)
4569 return;
4571 switch (event->type)
4573 case EnterNotify:
4574 case LeaveNotify:
4576 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4577 int focus_state
4578 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4580 if (event->xcrossing.detail != NotifyInferior
4581 && event->xcrossing.focus
4582 && ! (focus_state & FOCUS_EXPLICIT))
4583 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4584 FOCUS_IMPLICIT,
4585 dpyinfo, frame, bufp);
4587 break;
4589 case FocusIn:
4590 case FocusOut:
4591 x_focus_changed (event->type,
4592 (event->xfocus.detail == NotifyPointer ?
4593 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4594 dpyinfo, frame, bufp);
4595 break;
4597 case ClientMessage:
4598 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4600 enum xembed_message msg = event->xclient.data.l[1];
4601 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4602 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4604 break;
4609 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4610 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4612 void
4613 x_mouse_leave (struct x_display_info *dpyinfo)
4615 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4617 #endif
4619 /* The focus has changed, or we have redirected a frame's focus to
4620 another frame (this happens when a frame uses a surrogate
4621 mini-buffer frame). Shift the highlight as appropriate.
4623 The FRAME argument doesn't necessarily have anything to do with which
4624 frame is being highlighted or un-highlighted; we only use it to find
4625 the appropriate X display info. */
4627 static void
4628 XTframe_rehighlight (struct frame *frame)
4630 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4633 static void
4634 x_frame_rehighlight (struct x_display_info *dpyinfo)
4636 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4638 if (dpyinfo->x_focus_frame)
4640 dpyinfo->x_highlight_frame
4641 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4642 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4643 : dpyinfo->x_focus_frame);
4644 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4646 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4647 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4650 else
4651 dpyinfo->x_highlight_frame = 0;
4653 if (dpyinfo->x_highlight_frame != old_highlight)
4655 if (old_highlight)
4656 frame_unhighlight (old_highlight);
4657 if (dpyinfo->x_highlight_frame)
4658 frame_highlight (dpyinfo->x_highlight_frame);
4664 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4666 /* Initialize mode_switch_bit and modifier_meaning. */
4667 static void
4668 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4670 int min_code, max_code;
4671 KeySym *syms;
4672 int syms_per_code;
4673 XModifierKeymap *mods;
4675 dpyinfo->meta_mod_mask = 0;
4676 dpyinfo->shift_lock_mask = 0;
4677 dpyinfo->alt_mod_mask = 0;
4678 dpyinfo->super_mod_mask = 0;
4679 dpyinfo->hyper_mod_mask = 0;
4681 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4683 syms = XGetKeyboardMapping (dpyinfo->display,
4684 min_code, max_code - min_code + 1,
4685 &syms_per_code);
4686 mods = XGetModifierMapping (dpyinfo->display);
4688 /* Scan the modifier table to see which modifier bits the Meta and
4689 Alt keysyms are on. */
4691 int row, col; /* The row and column in the modifier table. */
4692 bool found_alt_or_meta;
4694 for (row = 3; row < 8; row++)
4696 found_alt_or_meta = false;
4697 for (col = 0; col < mods->max_keypermod; col++)
4699 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4701 /* Zeroes are used for filler. Skip them. */
4702 if (code == 0)
4703 continue;
4705 /* Are any of this keycode's keysyms a meta key? */
4707 int code_col;
4709 for (code_col = 0; code_col < syms_per_code; code_col++)
4711 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4713 switch (sym)
4715 case XK_Meta_L:
4716 case XK_Meta_R:
4717 found_alt_or_meta = true;
4718 dpyinfo->meta_mod_mask |= (1 << row);
4719 break;
4721 case XK_Alt_L:
4722 case XK_Alt_R:
4723 found_alt_or_meta = true;
4724 dpyinfo->alt_mod_mask |= (1 << row);
4725 break;
4727 case XK_Hyper_L:
4728 case XK_Hyper_R:
4729 if (!found_alt_or_meta)
4730 dpyinfo->hyper_mod_mask |= (1 << row);
4731 code_col = syms_per_code;
4732 col = mods->max_keypermod;
4733 break;
4735 case XK_Super_L:
4736 case XK_Super_R:
4737 if (!found_alt_or_meta)
4738 dpyinfo->super_mod_mask |= (1 << row);
4739 code_col = syms_per_code;
4740 col = mods->max_keypermod;
4741 break;
4743 case XK_Shift_Lock:
4744 /* Ignore this if it's not on the lock modifier. */
4745 if (!found_alt_or_meta && ((1 << row) == LockMask))
4746 dpyinfo->shift_lock_mask = LockMask;
4747 code_col = syms_per_code;
4748 col = mods->max_keypermod;
4749 break;