Don't add `search-failed' to ignored errors in info.el (Bug#6106)
[emacs.git] / src / xterm.c
blob4f9eff6c5e6a0e02118d1aad5c1177b08c662c83
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 #ifdef USE_CAIRO
27 #include <math.h>
28 #endif
30 #include "lisp.h"
31 #include "blockinput.h"
33 /* This may include sys/types.h, and that somehow loses
34 if this is not done before the other system files. */
35 #include "xterm.h"
36 #include <X11/cursorfont.h>
38 /* If we have Xfixes extension, use it for pointer blanking. */
39 #ifdef HAVE_XFIXES
40 #include <X11/extensions/Xfixes.h>
41 #endif
43 /* Using Xft implies that XRender is available. */
44 #ifdef HAVE_XFT
45 #include <X11/extensions/Xrender.h>
46 #endif
48 #ifdef HAVE_XDBE
49 #include <X11/extensions/Xdbe.h>
50 #endif
52 /* Load sys/types.h if not already loaded.
53 In some systems loading it twice is suicidal. */
54 #ifndef makedev
55 #include <sys/types.h>
56 #endif /* makedev */
58 #include <sys/ioctl.h>
60 #include "systime.h"
62 #include <fcntl.h>
63 #include <errno.h>
64 #include <sys/stat.h>
65 #include "character.h"
66 #include "coding.h"
67 #include "composite.h"
68 #include "frame.h"
69 #include "dispextern.h"
70 #include "xwidget.h"
71 #include "fontset.h"
72 #include "termhooks.h"
73 #include "termopts.h"
74 #include "termchar.h"
75 #include "emacs-icon.h"
76 #include "buffer.h"
77 #include "window.h"
78 #include "keyboard.h"
79 #include "atimer.h"
80 #include "font.h"
81 #include "xsettings.h"
82 #include "sysselect.h"
83 #include "menu.h"
85 #ifdef USE_X_TOOLKIT
86 #include <X11/Shell.h>
87 #endif
89 #include <unistd.h>
91 #ifdef USE_GTK
92 #include "gtkutil.h"
93 #ifdef HAVE_GTK3
94 #include <X11/Xproto.h>
95 #endif
96 #endif
98 #if defined (USE_LUCID) || defined (USE_MOTIF)
99 #include "../lwlib/xlwmenu.h"
100 #endif
102 #ifdef USE_X_TOOLKIT
104 /* Include toolkit specific headers for the scroll bar widget. */
106 #ifdef USE_TOOLKIT_SCROLL_BARS
107 #if defined USE_MOTIF
108 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
109 #include <Xm/ScrollBar.h>
110 #else /* !USE_MOTIF i.e. use Xaw */
112 #ifdef HAVE_XAW3D
113 #include <X11/Xaw3d/Simple.h>
114 #include <X11/Xaw3d/Scrollbar.h>
115 #include <X11/Xaw3d/ThreeD.h>
116 #else /* !HAVE_XAW3D */
117 #include <X11/Xaw/Simple.h>
118 #include <X11/Xaw/Scrollbar.h>
119 #endif /* !HAVE_XAW3D */
120 #ifndef XtNpickTop
121 #define XtNpickTop "pickTop"
122 #endif /* !XtNpickTop */
123 #endif /* !USE_MOTIF */
124 #endif /* USE_TOOLKIT_SCROLL_BARS */
126 #endif /* USE_X_TOOLKIT */
128 #ifdef USE_X_TOOLKIT
129 #include "widget.h"
130 #ifndef XtNinitialState
131 #define XtNinitialState "initialState"
132 #endif
133 #endif
135 #include "bitmaps/gray.xbm"
137 #ifdef HAVE_XKB
138 #include <X11/XKBlib.h>
139 #endif
141 /* Default to using XIM if available. */
142 #ifdef USE_XIM
143 bool use_xim = true;
144 #else
145 bool use_xim = false; /* configure --without-xim */
146 #endif
148 /* Non-zero means that a HELP_EVENT has been generated since Emacs
149 start. */
151 static bool any_help_event_p;
153 /* This is a chain of structures for all the X displays currently in
154 use. */
156 struct x_display_info *x_display_list;
158 #ifdef USE_X_TOOLKIT
160 /* The application context for Xt use. */
161 XtAppContext Xt_app_con;
162 static String Xt_default_resources[] = {0};
164 /* Non-zero means user is interacting with a toolkit scroll bar. */
165 static bool toolkit_scroll_bar_interaction;
167 #endif /* USE_X_TOOLKIT */
169 /* Non-zero timeout value means ignore next mouse click if it arrives
170 before that timeout elapses (i.e. as part of the same sequence of
171 events resulting from clicking on a frame to select it). */
173 static Time ignore_next_mouse_click_timeout;
175 /* Used locally within XTread_socket. */
177 static int x_noop_count;
179 #ifdef USE_GTK
180 /* The name of the Emacs icon file. */
181 static Lisp_Object xg_default_icon_file;
182 #endif
184 /* Some functions take this as char *, not const char *. */
185 static char emacs_class[] = EMACS_CLASS;
187 enum xembed_info
189 XEMBED_MAPPED = 1 << 0
192 enum xembed_message
194 XEMBED_EMBEDDED_NOTIFY = 0,
195 XEMBED_WINDOW_ACTIVATE = 1,
196 XEMBED_WINDOW_DEACTIVATE = 2,
197 XEMBED_REQUEST_FOCUS = 3,
198 XEMBED_FOCUS_IN = 4,
199 XEMBED_FOCUS_OUT = 5,
200 XEMBED_FOCUS_NEXT = 6,
201 XEMBED_FOCUS_PREV = 7,
203 XEMBED_MODALITY_ON = 10,
204 XEMBED_MODALITY_OFF = 11,
205 XEMBED_REGISTER_ACCELERATOR = 12,
206 XEMBED_UNREGISTER_ACCELERATOR = 13,
207 XEMBED_ACTIVATE_ACCELERATOR = 14
210 static void x_free_cr_resources (struct frame *);
211 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
212 static void x_raise_frame (struct frame *);
213 static void x_lower_frame (struct frame *);
214 static int x_io_error_quitter (Display *);
215 static struct terminal *x_create_terminal (struct x_display_info *);
216 static void x_frame_rehighlight (struct x_display_info *);
218 static void x_clip_to_row (struct window *, struct glyph_row *,
219 enum glyph_row_area, GC);
220 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
221 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
222 enum scroll_bar_part *,
223 Lisp_Object *, Lisp_Object *,
224 Time *);
225 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
226 enum scroll_bar_part *,
227 Lisp_Object *, Lisp_Object *,
228 Time *);
229 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
230 static void x_check_fullscreen (struct frame *);
231 static void x_check_expected_move (struct frame *, int, int);
232 static void x_sync_with_move (struct frame *, int, int, bool);
233 static int handle_one_xevent (struct x_display_info *,
234 const XEvent *, int *,
235 struct input_event *);
236 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
237 static int x_dispatch_event (XEvent *, Display *);
238 #endif
239 static void x_wm_set_window_state (struct frame *, int);
240 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
241 static void x_initialize (void);
243 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
245 /* Flush display of frame F. */
247 static void
248 x_flush (struct frame *f)
250 eassert (f && FRAME_X_P (f));
251 /* Don't call XFlush when it is not safe to redisplay; the X
252 connection may be broken. */
253 if (!NILP (Vinhibit_redisplay))
254 return;
256 block_input ();
257 XFlush (FRAME_X_DISPLAY (f));
258 unblock_input ();
262 /* Remove calls to XFlush by defining XFlush to an empty replacement.
263 Calls to XFlush should be unnecessary because the X output buffer
264 is flushed automatically as needed by calls to XPending,
265 XNextEvent, or XWindowEvent according to the XFlush man page.
266 XTread_socket calls XPending. Removing XFlush improves
267 performance. */
269 #define XFlush(DISPLAY) (void) 0
272 /***********************************************************************
273 Debugging
274 ***********************************************************************/
276 #if false
278 /* This is a function useful for recording debugging information about
279 the sequence of occurrences in this file. */
281 struct record
283 char *locus;
284 int type;
287 struct record event_record[100];
289 int event_record_index;
291 void
292 record_event (char *locus, int type)
294 if (event_record_index == ARRAYELTS (event_record))
295 event_record_index = 0;
297 event_record[event_record_index].locus = locus;
298 event_record[event_record_index].type = type;
299 event_record_index++;
302 #endif
304 #ifdef USE_CAIRO
306 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
307 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
309 static struct x_gc_ext_data *
310 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
312 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
313 XEDataObject object;
314 XExtData **head, *ext_data;
316 object.gc = gc;
317 head = XEHeadOfExtensionList (object);
318 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
319 if (ext_data == NULL)
321 if (!create_if_not_found_p)
322 return NULL;
323 else
325 ext_data = xzalloc (sizeof (*ext_data));
326 ext_data->number = dpyinfo->ext_codes->extension;
327 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
328 XAddToExtensionList (head, ext_data);
331 return (struct x_gc_ext_data *) ext_data->private_data;
334 static void
335 x_extension_initialize (struct x_display_info *dpyinfo)
337 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
339 dpyinfo->ext_codes = ext_codes;
342 static void
343 x_cr_destroy_surface (struct frame *f)
345 if (FRAME_CR_SURFACE (f))
347 cairo_t *cr = FRAME_CR_CONTEXT (f);
348 cairo_surface_destroy (FRAME_CR_SURFACE (f));
349 FRAME_CR_SURFACE (f) = 0;
350 if (cr) cairo_destroy (cr);
351 FRAME_CR_CONTEXT (f) = NULL;
355 cairo_t *
356 x_begin_cr_clip (struct frame *f, GC gc)
358 cairo_t *cr = FRAME_CR_CONTEXT (f);
360 if (!cr)
363 if (! FRAME_CR_SURFACE (f))
365 cairo_surface_t *surface;
366 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
367 FRAME_X_DRAWABLE (f),
368 FRAME_DISPLAY_INFO (f)->visual,
369 FRAME_PIXEL_WIDTH (f),
370 FRAME_PIXEL_HEIGHT (f));
371 cr = cairo_create (surface);
372 cairo_surface_destroy (surface);
374 else
375 cr = cairo_create (FRAME_CR_SURFACE (f));
376 FRAME_CR_CONTEXT (f) = cr;
378 cairo_save (cr);
380 if (gc)
382 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
384 if (gc_ext && gc_ext->n_clip_rects)
386 int i;
388 for (i = 0; i < gc_ext->n_clip_rects; i++)
389 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
390 gc_ext->clip_rects[i].y,
391 gc_ext->clip_rects[i].width,
392 gc_ext->clip_rects[i].height);
393 cairo_clip (cr);
397 return cr;
400 void
401 x_end_cr_clip (struct frame *f)
403 cairo_restore (FRAME_CR_CONTEXT (f));
406 void
407 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
409 XGCValues xgcv;
410 XColor color;
412 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
413 color.pixel = xgcv.foreground;
414 x_query_color (f, &color);
415 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
416 color.green / 65535.0, color.blue / 65535.0);
419 void
420 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
422 XGCValues xgcv;
423 XColor color;
425 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
426 color.pixel = xgcv.background;
427 x_query_color (f, &color);
428 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
429 color.green / 65535.0, color.blue / 65535.0);
432 /* Fringe bitmaps. */
434 static int max_fringe_bmp = 0;
435 static cairo_pattern_t **fringe_bmp = 0;
437 static void
438 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
440 int i, stride;
441 cairo_surface_t *surface;
442 unsigned char *data;
443 cairo_pattern_t *pattern;
445 if (which >= max_fringe_bmp)
447 i = max_fringe_bmp;
448 max_fringe_bmp = which + 20;
449 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
450 while (i < max_fringe_bmp)
451 fringe_bmp[i++] = 0;
454 block_input ();
456 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
457 stride = cairo_image_surface_get_stride (surface);
458 data = cairo_image_surface_get_data (surface);
460 for (i = 0; i < h; i++)
462 *((unsigned short *) data) = bits[i];
463 data += stride;
466 cairo_surface_mark_dirty (surface);
467 pattern = cairo_pattern_create_for_surface (surface);
468 cairo_surface_destroy (surface);
470 unblock_input ();
472 fringe_bmp[which] = pattern;
475 static void
476 x_cr_destroy_fringe_bitmap (int which)
478 if (which >= max_fringe_bmp)
479 return;
481 if (fringe_bmp[which])
483 block_input ();
484 cairo_pattern_destroy (fringe_bmp[which]);
485 unblock_input ();
487 fringe_bmp[which] = 0;
490 static void
491 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
492 int src_x, int src_y, int width, int height,
493 int dest_x, int dest_y, bool overlay_p)
495 cairo_t *cr;
496 cairo_matrix_t matrix;
497 cairo_surface_t *surface;
498 cairo_format_t format;
500 cr = x_begin_cr_clip (f, gc);
501 if (overlay_p)
502 cairo_rectangle (cr, dest_x, dest_y, width, height);
503 else
505 x_set_cr_source_with_gc_background (f, gc);
506 cairo_rectangle (cr, dest_x, dest_y, width, height);
507 cairo_fill_preserve (cr);
509 cairo_clip (cr);
510 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
511 cairo_pattern_set_matrix (image, &matrix);
512 cairo_pattern_get_surface (image, &surface);
513 format = cairo_image_surface_get_format (surface);
514 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
516 cairo_set_source (cr, image);
517 cairo_fill (cr);
519 else
521 x_set_cr_source_with_gc_foreground (f, gc);
522 cairo_mask (cr, image);
524 x_end_cr_clip (f);
527 void
528 x_cr_draw_frame (cairo_t *cr, struct frame *f)
530 int width, height;
532 width = FRAME_PIXEL_WIDTH (f);
533 height = FRAME_PIXEL_HEIGHT (f);
535 x_free_cr_resources (f);
536 FRAME_CR_CONTEXT (f) = cr;
537 x_clear_area (f, 0, 0, width, height);
538 expose_frame (f, 0, 0, width, height);
539 FRAME_CR_CONTEXT (f) = NULL;
542 static cairo_status_t
543 x_cr_accumulate_data (void *closure, const unsigned char *data,
544 unsigned int length)
546 Lisp_Object *acc = (Lisp_Object *) closure;
548 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
550 return CAIRO_STATUS_SUCCESS;
553 static void
554 x_cr_destroy (Lisp_Object arg)
556 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
558 block_input ();
559 cairo_destroy (cr);
560 unblock_input ();
563 Lisp_Object
564 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
566 struct frame *f;
567 cairo_surface_t *surface;
568 cairo_t *cr;
569 int width, height;
570 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
571 Lisp_Object acc = Qnil;
572 int count = SPECPDL_INDEX ();
574 specbind (Qredisplay_dont_pause, Qt);
575 redisplay_preserve_echo_area (31);
577 f = XFRAME (XCAR (frames));
578 frames = XCDR (frames);
579 width = FRAME_PIXEL_WIDTH (f);
580 height = FRAME_PIXEL_HEIGHT (f);
582 block_input ();
583 #ifdef CAIRO_HAS_PDF_SURFACE
584 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
586 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
587 width, height);
588 surface_set_size_func = cairo_pdf_surface_set_size;
590 else
591 #endif
592 #ifdef CAIRO_HAS_PNG_FUNCTIONS
593 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
594 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
595 else
596 #endif
597 #ifdef CAIRO_HAS_PS_SURFACE
598 if (surface_type == CAIRO_SURFACE_TYPE_PS)
600 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
601 width, height);
602 surface_set_size_func = cairo_ps_surface_set_size;
604 else
605 #endif
606 #ifdef CAIRO_HAS_SVG_SURFACE
607 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
608 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
609 width, height);
610 else
611 #endif
612 abort ();
614 cr = cairo_create (surface);
615 cairo_surface_destroy (surface);
616 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
618 while (1)
620 x_free_cr_resources (f);
621 FRAME_CR_CONTEXT (f) = cr;
622 x_clear_area (f, 0, 0, width, height);
623 expose_frame (f, 0, 0, width, height);
624 FRAME_CR_CONTEXT (f) = NULL;
626 if (NILP (frames))
627 break;
629 cairo_surface_show_page (surface);
630 f = XFRAME (XCAR (frames));
631 frames = XCDR (frames);
632 width = FRAME_PIXEL_WIDTH (f);
633 height = FRAME_PIXEL_HEIGHT (f);
634 if (surface_set_size_func)
635 (*surface_set_size_func) (surface, width, height);
637 unblock_input ();
638 maybe_quit ();
639 block_input ();
642 #ifdef CAIRO_HAS_PNG_FUNCTIONS
643 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
645 cairo_surface_flush (surface);
646 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
648 #endif
649 unblock_input ();
651 unbind_to (count, Qnil);
653 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
656 #endif /* USE_CAIRO */
658 static void
659 x_free_cr_resources (struct frame *f)
661 #ifdef USE_CAIRO
662 if (f == NULL)
664 Lisp_Object rest, frame;
665 FOR_EACH_FRAME (rest, frame)
666 if (FRAME_X_P (XFRAME (frame)))
667 x_free_cr_resources (XFRAME (frame));
669 else
671 cairo_t *cr = FRAME_CR_CONTEXT (f);
673 if (cr)
675 cairo_surface_t *surface = cairo_get_target (cr);
677 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
679 cairo_destroy (cr);
680 FRAME_CR_CONTEXT (f) = NULL;
684 #endif
687 static void
688 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
690 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
691 #ifdef USE_CAIRO
692 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
695 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
697 gc_ext->n_clip_rects = n;
698 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
700 #endif
703 static void
704 x_reset_clip_rectangles (struct frame *f, GC gc)
706 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
707 #ifdef USE_CAIRO
709 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
711 if (gc_ext)
712 gc_ext->n_clip_rects = 0;
714 #endif
717 static void
718 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
720 #ifdef USE_CAIRO
721 cairo_t *cr;
723 cr = x_begin_cr_clip (f, gc);
724 x_set_cr_source_with_gc_foreground (f, gc);
725 cairo_rectangle (cr, x, y, width, height);
726 cairo_fill (cr);
727 x_end_cr_clip (f);
728 #else
729 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
730 gc, x, y, width, height);
731 #endif
734 static void
735 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
737 #ifdef USE_CAIRO
738 cairo_t *cr;
740 cr = x_begin_cr_clip (f, gc);
741 x_set_cr_source_with_gc_foreground (f, gc);
742 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
743 cairo_set_line_width (cr, 1);
744 cairo_stroke (cr);
745 x_end_cr_clip (f);
746 #else
747 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
748 gc, x, y, width, height);
749 #endif
752 static void
753 x_clear_window (struct frame *f)
755 #ifdef USE_CAIRO
756 cairo_t *cr;
758 cr = x_begin_cr_clip (f, NULL);
759 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
760 cairo_paint (cr);
761 x_end_cr_clip (f);
762 #else
763 if (FRAME_X_DOUBLE_BUFFERED_P (f))
764 x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
765 else
766 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
767 #endif
770 #ifdef USE_CAIRO
771 static void
772 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
773 int width, int height, int top_p)
775 cairo_t *cr;
777 cr = x_begin_cr_clip (f, gc);
778 x_set_cr_source_with_gc_foreground (f, gc);
779 cairo_move_to (cr, top_p ? x : x + height, y);
780 cairo_line_to (cr, x, y + height);
781 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
782 cairo_line_to (cr, x + width, y);
783 cairo_fill (cr);
784 x_end_cr_clip (f);
787 enum corners
789 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
790 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
791 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
792 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
793 CORNER_LAST
796 static void
797 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
798 int width, int height,
799 double radius, double margin, int corners)
801 cairo_t *cr;
802 int i;
804 cr = x_begin_cr_clip (f, gc);
805 x_set_cr_source_with_gc_background (f, gc);
806 for (i = 0; i < CORNER_LAST; i++)
807 if (corners & (1 << i))
809 double xm, ym, xc, yc;
811 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
812 xm = x - margin, xc = xm + radius;
813 else
814 xm = x + width + margin, xc = xm - radius;
815 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
816 ym = y - margin, yc = ym + radius;
817 else
818 ym = y + height + margin, yc = ym - radius;
820 cairo_move_to (cr, xm, ym);
821 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
823 cairo_clip (cr);
824 cairo_rectangle (cr, x, y, width, height);
825 cairo_fill (cr);
826 x_end_cr_clip (f);
829 static void
830 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
831 int width, int height, int wave_length)
833 cairo_t *cr;
834 double dx = wave_length, dy = height - 1;
835 int xoffset, n;
837 cr = x_begin_cr_clip (f, gc);
838 x_set_cr_source_with_gc_foreground (f, gc);
839 cairo_rectangle (cr, x, y, width, height);
840 cairo_clip (cr);
842 if (x >= 0)
844 xoffset = x % (wave_length * 2);
845 if (xoffset == 0)
846 xoffset = wave_length * 2;
848 else
849 xoffset = x % (wave_length * 2) + wave_length * 2;
850 n = (width + xoffset) / wave_length + 1;
851 if (xoffset > wave_length)
853 xoffset -= wave_length;
854 --n;
855 y += height - 1;
856 dy = -dy;
859 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
860 while (--n >= 0)
862 cairo_rel_line_to (cr, dx, dy);
863 dy = -dy;
865 cairo_set_line_width (cr, 1);
866 cairo_stroke (cr);
867 x_end_cr_clip (f);
869 #endif
872 /* Return the struct x_display_info corresponding to DPY. */
874 struct x_display_info *
875 x_display_info_for_display (Display *dpy)
877 struct x_display_info *dpyinfo;
879 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
880 if (dpyinfo->display == dpy)
881 return dpyinfo;
883 return 0;
886 static Window
887 x_find_topmost_parent (struct frame *f)
889 struct x_output *x = f->output_data.x;
890 Window win = None, wi = x->parent_desc;
891 Display *dpy = FRAME_X_DISPLAY (f);
893 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
895 Window root;
896 Window *children;
897 unsigned int nchildren;
899 win = wi;
900 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
901 XFree (children);
902 else
903 break;
906 return win;
909 #define OPAQUE 0xffffffff
911 void
912 x_set_frame_alpha (struct frame *f)
914 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
915 Display *dpy = FRAME_X_DISPLAY (f);
916 Window win = FRAME_OUTER_WINDOW (f);
917 double alpha = 1.0;
918 double alpha_min = 1.0;
919 unsigned long opac;
920 Window parent;
922 if (dpyinfo->x_highlight_frame == f)
923 alpha = f->alpha[0];
924 else
925 alpha = f->alpha[1];
927 if (FLOATP (Vframe_alpha_lower_limit))
928 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
929 else if (INTEGERP (Vframe_alpha_lower_limit))
930 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
932 if (alpha < 0.0)
933 return;
934 else if (alpha > 1.0)
935 alpha = 1.0;
936 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
937 alpha = alpha_min;
939 opac = alpha * OPAQUE;
941 x_catch_errors (dpy);
943 /* If there is a parent from the window manager, put the property there
944 also, to work around broken window managers that fail to do that.
945 Do this unconditionally as this function is called on reparent when
946 alpha has not changed on the frame. */
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);
954 /* return unless necessary */
956 unsigned char *data;
957 Atom actual;
958 int rc, format;
959 unsigned long n, left;
961 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
962 0, 1, False, XA_CARDINAL,
963 &actual, &format, &n, &left,
964 &data);
966 if (rc == Success && actual != None)
968 unsigned long value = *(unsigned long *)data;
969 XFree (data);
970 if (value == opac)
972 x_uncatch_errors ();
973 return;
978 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
979 XA_CARDINAL, 32, PropModeReplace,
980 (unsigned char *) &opac, 1);
981 x_uncatch_errors ();
984 /***********************************************************************
985 Starting and ending an update
986 ***********************************************************************/
988 /* Start an update of frame F. This function is installed as a hook
989 for update_begin, i.e. it is called when update_begin is called.
990 This function is called prior to calls to x_update_window_begin for
991 each window being updated. Currently, there is nothing to do here
992 because all interesting stuff is done on a window basis. */
994 static void
995 x_update_begin (struct frame *f)
997 #ifdef USE_CAIRO
998 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
999 && ! FRAME_VISIBLE_P (f))
1000 return;
1002 if (! FRAME_CR_SURFACE (f))
1004 int width, height;
1005 #ifdef USE_GTK
1006 if (FRAME_GTK_WIDGET (f))
1008 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1009 width = gdk_window_get_width (w);
1010 height = gdk_window_get_height (w);
1012 else
1013 #endif
1015 width = FRAME_PIXEL_WIDTH (f);
1016 height = FRAME_PIXEL_HEIGHT (f);
1017 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1018 height += FRAME_TOOL_BAR_HEIGHT (f);
1019 if (! FRAME_EXTERNAL_MENU_BAR (f))
1020 height += FRAME_MENU_BAR_HEIGHT (f);
1023 if (width > 0 && height > 0)
1025 block_input();
1026 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1027 (CAIRO_FORMAT_ARGB32, width, height);
1028 unblock_input();
1031 #endif /* USE_CAIRO */
1034 /* Start update of window W. */
1036 static void
1037 x_update_window_begin (struct window *w)
1039 struct frame *f = XFRAME (WINDOW_FRAME (w));
1040 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1042 w->output_cursor = w->cursor;
1044 block_input ();
1046 if (f == hlinfo->mouse_face_mouse_frame)
1048 /* Don't do highlighting for mouse motion during the update. */
1049 hlinfo->mouse_face_defer = true;
1051 /* If F needs to be redrawn, simply forget about any prior mouse
1052 highlighting. */
1053 if (FRAME_GARBAGED_P (f))
1054 hlinfo->mouse_face_window = Qnil;
1057 unblock_input ();
1061 /* Draw a vertical window border from (x,y0) to (x,y1) */
1063 static void
1064 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1066 struct frame *f = XFRAME (WINDOW_FRAME (w));
1067 struct face *face;
1069 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1070 if (face)
1071 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1072 face->foreground);
1074 #ifdef USE_CAIRO
1075 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1076 #else
1077 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1078 f->output_data.x->normal_gc, x, y0, x, y1);
1079 #endif
1082 /* Draw a window divider from (x0,y0) to (x1,y1) */
1084 static void
1085 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1087 struct frame *f = XFRAME (WINDOW_FRAME (w));
1088 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1089 struct face *face_first
1090 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1091 struct face *face_last
1092 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1093 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1094 unsigned long color_first = (face_first
1095 ? face_first->foreground
1096 : FRAME_FOREGROUND_PIXEL (f));
1097 unsigned long color_last = (face_last
1098 ? face_last->foreground
1099 : FRAME_FOREGROUND_PIXEL (f));
1100 Display *display = FRAME_X_DISPLAY (f);
1102 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1103 /* Vertical. */
1105 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1106 x_fill_rectangle (f, f->output_data.x->normal_gc,
1107 x0, y0, 1, y1 - y0);
1108 XSetForeground (display, f->output_data.x->normal_gc, color);
1109 x_fill_rectangle (f, f->output_data.x->normal_gc,
1110 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1111 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1112 x_fill_rectangle (f, f->output_data.x->normal_gc,
1113 x1 - 1, y0, 1, y1 - y0);
1115 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1116 /* Horizontal. */
1118 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1119 x_fill_rectangle (f, f->output_data.x->normal_gc,
1120 x0, y0, x1 - x0, 1);
1121 XSetForeground (display, f->output_data.x->normal_gc, color);
1122 x_fill_rectangle (f, f->output_data.x->normal_gc,
1123 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1124 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1125 x_fill_rectangle (f, f->output_data.x->normal_gc,
1126 x0, y1 - 1, x1 - x0, 1);
1128 else
1130 XSetForeground (display, f->output_data.x->normal_gc, color);
1131 x_fill_rectangle (f, f->output_data.x->normal_gc,
1132 x0, y0, x1 - x0, y1 - y0);
1136 /* End update of window W.
1138 Draw vertical borders between horizontally adjacent windows, and
1139 display W's cursor if CURSOR_ON_P is non-zero.
1141 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1142 glyphs in mouse-face were overwritten. In that case we have to
1143 make sure that the mouse-highlight is properly redrawn.
1145 W may be a menu bar pseudo-window in case we don't have X toolkit
1146 support. Such windows don't have a cursor, so don't display it
1147 here. */
1149 static void
1150 x_update_window_end (struct window *w, bool cursor_on_p,
1151 bool mouse_face_overwritten_p)
1153 if (!w->pseudo_window_p)
1155 block_input ();
1157 if (cursor_on_p)
1158 display_and_set_cursor (w, true,
1159 w->output_cursor.hpos, w->output_cursor.vpos,
1160 w->output_cursor.x, w->output_cursor.y);
1162 if (draw_window_fringes (w, true))
1164 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1165 x_draw_right_divider (w);
1166 else
1167 x_draw_vertical_border (w);
1170 unblock_input ();
1173 /* If a row with mouse-face was overwritten, arrange for
1174 XTframe_up_to_date to redisplay the mouse highlight. */
1175 if (mouse_face_overwritten_p)
1177 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1179 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1180 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1181 hlinfo->mouse_face_window = Qnil;
1185 /* Show the frame back buffer. If frame is double-buffered,
1186 atomically publish to the user's screen graphics updates made since
1187 the last call to show_back_buffer. */
1188 static void
1189 show_back_buffer (struct frame *f)
1191 block_input ();
1192 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1194 #ifdef HAVE_XDBE
1195 XdbeSwapInfo swap_info;
1196 memset (&swap_info, 0, sizeof (swap_info));
1197 swap_info.swap_window = FRAME_X_WINDOW (f);
1198 swap_info.swap_action = XdbeCopied;
1199 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1200 #else
1201 eassert (!"should have back-buffer only with XDBE");
1202 #endif
1204 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1205 unblock_input ();
1208 /* Updates back buffer and flushes changes to display. Called from
1209 minibuf read code. Note that we display the back buffer even if
1210 buffer flipping is blocked. */
1211 static void
1212 x_flip_and_flush (struct frame *f)
1214 block_input ();
1215 if (FRAME_X_NEED_BUFFER_FLIP (f))
1216 show_back_buffer (f);
1217 x_flush (f);
1218 unblock_input ();
1221 /* End update of frame F. This function is installed as a hook in
1222 update_end. */
1224 static void
1225 x_update_end (struct frame *f)
1227 /* Mouse highlight may be displayed again. */
1228 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1230 #ifdef USE_CAIRO
1231 if (FRAME_CR_SURFACE (f))
1233 cairo_t *cr = 0;
1234 block_input();
1235 #if defined (USE_GTK) && defined (HAVE_GTK3)
1236 if (FRAME_GTK_WIDGET (f))
1238 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1239 cr = gdk_cairo_create (w);
1241 else
1242 #endif
1244 cairo_surface_t *surface;
1245 int width = FRAME_PIXEL_WIDTH (f);
1246 int height = FRAME_PIXEL_HEIGHT (f);
1247 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1248 height += FRAME_TOOL_BAR_HEIGHT (f);
1249 if (! FRAME_EXTERNAL_MENU_BAR (f))
1250 height += FRAME_MENU_BAR_HEIGHT (f);
1251 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1252 FRAME_X_DRAWABLE (f),
1253 FRAME_DISPLAY_INFO (f)->visual,
1254 width,
1255 height);
1256 cr = cairo_create (surface);
1257 cairo_surface_destroy (surface);
1260 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1261 cairo_paint (cr);
1262 cairo_destroy (cr);
1263 unblock_input ();
1265 #endif
1267 #ifndef XFlush
1268 block_input ();
1269 XFlush (FRAME_X_DISPLAY (f));
1270 unblock_input ();
1271 #endif
1274 /* This function is called from various places in xdisp.c
1275 whenever a complete update has been performed. */
1277 static void
1278 XTframe_up_to_date (struct frame *f)
1280 eassert (FRAME_X_P (f));
1281 block_input ();
1282 FRAME_MOUSE_UPDATE (f);
1283 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1284 show_back_buffer (f);
1285 unblock_input ();
1288 static void
1289 XTbuffer_flipping_unblocked_hook (struct frame *f)
1291 if (FRAME_X_NEED_BUFFER_FLIP (f))
1292 show_back_buffer (f);
1295 /* Clear under internal border if any (GTK has its own version). */
1296 #ifndef USE_GTK
1297 void
1298 x_clear_under_internal_border (struct frame *f)
1300 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1302 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1303 int width = FRAME_PIXEL_WIDTH (f);
1304 int height = FRAME_PIXEL_HEIGHT (f);
1305 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1307 block_input ();
1308 x_clear_area (f, 0, 0, border, height);
1309 x_clear_area (f, 0, margin, width, border);
1310 x_clear_area (f, width - border, 0, border, height);
1311 x_clear_area (f, 0, height - border, width, border);
1312 unblock_input ();
1315 #endif
1317 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1318 arrow bitmaps, or clear the fringes if no bitmaps are required
1319 before DESIRED_ROW is made current. This function is called from
1320 update_window_line only if it is known that there are differences
1321 between bitmaps to be drawn between current row and DESIRED_ROW. */
1323 static void
1324 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1326 eassert (w);
1328 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1329 desired_row->redraw_fringe_bitmaps_p = true;
1331 #ifdef USE_X_TOOLKIT
1332 /* When a window has disappeared, make sure that no rest of
1333 full-width rows stays visible in the internal border. Could
1334 check here if updated window is the leftmost/rightmost window,
1335 but I guess it's not worth doing since vertically split windows
1336 are almost never used, internal border is rarely set, and the
1337 overhead is very small. */
1339 struct frame *f;
1340 int width, height;
1342 if (windows_or_buffers_changed
1343 && desired_row->full_width_p
1344 && (f = XFRAME (w->frame),
1345 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1346 width != 0)
1347 && (height = desired_row->visible_height,
1348 height > 0))
1350 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1352 block_input ();
1353 x_clear_area (f, 0, y, width, height);
1354 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1355 unblock_input ();
1358 #endif
1361 static void
1362 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1364 struct frame *f = XFRAME (WINDOW_FRAME (w));
1365 Display *display = FRAME_X_DISPLAY (f);
1366 GC gc = f->output_data.x->normal_gc;
1367 struct face *face = p->face;
1369 /* Must clip because of partially visible lines. */
1370 x_clip_to_row (w, row, ANY_AREA, gc);
1372 if (p->bx >= 0 && !p->overlay_p)
1374 /* In case the same realized face is used for fringes and
1375 for something displayed in the text (e.g. face `region' on
1376 mono-displays, the fill style may have been changed to
1377 FillSolid in x_draw_glyph_string_background. */
1378 if (face->stipple)
1379 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1380 else
1381 XSetForeground (display, face->gc, face->background);
1383 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1385 if (!face->stipple)
1386 XSetForeground (display, face->gc, face->foreground);
1389 #ifdef USE_CAIRO
1390 if (p->which && p->which < max_fringe_bmp)
1392 XGCValues gcv;
1394 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1395 XSetForeground (display, gc, (p->cursor_p
1396 ? (p->overlay_p ? face->background
1397 : f->output_data.x->cursor_pixel)
1398 : face->foreground));
1399 XSetBackground (display, gc, face->background);
1400 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1401 p->wd, p->h, p->x, p->y, p->overlay_p);
1402 XSetForeground (display, gc, gcv.foreground);
1403 XSetBackground (display, gc, gcv.background);
1405 #else /* not USE_CAIRO */
1406 if (p->which)
1408 Drawable drawable = FRAME_X_DRAWABLE (f);
1409 char *bits;
1410 Pixmap pixmap, clipmask = (Pixmap) 0;
1411 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1412 XGCValues gcv;
1414 if (p->wd > 8)
1415 bits = (char *) (p->bits + p->dh);
1416 else
1417 bits = (char *) p->bits + p->dh;
1419 /* Draw the bitmap. I believe these small pixmaps can be cached
1420 by the server. */
1421 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1422 (p->cursor_p
1423 ? (p->overlay_p ? face->background
1424 : f->output_data.x->cursor_pixel)
1425 : face->foreground),
1426 face->background, depth);
1428 if (p->overlay_p)
1430 clipmask = XCreatePixmapFromBitmapData (display,
1431 FRAME_DISPLAY_INFO (f)->root_window,
1432 bits, p->wd, p->h,
1433 1, 0, 1);
1434 gcv.clip_mask = clipmask;
1435 gcv.clip_x_origin = p->x;
1436 gcv.clip_y_origin = p->y;
1437 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1440 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1441 p->wd, p->h, p->x, p->y);
1442 XFreePixmap (display, pixmap);
1444 if (p->overlay_p)
1446 gcv.clip_mask = (Pixmap) 0;
1447 XChangeGC (display, gc, GCClipMask, &gcv);
1448 XFreePixmap (display, clipmask);
1451 #endif /* not USE_CAIRO */
1453 x_reset_clip_rectangles (f, gc);
1456 /***********************************************************************
1457 Glyph display
1458 ***********************************************************************/
1462 static void x_set_glyph_string_clipping (struct glyph_string *);
1463 static void x_set_glyph_string_gc (struct glyph_string *);
1464 static void x_draw_glyph_string_foreground (struct glyph_string *);
1465 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1466 static void x_draw_glyph_string_box (struct glyph_string *);
1467 static void x_draw_glyph_string (struct glyph_string *);
1468 static _Noreturn void x_delete_glyphs (struct frame *, int);
1469 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1470 static void x_set_cursor_gc (struct glyph_string *);
1471 static void x_set_mode_line_face_gc (struct glyph_string *);
1472 static void x_set_mouse_face_gc (struct glyph_string *);
1473 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1474 unsigned long *, double, int);
1475 static void x_setup_relief_color (struct frame *, struct relief *,
1476 double, int, unsigned long);
1477 static void x_setup_relief_colors (struct glyph_string *);
1478 static void x_draw_image_glyph_string (struct glyph_string *);
1479 static void x_draw_image_relief (struct glyph_string *);
1480 static void x_draw_image_foreground (struct glyph_string *);
1481 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1482 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1483 int, int, int);
1484 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1485 int, bool, bool, bool, bool, bool,
1486 XRectangle *);
1487 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1488 int, bool, bool, XRectangle *);
1489 static void x_scroll_bar_clear (struct frame *);
1491 #ifdef GLYPH_DEBUG
1492 static void x_check_font (struct frame *, struct font *);
1493 #endif
1496 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1497 face. */
1499 static void
1500 x_set_cursor_gc (struct glyph_string *s)
1502 if (s->font == FRAME_FONT (s->f)
1503 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1504 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1505 && !s->cmp)
1506 s->gc = s->f->output_data.x->cursor_gc;
1507 else
1509 /* Cursor on non-default face: must merge. */
1510 XGCValues xgcv;
1511 unsigned long mask;
1513 xgcv.background = s->f->output_data.x->cursor_pixel;
1514 xgcv.foreground = s->face->background;
1516 /* If the glyph would be invisible, try a different foreground. */
1517 if (xgcv.foreground == xgcv.background)
1518 xgcv.foreground = s->face->foreground;
1519 if (xgcv.foreground == xgcv.background)
1520 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1521 if (xgcv.foreground == xgcv.background)
1522 xgcv.foreground = s->face->foreground;
1524 /* Make sure the cursor is distinct from text in this face. */
1525 if (xgcv.background == s->face->background
1526 && xgcv.foreground == s->face->foreground)
1528 xgcv.background = s->face->foreground;
1529 xgcv.foreground = s->face->background;
1532 IF_DEBUG (x_check_font (s->f, s->font));
1533 xgcv.graphics_exposures = False;
1534 mask = GCForeground | GCBackground | GCGraphicsExposures;
1536 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1537 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1538 mask, &xgcv);
1539 else
1540 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1541 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1543 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1548 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1550 static void
1551 x_set_mouse_face_gc (struct glyph_string *s)
1553 int face_id;
1554 struct face *face;
1556 /* What face has to be used last for the mouse face? */
1557 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1558 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1559 if (face == NULL)
1560 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1562 if (s->first_glyph->type == CHAR_GLYPH)
1563 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1564 else
1565 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1566 s->face = FACE_FROM_ID (s->f, face_id);
1567 prepare_face_for_display (s->f, s->face);
1569 if (s->font == s->face->font)
1570 s->gc = s->face->gc;
1571 else
1573 /* Otherwise construct scratch_cursor_gc with values from FACE
1574 except for FONT. */
1575 XGCValues xgcv;
1576 unsigned long mask;
1578 xgcv.background = s->face->background;
1579 xgcv.foreground = s->face->foreground;
1580 xgcv.graphics_exposures = False;
1581 mask = GCForeground | GCBackground | GCGraphicsExposures;
1583 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1584 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1585 mask, &xgcv);
1586 else
1587 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1588 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1590 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1593 eassert (s->gc != 0);
1597 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1598 Faces to use in the mode line have already been computed when the
1599 matrix was built, so there isn't much to do, here. */
1601 static void
1602 x_set_mode_line_face_gc (struct glyph_string *s)
1604 s->gc = s->face->gc;
1608 /* Set S->gc of glyph string S for drawing that glyph string. Set
1609 S->stippled_p to a non-zero value if the face of S has a stipple
1610 pattern. */
1612 static void
1613 x_set_glyph_string_gc (struct glyph_string *s)
1615 prepare_face_for_display (s->f, s->face);
1617 if (s->hl == DRAW_NORMAL_TEXT)
1619 s->gc = s->face->gc;
1620 s->stippled_p = s->face->stipple != 0;
1622 else if (s->hl == DRAW_INVERSE_VIDEO)
1624 x_set_mode_line_face_gc (s);
1625 s->stippled_p = s->face->stipple != 0;
1627 else if (s->hl == DRAW_CURSOR)
1629 x_set_cursor_gc (s);
1630 s->stippled_p = false;
1632 else if (s->hl == DRAW_MOUSE_FACE)
1634 x_set_mouse_face_gc (s);
1635 s->stippled_p = s->face->stipple != 0;
1637 else if (s->hl == DRAW_IMAGE_RAISED
1638 || s->hl == DRAW_IMAGE_SUNKEN)
1640 s->gc = s->face->gc;
1641 s->stippled_p = s->face->stipple != 0;
1643 else
1644 emacs_abort ();
1646 /* GC must have been set. */
1647 eassert (s->gc != 0);
1651 /* Set clipping for output of glyph string S. S may be part of a mode
1652 line or menu if we don't have X toolkit support. */
1654 static void
1655 x_set_glyph_string_clipping (struct glyph_string *s)
1657 XRectangle *r = s->clip;
1658 int n = get_glyph_string_clip_rects (s, r, 2);
1660 if (n > 0)
1661 x_set_clip_rectangles (s->f, s->gc, r, n);
1662 s->num_clips = n;
1666 /* Set SRC's clipping for output of glyph string DST. This is called
1667 when we are drawing DST's left_overhang or right_overhang only in
1668 the area of SRC. */
1670 static void
1671 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1673 XRectangle r;
1675 r.x = src->x;
1676 r.width = src->width;
1677 r.y = src->y;
1678 r.height = src->height;
1679 dst->clip[0] = r;
1680 dst->num_clips = 1;
1681 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1685 /* RIF:
1686 Compute left and right overhang of glyph string S. */
1688 static void
1689 x_compute_glyph_string_overhangs (struct glyph_string *s)
1691 if (s->cmp == NULL
1692 && (s->first_glyph->type == CHAR_GLYPH
1693 || s->first_glyph->type == COMPOSITE_GLYPH))
1695 struct font_metrics metrics;
1697 if (s->first_glyph->type == CHAR_GLYPH)
1699 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1700 struct font *font = s->font;
1701 int i;
1703 for (i = 0; i < s->nchars; i++)
1704 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1705 font->driver->text_extents (font, code, s->nchars, &metrics);
1707 else
1709 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1711 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1713 s->right_overhang = (metrics.rbearing > metrics.width
1714 ? metrics.rbearing - metrics.width : 0);
1715 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1717 else if (s->cmp)
1719 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1720 s->left_overhang = - s->cmp->lbearing;
1725 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1727 static void
1728 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1730 XGCValues xgcv;
1731 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1732 XSetForeground (s->display, s->gc, xgcv.background);
1733 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1734 XSetForeground (s->display, s->gc, xgcv.foreground);
1738 /* Draw the background of glyph_string S. If S->background_filled_p
1739 is non-zero don't draw it. FORCE_P non-zero means draw the
1740 background even if it wouldn't be drawn normally. This is used
1741 when a string preceding S draws into the background of S, or S
1742 contains the first component of a composition. */
1744 static void
1745 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1747 /* Nothing to do if background has already been drawn or if it
1748 shouldn't be drawn in the first place. */
1749 if (!s->background_filled_p)
1751 int box_line_width = max (s->face->box_line_width, 0);
1753 if (s->stippled_p)
1755 /* Fill background with a stipple pattern. */
1756 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1757 x_fill_rectangle (s->f, s->gc, s->x,
1758 s->y + box_line_width,
1759 s->background_width,
1760 s->height - 2 * box_line_width);
1761 XSetFillStyle (s->display, s->gc, FillSolid);
1762 s->background_filled_p = true;
1764 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1765 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1766 font dimensions, since the actual glyphs might be
1767 much smaller. So in that case we always clear the
1768 rectangle with background color. */
1769 || FONT_TOO_HIGH (s->font)
1770 || s->font_not_found_p
1771 || s->extends_to_end_of_line_p
1772 || force_p)
1774 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1775 s->background_width,
1776 s->height - 2 * box_line_width);
1777 s->background_filled_p = true;
1783 /* Draw the foreground of glyph string S. */
1785 static void
1786 x_draw_glyph_string_foreground (struct glyph_string *s)
1788 int i, x;
1790 /* If first glyph of S has a left box line, start drawing the text
1791 of S to the right of that box line. */
1792 if (s->face->box != FACE_NO_BOX
1793 && s->first_glyph->left_box_line_p)
1794 x = s->x + eabs (s->face->box_line_width);
1795 else
1796 x = s->x;
1798 /* Draw characters of S as rectangles if S's font could not be
1799 loaded. */
1800 if (s->font_not_found_p)
1802 for (i = 0; i < s->nchars; ++i)
1804 struct glyph *g = s->first_glyph + i;
1805 x_draw_rectangle (s->f,
1806 s->gc, x, s->y, g->pixel_width - 1,
1807 s->height - 1);
1808 x += g->pixel_width;
1811 else
1813 struct font *font = s->font;
1814 int boff = font->baseline_offset;
1815 int y;
1817 if (font->vertical_centering)
1818 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1820 y = s->ybase - boff;
1821 if (s->for_overlaps
1822 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1823 font->driver->draw (s, 0, s->nchars, x, y, false);
1824 else
1825 font->driver->draw (s, 0, s->nchars, x, y, true);
1826 if (s->face->overstrike)
1827 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1831 /* Draw the foreground of composite glyph string S. */
1833 static void
1834 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1836 int i, j, x;
1837 struct font *font = s->font;
1839 /* If first glyph of S has a left box line, start drawing the text
1840 of S to the right of that box line. */
1841 if (s->face && s->face->box != FACE_NO_BOX
1842 && s->first_glyph->left_box_line_p)
1843 x = s->x + eabs (s->face->box_line_width);
1844 else
1845 x = s->x;
1847 /* S is a glyph string for a composition. S->cmp_from is the index
1848 of the first character drawn for glyphs of this composition.
1849 S->cmp_from == 0 means we are drawing the very first character of
1850 this composition. */
1852 /* Draw a rectangle for the composition if the font for the very
1853 first character of the composition could not be loaded. */
1854 if (s->font_not_found_p)
1856 if (s->cmp_from == 0)
1857 x_draw_rectangle (s->f, s->gc, x, s->y,
1858 s->width - 1, s->height - 1);
1860 else if (! s->first_glyph->u.cmp.automatic)
1862 int y = s->ybase;
1864 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1865 /* TAB in a composition means display glyphs with padding
1866 space on the left or right. */
1867 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1869 int xx = x + s->cmp->offsets[j * 2];
1870 int yy = y - s->cmp->offsets[j * 2 + 1];
1872 font->driver->draw (s, j, j + 1, xx, yy, false);
1873 if (s->face->overstrike)
1874 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1877 else
1879 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1880 Lisp_Object glyph;
1881 int y = s->ybase;
1882 int width = 0;
1884 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1886 glyph = LGSTRING_GLYPH (gstring, i);
1887 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1888 width += LGLYPH_WIDTH (glyph);
1889 else
1891 int xoff, yoff, wadjust;
1893 if (j < i)
1895 font->driver->draw (s, j, i, x, y, false);
1896 if (s->face->overstrike)
1897 font->driver->draw (s, j, i, x + 1, y, false);
1898 x += width;
1900 xoff = LGLYPH_XOFF (glyph);
1901 yoff = LGLYPH_YOFF (glyph);
1902 wadjust = LGLYPH_WADJUST (glyph);
1903 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1904 if (s->face->overstrike)
1905 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1906 false);
1907 x += wadjust;
1908 j = i + 1;
1909 width = 0;
1912 if (j < i)
1914 font->driver->draw (s, j, i, x, y, false);
1915 if (s->face->overstrike)
1916 font->driver->draw (s, j, i, x + 1, y, false);
1922 /* Draw the foreground of glyph string S for glyphless characters. */
1924 static void
1925 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1927 struct glyph *glyph = s->first_glyph;
1928 XChar2b char2b[8];
1929 int x, i, j;
1931 /* If first glyph of S has a left box line, start drawing the text
1932 of S to the right of that box line. */
1933 if (s->face && s->face->box != FACE_NO_BOX
1934 && s->first_glyph->left_box_line_p)
1935 x = s->x + eabs (s->face->box_line_width);
1936 else
1937 x = s->x;
1939 s->char2b = char2b;
1941 for (i = 0; i < s->nchars; i++, glyph++)
1943 char buf[7], *str = NULL;
1944 int len = glyph->u.glyphless.len;
1946 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1948 if (len > 0
1949 && CHAR_TABLE_P (Vglyphless_char_display)
1950 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1951 >= 1))
1953 Lisp_Object acronym
1954 = (! glyph->u.glyphless.for_no_font
1955 ? CHAR_TABLE_REF (Vglyphless_char_display,
1956 glyph->u.glyphless.ch)
1957 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1958 if (STRINGP (acronym))
1959 str = SSDATA (acronym);
1962 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1964 sprintf (buf, "%0*X",
1965 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1966 glyph->u.glyphless.ch + 0u);
1967 str = buf;
1970 if (str)
1972 int upper_len = (len + 1) / 2;
1973 unsigned code;
1975 /* It is assured that all LEN characters in STR is ASCII. */
1976 for (j = 0; j < len; j++)
1978 code = s->font->driver->encode_char (s->font, str[j]);
1979 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
1981 s->font->driver->draw (s, 0, upper_len,
1982 x + glyph->slice.glyphless.upper_xoff,
1983 s->ybase + glyph->slice.glyphless.upper_yoff,
1984 false);
1985 s->font->driver->draw (s, upper_len, len,
1986 x + glyph->slice.glyphless.lower_xoff,
1987 s->ybase + glyph->slice.glyphless.lower_yoff,
1988 false);
1990 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1991 x_draw_rectangle (s->f, s->gc,
1992 x, s->ybase - glyph->ascent,
1993 glyph->pixel_width - 1,
1994 glyph->ascent + glyph->descent - 1);
1995 x += glyph->pixel_width;
1999 #ifdef USE_X_TOOLKIT
2001 #ifdef USE_LUCID
2003 /* Return the frame on which widget WIDGET is used.. Abort if frame
2004 cannot be determined. */
2006 static struct frame *
2007 x_frame_of_widget (Widget widget)
2009 struct x_display_info *dpyinfo;
2010 Lisp_Object tail, frame;
2011 struct frame *f;
2013 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2015 /* Find the top-level shell of the widget. Note that this function
2016 can be called when the widget is not yet realized, so XtWindow
2017 (widget) == 0. That's the reason we can't simply use
2018 x_any_window_to_frame. */
2019 while (!XtIsTopLevelShell (widget))
2020 widget = XtParent (widget);
2022 /* Look for a frame with that top-level widget. Allocate the color
2023 on that frame to get the right gamma correction value. */
2024 FOR_EACH_FRAME (tail, frame)
2026 f = XFRAME (frame);
2027 if (FRAME_X_P (f)
2028 && f->output_data.nothing != 1
2029 && FRAME_DISPLAY_INFO (f) == dpyinfo
2030 && f->output_data.x->widget == widget)
2031 return f;
2033 emacs_abort ();
2036 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2037 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2038 If this produces the same color as PIXEL, try a color where all RGB
2039 values have DELTA added. Return the allocated color in *PIXEL.
2040 DISPLAY is the X display, CMAP is the colormap to operate on.
2041 Value is true if successful. */
2043 bool
2044 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2045 unsigned long *pixel, double factor, int delta)
2047 struct frame *f = x_frame_of_widget (widget);
2048 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2051 #endif /* USE_LUCID */
2054 /* Structure specifying which arguments should be passed by Xt to
2055 cvt_string_to_pixel. We want the widget's screen and colormap. */
2057 static XtConvertArgRec cvt_string_to_pixel_args[] =
2059 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2060 sizeof (Screen *)},
2061 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2062 sizeof (Colormap)}
2066 /* The address of this variable is returned by
2067 cvt_string_to_pixel. */
2069 static Pixel cvt_string_to_pixel_value;
2072 /* Convert a color name to a pixel color.
2074 DPY is the display we are working on.
2076 ARGS is an array of *NARGS XrmValue structures holding additional
2077 information about the widget for which the conversion takes place.
2078 The contents of this array are determined by the specification
2079 in cvt_string_to_pixel_args.
2081 FROM is a pointer to an XrmValue which points to the color name to
2082 convert. TO is an XrmValue in which to return the pixel color.
2084 CLOSURE_RET is a pointer to user-data, in which we record if
2085 we allocated the color or not.
2087 Value is True if successful, False otherwise. */
2089 static Boolean
2090 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2091 XrmValue *from, XrmValue *to,
2092 XtPointer *closure_ret)
2094 Screen *screen;
2095 Colormap cmap;
2096 Pixel pixel;
2097 String color_name;
2098 XColor color;
2100 if (*nargs != 2)
2102 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2103 "wrongParameters", "cvt_string_to_pixel",
2104 "XtToolkitError",
2105 "Screen and colormap args required", NULL, NULL);
2106 return False;
2109 screen = *(Screen **) args[0].addr;
2110 cmap = *(Colormap *) args[1].addr;
2111 color_name = (String) from->addr;
2113 if (strcmp (color_name, XtDefaultBackground) == 0)
2115 *closure_ret = (XtPointer) False;
2116 pixel = WhitePixelOfScreen (screen);
2118 else if (strcmp (color_name, XtDefaultForeground) == 0)
2120 *closure_ret = (XtPointer) False;
2121 pixel = BlackPixelOfScreen (screen);
2123 else if (XParseColor (dpy, cmap, color_name, &color)
2124 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2126 pixel = color.pixel;
2127 *closure_ret = (XtPointer) True;
2129 else
2131 String params[1];
2132 Cardinal nparams = 1;
2134 params[0] = color_name;
2135 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2136 "badValue", "cvt_string_to_pixel",
2137 "XtToolkitError", "Invalid color '%s'",
2138 params, &nparams);
2139 return False;
2142 if (to->addr != NULL)
2144 if (to->size < sizeof (Pixel))
2146 to->size = sizeof (Pixel);
2147 return False;
2150 *(Pixel *) to->addr = pixel;
2152 else
2154 cvt_string_to_pixel_value = pixel;
2155 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2158 to->size = sizeof (Pixel);
2159 return True;
2163 /* Free a pixel color which was previously allocated via
2164 cvt_string_to_pixel. This is registered as the destructor
2165 for this type of resource via XtSetTypeConverter.
2167 APP is the application context in which we work.
2169 TO is a pointer to an XrmValue holding the color to free.
2170 CLOSURE is the value we stored in CLOSURE_RET for this color
2171 in cvt_string_to_pixel.
2173 ARGS and NARGS are like for cvt_string_to_pixel. */
2175 static void
2176 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2177 Cardinal *nargs)
2179 if (*nargs != 2)
2181 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2182 "XtToolkitError",
2183 "Screen and colormap arguments required",
2184 NULL, NULL);
2186 else if (closure != NULL)
2188 /* We did allocate the pixel, so free it. */
2189 Screen *screen = *(Screen **) args[0].addr;
2190 Colormap cmap = *(Colormap *) args[1].addr;
2191 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2192 (Pixel *) to->addr, 1);
2197 #endif /* USE_X_TOOLKIT */
2200 /* Value is an array of XColor structures for the contents of the
2201 color map of display DPY. Set *NCELLS to the size of the array.
2202 Note that this probably shouldn't be called for large color maps,
2203 say a 24-bit TrueColor map. */
2205 static const XColor *
2206 x_color_cells (Display *dpy, int *ncells)
2208 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2209 eassume (dpyinfo);
2211 if (dpyinfo->color_cells == NULL)
2213 Screen *screen = dpyinfo->screen;
2214 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2215 int i;
2217 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2218 sizeof *dpyinfo->color_cells);
2219 dpyinfo->ncolor_cells = ncolor_cells;
2221 for (i = 0; i < ncolor_cells; ++i)
2222 dpyinfo->color_cells[i].pixel = i;
2224 XQueryColors (dpy, dpyinfo->cmap,
2225 dpyinfo->color_cells, ncolor_cells);
2228 *ncells = dpyinfo->ncolor_cells;
2229 return dpyinfo->color_cells;
2233 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2234 colors in COLORS. Use cached information, if available. */
2236 void
2237 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2239 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2241 if (dpyinfo->red_bits > 0)
2243 /* For TrueColor displays, we can decompose the RGB value
2244 directly. */
2245 int i;
2246 unsigned int rmult, gmult, bmult;
2247 unsigned int rmask, gmask, bmask;
2249 rmask = (1 << dpyinfo->red_bits) - 1;
2250 gmask = (1 << dpyinfo->green_bits) - 1;
2251 bmask = (1 << dpyinfo->blue_bits) - 1;
2252 /* If we're widening, for example, 8 bits in the pixel value to
2253 16 bits for the separate-color representation, we want to
2254 extrapolate the lower bits based on those bits available --
2255 in other words, we'd like 0xff to become 0xffff instead of
2256 the 0xff00 we'd get by just zero-filling the lower bits.
2258 We generate a 32-bit scaled-up value and shift it, in case
2259 the bit count doesn't divide 16 evenly (e.g., when dealing
2260 with a 3-3-2 bit RGB display), to get more of the lower bits
2261 correct.
2263 Should we cache the multipliers in dpyinfo? Maybe
2264 special-case the 8-8-8 common case? */
2265 rmult = 0xffffffff / rmask;
2266 gmult = 0xffffffff / gmask;
2267 bmult = 0xffffffff / bmask;
2269 for (i = 0; i < ncolors; ++i)
2271 unsigned int r, g, b;
2272 unsigned long pixel = colors[i].pixel;
2274 r = (pixel >> dpyinfo->red_offset) & rmask;
2275 g = (pixel >> dpyinfo->green_offset) & gmask;
2276 b = (pixel >> dpyinfo->blue_offset) & bmask;
2278 colors[i].red = (r * rmult) >> 16;
2279 colors[i].green = (g * gmult) >> 16;
2280 colors[i].blue = (b * bmult) >> 16;
2282 return;
2285 if (dpyinfo->color_cells)
2287 int i;
2288 for (i = 0; i < ncolors; ++i)
2290 unsigned long pixel = colors[i].pixel;
2291 eassert (pixel < dpyinfo->ncolor_cells);
2292 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2293 colors[i] = dpyinfo->color_cells[pixel];
2295 return;
2298 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2302 /* On frame F, translate pixel color to RGB values for the color in
2303 COLOR. Use cached information, if available. */
2305 void
2306 x_query_color (struct frame *f, XColor *color)
2308 x_query_colors (f, color, 1);
2312 /* On frame F, translate the color name to RGB values. Use cached
2313 information, if possible.
2315 Note that there is currently no way to clean old entries out of the
2316 cache. However, it is limited to names in the server's database,
2317 and names we've actually looked up; list-colors-display is probably
2318 the most color-intensive case we're likely to hit. */
2320 Status x_parse_color (struct frame *f, const char *color_name,
2321 XColor *color)
2323 Display *dpy = FRAME_X_DISPLAY (f);
2324 Colormap cmap = FRAME_X_COLORMAP (f);
2325 struct color_name_cache_entry *cache_entry;
2327 if (color_name[0] == '#')
2329 /* The hex form is parsed directly by XParseColor without
2330 talking to the X server. No need for caching. */
2331 return XParseColor (dpy, cmap, color_name, color);
2334 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2335 cache_entry = cache_entry->next)
2337 if (!xstrcasecmp(cache_entry->name, color_name))
2339 *color = cache_entry->rgb;
2340 return 1;
2344 if (XParseColor (dpy, cmap, color_name, color) == 0)
2345 /* No caching of negative results, currently. */
2346 return 0;
2348 cache_entry = xzalloc (sizeof *cache_entry);
2349 cache_entry->rgb = *color;
2350 cache_entry->name = xstrdup (color_name);
2351 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2352 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2353 return 1;
2357 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2358 exact match can't be allocated, try the nearest color available.
2359 Value is true if successful. Set *COLOR to the color
2360 allocated. */
2362 static bool
2363 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2365 bool rc;
2367 rc = XAllocColor (dpy, cmap, color) != 0;
2368 if (rc == 0)
2370 /* If we got to this point, the colormap is full, so we're going
2371 to try to get the next closest color. The algorithm used is
2372 a least-squares matching, which is what X uses for closest
2373 color matching with StaticColor visuals. */
2374 int nearest, i;
2375 int max_color_delta = 255;
2376 int max_delta = 3 * max_color_delta;
2377 int nearest_delta = max_delta + 1;
2378 int ncells;
2379 const XColor *cells = x_color_cells (dpy, &ncells);
2381 for (nearest = i = 0; i < ncells; ++i)
2383 int dred = (color->red >> 8) - (cells[i].red >> 8);
2384 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2385 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2386 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2388 if (delta < nearest_delta)
2390 nearest = i;
2391 nearest_delta = delta;
2395 color->red = cells[nearest].red;
2396 color->green = cells[nearest].green;
2397 color->blue = cells[nearest].blue;
2398 rc = XAllocColor (dpy, cmap, color) != 0;
2400 else
2402 /* If allocation succeeded, and the allocated pixel color is not
2403 equal to a cached pixel color recorded earlier, there was a
2404 change in the colormap, so clear the color cache. */
2405 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2406 eassume (dpyinfo);
2408 if (dpyinfo->color_cells)
2410 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2411 if (cached_color->red != color->red
2412 || cached_color->blue != color->blue
2413 || cached_color->green != color->green)
2415 xfree (dpyinfo->color_cells);
2416 dpyinfo->color_cells = NULL;
2417 dpyinfo->ncolor_cells = 0;
2422 #ifdef DEBUG_X_COLORS
2423 if (rc)
2424 register_color (color->pixel);
2425 #endif /* DEBUG_X_COLORS */
2427 return rc;
2431 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2432 gamma correction. If an exact match can't be allocated, try the
2433 nearest color available. Value is true if successful. Set *COLOR
2434 to the color allocated. */
2436 bool
2437 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2439 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2441 gamma_correct (f, color);
2443 if (dpyinfo->red_bits > 0)
2445 color->pixel = x_make_truecolor_pixel (dpyinfo,
2446 color->red,
2447 color->green,
2448 color->blue);
2449 return true;
2452 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2456 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2457 It's necessary to do this instead of just using PIXEL directly to
2458 get color reference counts right. */
2460 unsigned long
2461 x_copy_color (struct frame *f, unsigned long pixel)
2463 XColor color;
2465 /* If display has an immutable color map, freeing colors is not
2466 necessary and some servers don't allow it. Since we won't free a
2467 color once we've allocated it, we don't need to re-allocate it to
2468 maintain the server's reference count. */
2469 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2470 return pixel;
2472 color.pixel = pixel;
2473 block_input ();
2474 /* The color could still be found in the color_cells array. */
2475 x_query_color (f, &color);
2476 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2477 unblock_input ();
2478 #ifdef DEBUG_X_COLORS
2479 register_color (pixel);
2480 #endif
2481 return color.pixel;
2485 /* Brightness beyond which a color won't have its highlight brightness
2486 boosted.
2488 Nominally, highlight colors for `3d' faces are calculated by
2489 brightening an object's color by a constant scale factor, but this
2490 doesn't yield good results for dark colors, so for colors who's
2491 brightness is less than this value (on a scale of 0-65535) have an
2492 use an additional additive factor.
2494 The value here is set so that the default menu-bar/mode-line color
2495 (grey75) will not have its highlights changed at all. */
2496 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2499 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2500 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2501 If this produces the same color as PIXEL, try a color where all RGB
2502 values have DELTA added. Return the allocated color in *PIXEL.
2503 DISPLAY is the X display, CMAP is the colormap to operate on.
2504 Value is non-zero if successful. */
2506 static bool
2507 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2508 unsigned long *pixel, double factor, int delta)
2510 XColor color, new;
2511 long bright;
2512 bool success_p;
2514 /* Get RGB color values. */
2515 color.pixel = *pixel;
2516 x_query_color (f, &color);
2518 /* Change RGB values by specified FACTOR. Avoid overflow! */
2519 eassert (factor >= 0);
2520 new.red = min (0xffff, factor * color.red);
2521 new.green = min (0xffff, factor * color.green);
2522 new.blue = min (0xffff, factor * color.blue);
2524 /* Calculate brightness of COLOR. */
2525 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2527 /* We only boost colors that are darker than
2528 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2529 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2530 /* Make an additive adjustment to NEW, because it's dark enough so
2531 that scaling by FACTOR alone isn't enough. */
2533 /* How far below the limit this color is (0 - 1, 1 being darker). */
2534 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2535 /* The additive adjustment. */
2536 int min_delta = delta * dimness * factor / 2;
2538 if (factor < 1)
2540 new.red = max (0, new.red - min_delta);
2541 new.green = max (0, new.green - min_delta);
2542 new.blue = max (0, new.blue - min_delta);
2544 else
2546 new.red = min (0xffff, min_delta + new.red);
2547 new.green = min (0xffff, min_delta + new.green);
2548 new.blue = min (0xffff, min_delta + new.blue);
2552 /* Try to allocate the color. */
2553 success_p = x_alloc_nearest_color (f, cmap, &new);
2554 if (success_p)
2556 if (new.pixel == *pixel)
2558 /* If we end up with the same color as before, try adding
2559 delta to the RGB values. */
2560 x_free_colors (f, &new.pixel, 1);
2562 new.red = min (0xffff, delta + color.red);
2563 new.green = min (0xffff, delta + color.green);
2564 new.blue = min (0xffff, delta + color.blue);
2565 success_p = x_alloc_nearest_color (f, cmap, &new);
2567 else
2568 success_p = true;
2569 *pixel = new.pixel;
2572 return success_p;
2576 /* Set up the foreground color for drawing relief lines of glyph
2577 string S. RELIEF is a pointer to a struct relief containing the GC
2578 with which lines will be drawn. Use a color that is FACTOR or
2579 DELTA lighter or darker than the relief's background which is found
2580 in S->f->output_data.x->relief_background. If such a color cannot
2581 be allocated, use DEFAULT_PIXEL, instead. */
2583 static void
2584 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2585 int delta, unsigned long default_pixel)
2587 XGCValues xgcv;
2588 struct x_output *di = f->output_data.x;
2589 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2590 unsigned long pixel;
2591 unsigned long background = di->relief_background;
2592 Colormap cmap = FRAME_X_COLORMAP (f);
2593 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2594 Display *dpy = FRAME_X_DISPLAY (f);
2596 xgcv.graphics_exposures = False;
2597 xgcv.line_width = 1;
2599 /* Free previously allocated color. The color cell will be reused
2600 when it has been freed as many times as it was allocated, so this
2601 doesn't affect faces using the same colors. */
2602 if (relief->gc && relief->pixel != -1)
2604 x_free_colors (f, &relief->pixel, 1);
2605 relief->pixel = -1;
2608 /* Allocate new color. */
2609 xgcv.foreground = default_pixel;
2610 pixel = background;
2611 if (dpyinfo->n_planes != 1
2612 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2613 xgcv.foreground = relief->pixel = pixel;
2615 if (relief->gc == 0)
2617 xgcv.stipple = dpyinfo->gray;
2618 mask |= GCStipple;
2619 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2621 else
2622 XChangeGC (dpy, relief->gc, mask, &xgcv);
2626 /* Set up colors for the relief lines around glyph string S. */
2628 static void
2629 x_setup_relief_colors (struct glyph_string *s)
2631 struct x_output *di = s->f->output_data.x;
2632 unsigned long color;
2634 if (s->face->use_box_color_for_shadows_p)
2635 color = s->face->box_color;
2636 else if (s->first_glyph->type == IMAGE_GLYPH
2637 && s->img->pixmap
2638 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2639 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2640 else
2642 XGCValues xgcv;
2644 /* Get the background color of the face. */
2645 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2646 color = xgcv.background;
2649 if (di->white_relief.gc == 0
2650 || color != di->relief_background)
2652 di->relief_background = color;
2653 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2654 WHITE_PIX_DEFAULT (s->f));
2655 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2656 BLACK_PIX_DEFAULT (s->f));
2661 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2662 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2663 to draw, it must be >= 0. RAISED_P means draw a raised
2664 relief. LEFT_P means draw a relief on the left side of
2665 the rectangle. RIGHT_P means draw a relief on the right
2666 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2667 when drawing. */
2669 static void
2670 x_draw_relief_rect (struct frame *f,
2671 int left_x, int top_y, int right_x, int bottom_y,
2672 int width, bool raised_p, bool top_p, bool bot_p,
2673 bool left_p, bool right_p,
2674 XRectangle *clip_rect)
2676 #ifdef USE_CAIRO
2677 GC top_left_gc, bottom_right_gc;
2678 int corners = 0;
2680 if (raised_p)
2682 top_left_gc = f->output_data.x->white_relief.gc;
2683 bottom_right_gc = f->output_data.x->black_relief.gc;
2685 else
2687 top_left_gc = f->output_data.x->black_relief.gc;
2688 bottom_right_gc = f->output_data.x->white_relief.gc;
2691 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2692 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2694 if (left_p)
2696 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2697 width, bottom_y + 1 - top_y);
2698 if (top_p)
2699 corners |= 1 << CORNER_TOP_LEFT;
2700 if (bot_p)
2701 corners |= 1 << CORNER_BOTTOM_LEFT;
2703 if (right_p)
2705 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2706 width, bottom_y + 1 - top_y);
2707 if (top_p)
2708 corners |= 1 << CORNER_TOP_RIGHT;
2709 if (bot_p)
2710 corners |= 1 << CORNER_BOTTOM_RIGHT;
2712 if (top_p)
2714 if (!right_p)
2715 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2716 right_x + 1 - left_x, width);
2717 else
2718 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2719 right_x + 1 - left_x, width, 1);
2721 if (bot_p)
2723 if (!left_p)
2724 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2725 right_x + 1 - left_x, width);
2726 else
2727 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2728 left_x, bottom_y + 1 - width,
2729 right_x + 1 - left_x, width, 0);
2731 if (left_p && width != 1)
2732 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2733 1, bottom_y + 1 - top_y);
2734 if (top_p && width != 1)
2735 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2736 right_x + 1 - left_x, 1);
2737 if (corners)
2739 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2740 FRAME_BACKGROUND_PIXEL (f));
2741 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2742 right_x - left_x + 1, bottom_y - top_y + 1,
2743 6, 1, corners);
2746 x_reset_clip_rectangles (f, top_left_gc);
2747 x_reset_clip_rectangles (f, bottom_right_gc);
2748 #else
2749 Display *dpy = FRAME_X_DISPLAY (f);
2750 Drawable drawable = FRAME_X_DRAWABLE (f);
2751 int i;
2752 GC gc;
2754 if (raised_p)
2755 gc = f->output_data.x->white_relief.gc;
2756 else
2757 gc = f->output_data.x->black_relief.gc;
2758 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2760 /* This code is more complicated than it has to be, because of two
2761 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2762 the outermost line using the black relief. (ii) Omit the four
2763 corner pixels. */
2765 /* Top. */
2766 if (top_p)
2768 if (width == 1)
2769 XDrawLine (dpy, drawable, gc,
2770 left_x + left_p, top_y,
2771 right_x + !right_p, top_y);
2773 for (i = 1; i < width; ++i)
2774 XDrawLine (dpy, drawable, gc,
2775 left_x + i * left_p, top_y + i,
2776 right_x + 1 - i * right_p, top_y + i);
2779 /* Left. */
2780 if (left_p)
2782 if (width == 1)
2783 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2785 x_clear_area(f, left_x, top_y, 1, 1);
2786 x_clear_area(f, left_x, bottom_y, 1, 1);
2788 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2789 XDrawLine (dpy, drawable, gc,
2790 left_x + i, top_y + (i + 1) * top_p,
2791 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2794 XSetClipMask (dpy, gc, None);
2795 if (raised_p)
2796 gc = f->output_data.x->black_relief.gc;
2797 else
2798 gc = f->output_data.x->white_relief.gc;
2799 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2801 if (width > 1)
2803 /* Outermost top line. */
2804 if (top_p)
2805 XDrawLine (dpy, drawable, gc,
2806 left_x + left_p, top_y,
2807 right_x + !right_p, top_y);
2809 /* Outermost left line. */
2810 if (left_p)
2811 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2814 /* Bottom. */
2815 if (bot_p)
2817 XDrawLine (dpy, drawable, gc,
2818 left_x + left_p, bottom_y,
2819 right_x + !right_p, bottom_y);
2820 for (i = 1; i < width; ++i)
2821 XDrawLine (dpy, drawable, gc,
2822 left_x + i * left_p, bottom_y - i,
2823 right_x + 1 - i * right_p, bottom_y - i);
2826 /* Right. */
2827 if (right_p)
2829 x_clear_area(f, right_x, top_y, 1, 1);
2830 x_clear_area(f, right_x, bottom_y, 1, 1);
2831 for (i = 0; i < width; ++i)
2832 XDrawLine (dpy, drawable, gc,
2833 right_x - i, top_y + (i + 1) * top_p,
2834 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2837 x_reset_clip_rectangles (f, gc);
2839 #endif
2843 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2844 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2845 draw, it must be >= 0. LEFT_P means draw a line on the
2846 left side of the rectangle. RIGHT_P means draw a line
2847 on the right side of the rectangle. CLIP_RECT is the clipping
2848 rectangle to use when drawing. */
2850 static void
2851 x_draw_box_rect (struct glyph_string *s,
2852 int left_x, int top_y, int right_x, int bottom_y, int width,
2853 bool left_p, bool right_p, XRectangle *clip_rect)
2855 XGCValues xgcv;
2857 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2858 XSetForeground (s->display, s->gc, s->face->box_color);
2859 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2861 /* Top. */
2862 x_fill_rectangle (s->f, s->gc,
2863 left_x, top_y, right_x - left_x + 1, width);
2865 /* Left. */
2866 if (left_p)
2867 x_fill_rectangle (s->f, s->gc,
2868 left_x, top_y, width, bottom_y - top_y + 1);
2870 /* Bottom. */
2871 x_fill_rectangle (s->f, s->gc,
2872 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2874 /* Right. */
2875 if (right_p)
2876 x_fill_rectangle (s->f, s->gc,
2877 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2879 XSetForeground (s->display, s->gc, xgcv.foreground);
2880 x_reset_clip_rectangles (s->f, s->gc);
2884 /* Draw a box around glyph string S. */
2886 static void
2887 x_draw_glyph_string_box (struct glyph_string *s)
2889 int width, left_x, right_x, top_y, bottom_y, last_x;
2890 bool raised_p, left_p, right_p;
2891 struct glyph *last_glyph;
2892 XRectangle clip_rect;
2894 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2895 ? WINDOW_RIGHT_EDGE_X (s->w)
2896 : window_box_right (s->w, s->area));
2898 /* The glyph that may have a right box line. */
2899 last_glyph = (s->cmp || s->img
2900 ? s->first_glyph
2901 : s->first_glyph + s->nchars - 1);
2903 width = eabs (s->face->box_line_width);
2904 raised_p = s->face->box == FACE_RAISED_BOX;
2905 left_x = s->x;
2906 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2907 ? last_x - 1
2908 : min (last_x, s->x + s->background_width) - 1);
2909 top_y = s->y;
2910 bottom_y = top_y + s->height - 1;
2912 left_p = (s->first_glyph->left_box_line_p
2913 || (s->hl == DRAW_MOUSE_FACE
2914 && (s->prev == NULL
2915 || s->prev->hl != s->hl)));
2916 right_p = (last_glyph->right_box_line_p
2917 || (s->hl == DRAW_MOUSE_FACE
2918 && (s->next == NULL
2919 || s->next->hl != s->hl)));
2921 get_glyph_string_clip_rect (s, &clip_rect);
2923 if (s->face->box == FACE_SIMPLE_BOX)
2924 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2925 left_p, right_p, &clip_rect);
2926 else
2928 x_setup_relief_colors (s);
2929 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2930 width, raised_p, true, true, left_p, right_p,
2931 &clip_rect);
2936 /* Draw foreground of image glyph string S. */
2938 static void
2939 x_draw_image_foreground (struct glyph_string *s)
2941 int x = s->x;
2942 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2944 /* If first glyph of S has a left box line, start drawing it to the
2945 right of that line. */
2946 if (s->face->box != FACE_NO_BOX
2947 && s->first_glyph->left_box_line_p
2948 && s->slice.x == 0)
2949 x += eabs (s->face->box_line_width);
2951 /* If there is a margin around the image, adjust x- and y-position
2952 by that margin. */
2953 if (s->slice.x == 0)
2954 x += s->img->hmargin;
2955 if (s->slice.y == 0)
2956 y += s->img->vmargin;
2958 if (s->img->pixmap)
2960 if (s->img->mask)
2962 /* We can't set both a clip mask and use XSetClipRectangles
2963 because the latter also sets a clip mask. We also can't
2964 trust on the shape extension to be available
2965 (XShapeCombineRegion). So, compute the rectangle to draw
2966 manually. */
2967 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2968 | GCFunction);
2969 XGCValues xgcv;
2970 XRectangle clip_rect, image_rect, r;
2972 xgcv.clip_mask = s->img->mask;
2973 xgcv.clip_x_origin = x;
2974 xgcv.clip_y_origin = y;
2975 xgcv.function = GXcopy;
2976 XChangeGC (s->display, s->gc, mask, &xgcv);
2978 get_glyph_string_clip_rect (s, &clip_rect);
2979 image_rect.x = x;
2980 image_rect.y = y;
2981 image_rect.width = s->slice.width;
2982 image_rect.height = s->slice.height;
2983 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2984 XCopyArea (s->display, s->img->pixmap,
2985 FRAME_X_DRAWABLE (s->f), s->gc,
2986 s->slice.x + r.x - x, s->slice.y + r.y - y,
2987 r.width, r.height, r.x, r.y);
2989 else
2991 XRectangle clip_rect, image_rect, r;
2993 get_glyph_string_clip_rect (s, &clip_rect);
2994 image_rect.x = x;
2995 image_rect.y = y;
2996 image_rect.width = s->slice.width;
2997 image_rect.height = s->slice.height;
2998 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2999 XCopyArea (s->display, s->img->pixmap,
3000 FRAME_X_DRAWABLE (s->f), s->gc,
3001 s->slice.x + r.x - x, s->slice.y + r.y - y,
3002 r.width, r.height, r.x, r.y);
3004 /* When the image has a mask, we can expect that at
3005 least part of a mouse highlight or a block cursor will
3006 be visible. If the image doesn't have a mask, make
3007 a block cursor visible by drawing a rectangle around
3008 the image. I believe it's looking better if we do
3009 nothing here for mouse-face. */
3010 if (s->hl == DRAW_CURSOR)
3012 int relief = eabs (s->img->relief);
3013 x_draw_rectangle (s->f, s->gc,
3014 x - relief, y - relief,
3015 s->slice.width + relief*2 - 1,
3016 s->slice.height + relief*2 - 1);
3020 else
3021 /* Draw a rectangle if image could not be loaded. */
3022 x_draw_rectangle (s->f, s->gc, x, y,
3023 s->slice.width - 1, s->slice.height - 1);
3027 /* Draw a relief around the image glyph string S. */
3029 static void
3030 x_draw_image_relief (struct glyph_string *s)
3032 int x1, y1, thick;
3033 bool raised_p, top_p, bot_p, left_p, right_p;
3034 int extra_x, extra_y;
3035 XRectangle r;
3036 int x = s->x;
3037 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3039 /* If first glyph of S has a left box line, start drawing it to the
3040 right of that line. */
3041 if (s->face->box != FACE_NO_BOX
3042 && s->first_glyph->left_box_line_p
3043 && s->slice.x == 0)
3044 x += eabs (s->face->box_line_width);
3046 /* If there is a margin around the image, adjust x- and y-position
3047 by that margin. */
3048 if (s->slice.x == 0)
3049 x += s->img->hmargin;
3050 if (s->slice.y == 0)
3051 y += s->img->vmargin;
3053 if (s->hl == DRAW_IMAGE_SUNKEN
3054 || s->hl == DRAW_IMAGE_RAISED)
3056 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3057 raised_p = s->hl == DRAW_IMAGE_RAISED;
3059 else
3061 thick = eabs (s->img->relief);
3062 raised_p = s->img->relief > 0;
3065 x1 = x + s->slice.width - 1;
3066 y1 = y + s->slice.height - 1;
3068 extra_x = extra_y = 0;
3069 if (s->face->id == TOOL_BAR_FACE_ID)
3071 if (CONSP (Vtool_bar_button_margin)
3072 && INTEGERP (XCAR (Vtool_bar_button_margin))
3073 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3075 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3076 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3078 else if (INTEGERP (Vtool_bar_button_margin))
3079 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3082 top_p = bot_p = left_p = right_p = false;
3084 if (s->slice.x == 0)
3085 x -= thick + extra_x, left_p = true;
3086 if (s->slice.y == 0)
3087 y -= thick + extra_y, top_p = true;
3088 if (s->slice.x + s->slice.width == s->img->width)
3089 x1 += thick + extra_x, right_p = true;
3090 if (s->slice.y + s->slice.height == s->img->height)
3091 y1 += thick + extra_y, bot_p = true;
3093 x_setup_relief_colors (s);
3094 get_glyph_string_clip_rect (s, &r);
3095 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3096 top_p, bot_p, left_p, right_p, &r);
3100 /* Draw the foreground of image glyph string S to PIXMAP. */
3102 static void
3103 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3105 int x = 0;
3106 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3108 /* If first glyph of S has a left box line, start drawing it to the
3109 right of that line. */
3110 if (s->face->box != FACE_NO_BOX
3111 && s->first_glyph->left_box_line_p
3112 && s->slice.x == 0)
3113 x += eabs (s->face->box_line_width);
3115 /* If there is a margin around the image, adjust x- and y-position
3116 by that margin. */
3117 if (s->slice.x == 0)
3118 x += s->img->hmargin;
3119 if (s->slice.y == 0)
3120 y += s->img->vmargin;
3122 if (s->img->pixmap)
3124 if (s->img->mask)
3126 /* We can't set both a clip mask and use XSetClipRectangles
3127 because the latter also sets a clip mask. We also can't
3128 trust on the shape extension to be available
3129 (XShapeCombineRegion). So, compute the rectangle to draw
3130 manually. */
3131 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3132 | GCFunction);
3133 XGCValues xgcv;
3135 xgcv.clip_mask = s->img->mask;
3136 xgcv.clip_x_origin = x - s->slice.x;
3137 xgcv.clip_y_origin = y - s->slice.y;
3138 xgcv.function = GXcopy;
3139 XChangeGC (s->display, s->gc, mask, &xgcv);
3141 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3142 s->slice.x, s->slice.y,
3143 s->slice.width, s->slice.height, x, y);
3144 XSetClipMask (s->display, s->gc, None);
3146 else
3148 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3149 s->slice.x, s->slice.y,
3150 s->slice.width, s->slice.height, x, y);
3152 /* When the image has a mask, we can expect that at
3153 least part of a mouse highlight or a block cursor will
3154 be visible. If the image doesn't have a mask, make
3155 a block cursor visible by drawing a rectangle around
3156 the image. I believe it's looking better if we do
3157 nothing here for mouse-face. */
3158 if (s->hl == DRAW_CURSOR)
3160 int r = eabs (s->img->relief);
3161 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3162 s->slice.width + r*2 - 1,
3163 s->slice.height + r*2 - 1);
3167 else
3168 /* Draw a rectangle if image could not be loaded. */
3169 x_draw_rectangle (s->f, s->gc, x, y,
3170 s->slice.width - 1, s->slice.height - 1);
3174 /* Draw part of the background of glyph string S. X, Y, W, and H
3175 give the rectangle to draw. */
3177 static void
3178 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3180 if (s->stippled_p)
3182 /* Fill background with a stipple pattern. */
3183 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3184 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3185 XSetFillStyle (s->display, s->gc, FillSolid);
3187 else
3188 x_clear_glyph_string_rect (s, x, y, w, h);
3192 /* Draw image glyph string S.
3194 s->y
3195 s->x +-------------------------
3196 | s->face->box
3198 | +-------------------------
3199 | | s->img->margin
3201 | | +-------------------
3202 | | | the image
3206 static void
3207 x_draw_image_glyph_string (struct glyph_string *s)
3209 int box_line_hwidth = eabs (s->face->box_line_width);
3210 int box_line_vwidth = max (s->face->box_line_width, 0);
3211 int height;
3212 Pixmap pixmap = None;
3214 height = s->height;
3215 if (s->slice.y == 0)
3216 height -= box_line_vwidth;
3217 if (s->slice.y + s->slice.height >= s->img->height)
3218 height -= box_line_vwidth;
3220 /* Fill background with face under the image. Do it only if row is
3221 taller than image or if image has a clip mask to reduce
3222 flickering. */
3223 s->stippled_p = s->face->stipple != 0;
3224 if (height > s->slice.height
3225 || s->img->hmargin
3226 || s->img->vmargin
3227 || s->img->mask
3228 || s->img->pixmap == 0
3229 || s->width != s->background_width)
3231 if (s->img->mask)
3233 /* Create a pixmap as large as the glyph string. Fill it
3234 with the background color. Copy the image to it, using
3235 its mask. Copy the temporary pixmap to the display. */
3236 Screen *screen = FRAME_X_SCREEN (s->f);
3237 int depth = DefaultDepthOfScreen (screen);
3239 /* Create a pixmap as large as the glyph string. */
3240 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3241 s->background_width,
3242 s->height, depth);
3244 /* Don't clip in the following because we're working on the
3245 pixmap. */
3246 XSetClipMask (s->display, s->gc, None);
3248 /* Fill the pixmap with the background color/stipple. */
3249 if (s->stippled_p)
3251 /* Fill background with a stipple pattern. */
3252 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3253 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3254 XFillRectangle (s->display, pixmap, s->gc,
3255 0, 0, s->background_width, s->height);
3256 XSetFillStyle (s->display, s->gc, FillSolid);
3257 XSetTSOrigin (s->display, s->gc, 0, 0);
3259 else
3261 XGCValues xgcv;
3262 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3263 &xgcv);
3264 XSetForeground (s->display, s->gc, xgcv.background);
3265 XFillRectangle (s->display, pixmap, s->gc,
3266 0, 0, s->background_width, s->height);
3267 XSetForeground (s->display, s->gc, xgcv.foreground);
3270 else
3272 int x = s->x;
3273 int y = s->y;
3274 int width = s->background_width;
3276 if (s->first_glyph->left_box_line_p
3277 && s->slice.x == 0)
3279 x += box_line_hwidth;
3280 width -= box_line_hwidth;
3283 if (s->slice.y == 0)
3284 y += box_line_vwidth;
3286 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3289 s->background_filled_p = true;
3292 /* Draw the foreground. */
3293 #ifdef USE_CAIRO
3294 if (s->img->cr_data)
3296 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3298 int x = s->x + s->img->hmargin;
3299 int y = s->y + s->img->vmargin;
3300 int width = s->background_width;
3302 cairo_set_source_surface (cr, s->img->cr_data,
3303 x - s->slice.x,
3304 y - s->slice.y);
3305 cairo_rectangle (cr, x, y, width, height);
3306 cairo_fill (cr);
3307 x_end_cr_clip (s->f);
3309 else
3310 #endif
3311 if (pixmap != None)
3313 x_draw_image_foreground_1 (s, pixmap);
3314 x_set_glyph_string_clipping (s);
3315 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3316 0, 0, s->background_width, s->height, s->x, s->y);
3317 XFreePixmap (s->display, pixmap);
3319 else
3320 x_draw_image_foreground (s);
3322 /* If we must draw a relief around the image, do it. */
3323 if (s->img->relief
3324 || s->hl == DRAW_IMAGE_RAISED
3325 || s->hl == DRAW_IMAGE_SUNKEN)
3326 x_draw_image_relief (s);
3330 /* Draw stretch glyph string S. */
3332 static void
3333 x_draw_stretch_glyph_string (struct glyph_string *s)
3335 eassert (s->first_glyph->type == STRETCH_GLYPH);
3337 if (s->hl == DRAW_CURSOR
3338 && !x_stretch_cursor_p)
3340 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3341 wide as the stretch glyph. */
3342 int width, background_width = s->background_width;
3343 int x = s->x;
3345 if (!s->row->reversed_p)
3347 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3349 if (x < left_x)
3351 background_width -= left_x - x;
3352 x = left_x;
3355 else
3357 /* In R2L rows, draw the cursor on the right edge of the
3358 stretch glyph. */
3359 int right_x = window_box_right (s->w, TEXT_AREA);
3361 if (x + background_width > right_x)
3362 background_width -= x - right_x;
3363 x += background_width;
3365 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3366 if (s->row->reversed_p)
3367 x -= width;
3369 /* Draw cursor. */
3370 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3372 /* Clear rest using the GC of the original non-cursor face. */
3373 if (width < background_width)
3375 int y = s->y;
3376 int w = background_width - width, h = s->height;
3377 XRectangle r;
3378 GC gc;
3380 if (!s->row->reversed_p)
3381 x += width;
3382 else
3383 x = s->x;
3384 if (s->row->mouse_face_p
3385 && cursor_in_mouse_face_p (s->w))
3387 x_set_mouse_face_gc (s);
3388 gc = s->gc;
3390 else
3391 gc = s->face->gc;
3393 get_glyph_string_clip_rect (s, &r);
3394 x_set_clip_rectangles (s->f, gc, &r, 1);
3396 if (s->face->stipple)
3398 /* Fill background with a stipple pattern. */
3399 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3400 x_fill_rectangle (s->f, gc, x, y, w, h);
3401 XSetFillStyle (s->display, gc, FillSolid);
3403 else
3405 XGCValues xgcv;
3406 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3407 XSetForeground (s->display, gc, xgcv.background);
3408 x_fill_rectangle (s->f, gc, x, y, w, h);
3409 XSetForeground (s->display, gc, xgcv.foreground);
3412 x_reset_clip_rectangles (s->f, gc);
3415 else if (!s->background_filled_p)
3417 int background_width = s->background_width;
3418 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3420 /* Don't draw into left margin, fringe or scrollbar area
3421 except for header line and mode line. */
3422 if (x < left_x && !s->row->mode_line_p)
3424 background_width -= left_x - x;
3425 x = left_x;
3427 if (background_width > 0)
3428 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3431 s->background_filled_p = true;
3435 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3437 x0 wave_length = 2
3439 y0 * * * * *
3440 |* * * * * * * * *
3441 wave_height = 3 | * * * *
3445 static void
3446 x_draw_underwave (struct glyph_string *s)
3448 int wave_height = 3, wave_length = 2;
3449 #ifdef USE_CAIRO
3450 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3451 s->width, wave_height, wave_length);
3452 #else /* not USE_CAIRO */
3453 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3454 bool odd;
3455 XRectangle wave_clip, string_clip, final_clip;
3457 dx = wave_length;
3458 dy = wave_height - 1;
3459 x0 = s->x;
3460 y0 = s->ybase - wave_height + 3;
3461 width = s->width;
3462 xmax = x0 + width;
3464 /* Find and set clipping rectangle */
3466 wave_clip.x = x0;
3467 wave_clip.y = y0;
3468 wave_clip.width = width;
3469 wave_clip.height = wave_height;
3470 get_glyph_string_clip_rect (s, &string_clip);
3472 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3473 return;
3475 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3477 /* Draw the waves */
3479 x1 = x0 - (x0 % dx);
3480 x2 = x1 + dx;
3481 odd = (x1 / dx) & 1;
3482 y1 = y2 = y0;
3484 if (odd)
3485 y1 += dy;
3486 else
3487 y2 += dy;
3489 if (INT_MAX - dx < xmax)
3490 emacs_abort ();
3492 while (x1 <= xmax)
3494 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3495 x1 = x2, y1 = y2;
3496 x2 += dx, y2 = y0 + odd*dy;
3497 odd = !odd;
3500 /* Restore previous clipping rectangle(s) */
3501 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3502 #endif /* not USE_CAIRO */
3506 /* Draw glyph string S. */
3508 static void
3509 x_draw_glyph_string (struct glyph_string *s)
3511 bool relief_drawn_p = false;
3513 /* If S draws into the background of its successors, draw the
3514 background of the successors first so that S can draw into it.
3515 This makes S->next use XDrawString instead of XDrawImageString. */
3516 if (s->next && s->right_overhang && !s->for_overlaps)
3518 int width;
3519 struct glyph_string *next;
3521 for (width = 0, next = s->next;
3522 next && width < s->right_overhang;
3523 width += next->width, next = next->next)
3524 if (next->first_glyph->type != IMAGE_GLYPH)
3526 x_set_glyph_string_gc (next);
3527 x_set_glyph_string_clipping (next);
3528 if (next->first_glyph->type == STRETCH_GLYPH)
3529 x_draw_stretch_glyph_string (next);
3530 else
3531 x_draw_glyph_string_background (next, true);
3532 next->num_clips = 0;
3536 /* Set up S->gc, set clipping and draw S. */
3537 x_set_glyph_string_gc (s);
3539 /* Draw relief (if any) in advance for char/composition so that the
3540 glyph string can be drawn over it. */
3541 if (!s->for_overlaps
3542 && s->face->box != FACE_NO_BOX
3543 && (s->first_glyph->type == CHAR_GLYPH
3544 || s->first_glyph->type == COMPOSITE_GLYPH))
3547 x_set_glyph_string_clipping (s);
3548 x_draw_glyph_string_background (s, true);
3549 x_draw_glyph_string_box (s);
3550 x_set_glyph_string_clipping (s);
3551 relief_drawn_p = true;
3553 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3554 && !s->clip_tail
3555 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3556 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3557 /* We must clip just this glyph. left_overhang part has already
3558 drawn when s->prev was drawn, and right_overhang part will be
3559 drawn later when s->next is drawn. */
3560 x_set_glyph_string_clipping_exactly (s, s);
3561 else
3562 x_set_glyph_string_clipping (s);
3564 switch (s->first_glyph->type)
3566 case IMAGE_GLYPH:
3567 x_draw_image_glyph_string (s);
3568 break;
3570 case XWIDGET_GLYPH:
3571 x_draw_xwidget_glyph_string (s);
3572 break;
3574 case STRETCH_GLYPH:
3575 x_draw_stretch_glyph_string (s);
3576 break;
3578 case CHAR_GLYPH:
3579 if (s->for_overlaps)
3580 s->background_filled_p = true;
3581 else
3582 x_draw_glyph_string_background (s, false);
3583 x_draw_glyph_string_foreground (s);
3584 break;
3586 case COMPOSITE_GLYPH:
3587 if (s->for_overlaps || (s->cmp_from > 0
3588 && ! s->first_glyph->u.cmp.automatic))
3589 s->background_filled_p = true;
3590 else
3591 x_draw_glyph_string_background (s, true);
3592 x_draw_composite_glyph_string_foreground (s);
3593 break;
3595 case GLYPHLESS_GLYPH:
3596 if (s->for_overlaps)
3597 s->background_filled_p = true;
3598 else
3599 x_draw_glyph_string_background (s, true);
3600 x_draw_glyphless_glyph_string_foreground (s);
3601 break;
3603 default:
3604 emacs_abort ();
3607 if (!s->for_overlaps)
3609 /* Draw underline. */
3610 if (s->face->underline_p)
3612 if (s->face->underline_type == FACE_UNDER_WAVE)
3614 if (s->face->underline_defaulted_p)
3615 x_draw_underwave (s);
3616 else
3618 XGCValues xgcv;
3619 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3620 XSetForeground (s->display, s->gc, s->face->underline_color);
3621 x_draw_underwave (s);
3622 XSetForeground (s->display, s->gc, xgcv.foreground);
3625 else if (s->face->underline_type == FACE_UNDER_LINE)
3627 unsigned long thickness, position;
3628 int y;
3630 if (s->prev && s->prev->face->underline_p
3631 && s->prev->face->underline_type == FACE_UNDER_LINE)
3633 /* We use the same underline style as the previous one. */
3634 thickness = s->prev->underline_thickness;
3635 position = s->prev->underline_position;
3637 else
3639 struct font *font = font_for_underline_metrics (s);
3641 /* Get the underline thickness. Default is 1 pixel. */
3642 if (font && font->underline_thickness > 0)
3643 thickness = font->underline_thickness;
3644 else
3645 thickness = 1;
3646 if (x_underline_at_descent_line)
3647 position = (s->height - thickness) - (s->ybase - s->y);
3648 else
3650 /* Get the underline position. This is the recommended
3651 vertical offset in pixels from the baseline to the top of
3652 the underline. This is a signed value according to the
3653 specs, and its default is
3655 ROUND ((maximum descent) / 2), with
3656 ROUND(x) = floor (x + 0.5) */
3658 if (x_use_underline_position_properties
3659 && font && font->underline_position >= 0)
3660 position = font->underline_position;
3661 else if (font)
3662 position = (font->descent + 1) / 2;
3663 else
3664 position = underline_minimum_offset;
3666 position = max (position, underline_minimum_offset);
3668 /* Check the sanity of thickness and position. We should
3669 avoid drawing underline out of the current line area. */
3670 if (s->y + s->height <= s->ybase + position)
3671 position = (s->height - 1) - (s->ybase - s->y);
3672 if (s->y + s->height < s->ybase + position + thickness)
3673 thickness = (s->y + s->height) - (s->ybase + position);
3674 s->underline_thickness = thickness;
3675 s->underline_position = position;
3676 y = s->ybase + position;
3677 if (s->face->underline_defaulted_p)
3678 x_fill_rectangle (s->f, s->gc,
3679 s->x, y, s->width, thickness);
3680 else
3682 XGCValues xgcv;
3683 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3684 XSetForeground (s->display, s->gc, s->face->underline_color);
3685 x_fill_rectangle (s->f, s->gc,
3686 s->x, y, s->width, thickness);
3687 XSetForeground (s->display, s->gc, xgcv.foreground);
3691 /* Draw overline. */
3692 if (s->face->overline_p)
3694 unsigned long dy = 0, h = 1;
3696 if (s->face->overline_color_defaulted_p)
3697 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3698 s->width, h);
3699 else
3701 XGCValues xgcv;
3702 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3703 XSetForeground (s->display, s->gc, s->face->overline_color);
3704 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3705 s->width, h);
3706 XSetForeground (s->display, s->gc, xgcv.foreground);
3710 /* Draw strike-through. */
3711 if (s->face->strike_through_p)
3713 /* Y-coordinate and height of the glyph string's first
3714 glyph. We cannot use s->y and s->height because those
3715 could be larger if there are taller display elements
3716 (e.g., characters displayed with a larger font) in the
3717 same glyph row. */
3718 int glyph_y = s->ybase - s->first_glyph->ascent;
3719 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3720 /* Strike-through width and offset from the glyph string's
3721 top edge. */
3722 unsigned long h = 1;
3723 unsigned long dy = (glyph_height - h) / 2;
3725 if (s->face->strike_through_color_defaulted_p)
3726 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3727 s->width, h);
3728 else
3730 XGCValues xgcv;
3731 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3732 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3733 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3734 s->width, h);
3735 XSetForeground (s->display, s->gc, xgcv.foreground);
3739 /* Draw relief if not yet drawn. */
3740 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3741 x_draw_glyph_string_box (s);
3743 if (s->prev)
3745 struct glyph_string *prev;
3747 for (prev = s->prev; prev; prev = prev->prev)
3748 if (prev->hl != s->hl
3749 && prev->x + prev->width + prev->right_overhang > s->x)
3751 /* As prev was drawn while clipped to its own area, we
3752 must draw the right_overhang part using s->hl now. */
3753 enum draw_glyphs_face save = prev->hl;
3755 prev->hl = s->hl;
3756 x_set_glyph_string_gc (prev);
3757 x_set_glyph_string_clipping_exactly (s, prev);
3758 if (prev->first_glyph->type == CHAR_GLYPH)
3759 x_draw_glyph_string_foreground (prev);
3760 else
3761 x_draw_composite_glyph_string_foreground (prev);
3762 x_reset_clip_rectangles (prev->f, prev->gc);
3763 prev->hl = save;
3764 prev->num_clips = 0;
3768 if (s->next)
3770 struct glyph_string *next;
3772 for (next = s->next; next; next = next->next)
3773 if (next->hl != s->hl
3774 && next->x - next->left_overhang < s->x + s->width)
3776 /* As next will be drawn while clipped to its own area,
3777 we must draw the left_overhang part using s->hl now. */
3778 enum draw_glyphs_face save = next->hl;
3780 next->hl = s->hl;
3781 x_set_glyph_string_gc (next);
3782 x_set_glyph_string_clipping_exactly (s, next);
3783 if (next->first_glyph->type == CHAR_GLYPH)
3784 x_draw_glyph_string_foreground (next);
3785 else
3786 x_draw_composite_glyph_string_foreground (next);
3787 x_reset_clip_rectangles (next->f, next->gc);
3788 next->hl = save;
3789 next->num_clips = 0;
3790 next->clip_head = s->next;
3795 /* Reset clipping. */
3796 x_reset_clip_rectangles (s->f, s->gc);
3797 s->num_clips = 0;
3800 /* Shift display to make room for inserted glyphs. */
3802 static void
3803 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3805 /* Never called on a GUI frame, see
3806 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3808 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3809 f->output_data.x->normal_gc,
3810 x, y, width, height,
3811 x + shift_by, y);
3814 /* Delete N glyphs at the nominal cursor position. Not implemented
3815 for X frames. */
3817 static void
3818 x_delete_glyphs (struct frame *f, register int n)
3820 emacs_abort ();
3824 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3825 If they are <= 0, this is probably an error. */
3827 static ATTRIBUTE_UNUSED void
3828 x_clear_area1 (Display *dpy, Window window,
3829 int x, int y, int width, int height, int exposures)
3831 eassert (width > 0 && height > 0);
3832 XClearArea (dpy, window, x, y, width, height, exposures);
3835 void
3836 x_clear_area (struct frame *f, int x, int y, int width, int height)
3838 #ifdef USE_CAIRO
3839 cairo_t *cr;
3841 eassert (width > 0 && height > 0);
3843 cr = x_begin_cr_clip (f, NULL);
3844 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3845 cairo_rectangle (cr, x, y, width, height);
3846 cairo_fill (cr);
3847 x_end_cr_clip (f);
3848 #else
3849 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3850 XFillRectangle (FRAME_X_DISPLAY (f),
3851 FRAME_X_DRAWABLE (f),
3852 f->output_data.x->reverse_gc,
3853 x, y, width, height);
3854 else
3855 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3856 x, y, width, height, False);
3857 #endif
3861 /* Clear an entire frame. */
3863 static void
3864 x_clear_frame (struct frame *f)
3866 /* Clearing the frame will erase any cursor, so mark them all as no
3867 longer visible. */
3868 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3870 block_input ();
3872 font_drop_xrender_surfaces (f);
3873 x_clear_window (f);
3875 /* We have to clear the scroll bars. If we have changed colors or
3876 something like that, then they should be notified. */
3877 x_scroll_bar_clear (f);
3879 XFlush (FRAME_X_DISPLAY (f));
3881 unblock_input ();
3884 /* RIF: Show hourglass cursor on frame F. */
3886 static void
3887 x_show_hourglass (struct frame *f)
3889 Display *dpy = FRAME_X_DISPLAY (f);
3891 if (dpy)
3893 struct x_output *x = FRAME_X_OUTPUT (f);
3894 #ifdef USE_X_TOOLKIT
3895 if (x->widget)
3896 #else
3897 if (FRAME_OUTER_WINDOW (f))
3898 #endif
3900 x->hourglass_p = true;
3902 if (!x->hourglass_window)
3904 unsigned long mask = CWCursor;
3905 XSetWindowAttributes attrs;
3906 #ifdef USE_GTK
3907 Window parent = FRAME_X_WINDOW (f);
3908 #else
3909 Window parent = FRAME_OUTER_WINDOW (f);
3910 #endif
3911 attrs.cursor = x->hourglass_cursor;
3913 x->hourglass_window = XCreateWindow
3914 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3915 InputOnly, CopyFromParent, mask, &attrs);
3918 XMapRaised (dpy, x->hourglass_window);
3919 XFlush (dpy);
3924 /* RIF: Cancel hourglass cursor on frame F. */
3926 static void
3927 x_hide_hourglass (struct frame *f)
3929 struct x_output *x = FRAME_X_OUTPUT (f);
3931 /* Watch out for newly created frames. */
3932 if (x->hourglass_window)
3934 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3935 /* Sync here because XTread_socket looks at the
3936 hourglass_p flag that is reset to zero below. */
3937 XSync (FRAME_X_DISPLAY (f), False);
3938 x->hourglass_p = false;
3942 /* Invert the middle quarter of the frame for .15 sec. */
3944 static void
3945 XTflash (struct frame *f)
3947 block_input ();
3950 #ifdef USE_GTK
3951 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3952 when the scroll bars and the edit widget share the same X window. */
3953 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3954 #ifdef HAVE_GTK3
3955 cairo_t *cr = gdk_cairo_create (window);
3956 cairo_set_source_rgb (cr, 1, 1, 1);
3957 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
3958 #define XFillRectangle(d, win, gc, x, y, w, h) \
3959 do { \
3960 cairo_rectangle (cr, x, y, w, h); \
3961 cairo_fill (cr); \
3963 while (false)
3964 #else /* ! HAVE_GTK3 */
3965 GdkGCValues vals;
3966 GdkGC *gc;
3967 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
3968 ^ FRAME_BACKGROUND_PIXEL (f));
3969 vals.function = GDK_XOR;
3970 gc = gdk_gc_new_with_values (window,
3971 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
3972 #define XFillRectangle(d, win, gc, x, y, w, h) \
3973 gdk_draw_rectangle (window, gc, true, x, y, w, h)
3974 #endif /* ! HAVE_GTK3 */
3975 #else /* ! USE_GTK */
3976 GC gc;
3978 /* Create a GC that will use the GXxor function to flip foreground
3979 pixels into background pixels. */
3981 XGCValues values;
3983 values.function = GXxor;
3984 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
3985 ^ FRAME_BACKGROUND_PIXEL (f));
3987 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3988 GCFunction | GCForeground, &values);
3990 #endif
3992 /* Get the height not including a menu bar widget. */
3993 int height = FRAME_PIXEL_HEIGHT (f);
3994 /* Height of each line to flash. */
3995 int flash_height = FRAME_LINE_HEIGHT (f);
3996 /* These will be the left and right margins of the rectangles. */
3997 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3998 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3999 int width = flash_right - flash_left;
4001 /* If window is tall, flash top and bottom line. */
4002 if (height > 3 * FRAME_LINE_HEIGHT (f))
4004 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4005 flash_left,
4006 (FRAME_INTERNAL_BORDER_WIDTH (f)
4007 + FRAME_TOP_MARGIN_HEIGHT (f)),
4008 width, flash_height);
4009 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4010 flash_left,
4011 (height - flash_height
4012 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4013 width, flash_height);
4016 else
4017 /* If it is short, flash it all. */
4018 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4019 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4020 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4022 x_flush (f);
4025 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4026 struct timespec wakeup = timespec_add (current_timespec (), delay);
4028 /* Keep waiting until past the time wakeup or any input gets
4029 available. */
4030 while (! detect_input_pending ())
4032 struct timespec current = current_timespec ();
4033 struct timespec timeout;
4035 /* Break if result would not be positive. */
4036 if (timespec_cmp (wakeup, current) <= 0)
4037 break;
4039 /* How long `select' should wait. */
4040 timeout = make_timespec (0, 10 * 1000 * 1000);
4042 /* Try to wait that long--but we might wake up sooner. */
4043 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4047 /* If window is tall, flash top and bottom line. */
4048 if (height > 3 * FRAME_LINE_HEIGHT (f))
4050 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4051 flash_left,
4052 (FRAME_INTERNAL_BORDER_WIDTH (f)
4053 + FRAME_TOP_MARGIN_HEIGHT (f)),
4054 width, flash_height);
4055 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4056 flash_left,
4057 (height - flash_height
4058 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4059 width, flash_height);
4061 else
4062 /* If it is short, flash it all. */
4063 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4064 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4065 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4067 #ifdef USE_GTK
4068 #ifdef HAVE_GTK3
4069 cairo_destroy (cr);
4070 #else
4071 g_object_unref (G_OBJECT (gc));
4072 #endif
4073 #undef XFillRectangle
4074 #else
4075 XFreeGC (FRAME_X_DISPLAY (f), gc);
4076 #endif
4077 x_flush (f);
4081 unblock_input ();
4085 static void
4086 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4088 block_input ();
4089 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4090 unblock_input ();
4094 /* Make audible bell. */
4096 static void
4097 XTring_bell (struct frame *f)
4099 if (FRAME_X_DISPLAY (f))
4101 if (visible_bell)
4102 XTflash (f);
4103 else
4105 block_input ();
4106 #ifdef HAVE_XKB
4107 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4108 #else
4109 XBell (FRAME_X_DISPLAY (f), 0);
4110 #endif
4111 XFlush (FRAME_X_DISPLAY (f));
4112 unblock_input ();
4117 /***********************************************************************
4118 Line Dance
4119 ***********************************************************************/
4121 /* Perform an insert-lines or delete-lines operation, inserting N
4122 lines or deleting -N lines at vertical position VPOS. */
4124 static void
4125 x_ins_del_lines (struct frame *f, int vpos, int n)
4127 emacs_abort ();
4131 /* Scroll part of the display as described by RUN. */
4133 static void
4134 x_scroll_run (struct window *w, struct run *run)
4136 struct frame *f = XFRAME (w->frame);
4137 int x, y, width, height, from_y, to_y, bottom_y;
4139 /* Get frame-relative bounding box of the text display area of W,
4140 without mode lines. Include in this box the left and right
4141 fringe of W. */
4142 window_box (w, ANY_AREA, &x, &y, &width, &height);
4144 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4145 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4146 bottom_y = y + height;
4148 if (to_y < from_y)
4150 /* Scrolling up. Make sure we don't copy part of the mode
4151 line at the bottom. */
4152 if (from_y + run->height > bottom_y)
4153 height = bottom_y - from_y;
4154 else
4155 height = run->height;
4157 else
4159 /* Scrolling down. Make sure we don't copy over the mode line.
4160 at the bottom. */
4161 if (to_y + run->height > bottom_y)
4162 height = bottom_y - to_y;
4163 else
4164 height = run->height;
4167 block_input ();
4169 /* Cursor off. Will be switched on again in x_update_window_end. */
4170 x_clear_cursor (w);
4172 #ifdef USE_CAIRO
4173 SET_FRAME_GARBAGED (f);
4174 #else
4175 XCopyArea (FRAME_X_DISPLAY (f),
4176 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4177 f->output_data.x->normal_gc,
4178 x, from_y,
4179 width, height,
4180 x, to_y);
4181 #endif
4183 unblock_input ();
4188 /***********************************************************************
4189 Exposure Events
4190 ***********************************************************************/
4193 static void
4194 frame_highlight (struct frame *f)
4196 /* We used to only do this if Vx_no_window_manager was non-nil, but
4197 the ICCCM (section 4.1.6) says that the window's border pixmap
4198 and border pixel are window attributes which are "private to the
4199 client", so we can always change it to whatever we want. */
4200 block_input ();
4201 /* I recently started to get errors in this XSetWindowBorder, depending on
4202 the window-manager in use, tho something more is at play since I've been
4203 using that same window-manager binary for ever. Let's not crash just
4204 because of this (bug#9310). */
4205 x_catch_errors (FRAME_X_DISPLAY (f));
4206 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4207 f->output_data.x->border_pixel);
4208 x_uncatch_errors ();
4209 unblock_input ();
4210 x_update_cursor (f, true);
4211 x_set_frame_alpha (f);
4214 static void
4215 frame_unhighlight (struct frame *f)
4217 /* We used to only do this if Vx_no_window_manager was non-nil, but
4218 the ICCCM (section 4.1.6) says that the window's border pixmap
4219 and border pixel are window attributes which are "private to the
4220 client", so we can always change it to whatever we want. */
4221 block_input ();
4222 /* Same as above for XSetWindowBorder (bug#9310). */
4223 x_catch_errors (FRAME_X_DISPLAY (f));
4224 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4225 f->output_data.x->border_tile);
4226 x_uncatch_errors ();
4227 unblock_input ();
4228 x_update_cursor (f, true);
4229 x_set_frame_alpha (f);
4232 /* The focus has changed. Update the frames as necessary to reflect
4233 the new situation. Note that we can't change the selected frame
4234 here, because the Lisp code we are interrupting might become confused.
4235 Each event gets marked with the frame in which it occurred, so the
4236 Lisp code can tell when the switch took place by examining the events. */
4238 static void
4239 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4241 struct frame *old_focus = dpyinfo->x_focus_frame;
4243 if (frame != dpyinfo->x_focus_frame)
4245 /* Set this before calling other routines, so that they see
4246 the correct value of x_focus_frame. */
4247 dpyinfo->x_focus_frame = frame;
4249 if (old_focus && old_focus->auto_lower)
4250 x_lower_frame (old_focus);
4252 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4253 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4254 else
4255 dpyinfo->x_pending_autoraise_frame = NULL;
4258 x_frame_rehighlight (dpyinfo);
4261 /* Handle FocusIn and FocusOut state changes for FRAME.
4262 If FRAME has focus and there exists more than one frame, puts
4263 a FOCUS_IN_EVENT into *BUFP. */
4265 static void
4266 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4268 if (type == FocusIn)
4270 if (dpyinfo->x_focus_event_frame != frame)
4272 x_new_focus_frame (dpyinfo, frame);
4273 dpyinfo->x_focus_event_frame = frame;
4275 /* Don't stop displaying the initial startup message
4276 for a switch-frame event we don't need. */
4277 /* When run as a daemon, Vterminal_frame is always NIL. */
4278 bufp->arg = (((NILP (Vterminal_frame)
4279 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4280 || EQ (Fdaemonp (), Qt))
4281 && CONSP (Vframe_list)
4282 && !NILP (XCDR (Vframe_list)))
4283 ? Qt : Qnil);
4284 bufp->kind = FOCUS_IN_EVENT;
4285 XSETFRAME (bufp->frame_or_window, frame);
4288 frame->output_data.x->focus_state |= state;
4290 #ifdef HAVE_X_I18N
4291 if (FRAME_XIC (frame))
4292 XSetICFocus (FRAME_XIC (frame));
4293 #endif
4295 else if (type == FocusOut)
4297 frame->output_data.x->focus_state &= ~state;
4299 if (dpyinfo->x_focus_event_frame == frame)
4301 dpyinfo->x_focus_event_frame = 0;
4302 x_new_focus_frame (dpyinfo, 0);
4304 bufp->kind = FOCUS_OUT_EVENT;
4305 XSETFRAME (bufp->frame_or_window, frame);
4308 #ifdef HAVE_X_I18N
4309 if (FRAME_XIC (frame))
4310 XUnsetICFocus (FRAME_XIC (frame));
4311 #endif
4312 if (frame->pointer_invisible)
4313 XTtoggle_invisible_pointer (frame, false);
4317 /* Return the Emacs frame-object corresponding to an X window.
4318 It could be the frame's main window or an icon window. */
4320 static struct frame *
4321 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4323 Lisp_Object tail, frame;
4324 struct frame *f;
4326 if (wdesc == None)
4327 return NULL;
4329 FOR_EACH_FRAME (tail, frame)
4331 f = XFRAME (frame);
4332 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4333 continue;
4334 if (f->output_data.x->hourglass_window == wdesc)
4335 return f;
4336 #ifdef USE_X_TOOLKIT
4337 if ((f->output_data.x->edit_widget
4338 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4339 /* A tooltip frame? */
4340 || (!f->output_data.x->edit_widget
4341 && FRAME_X_WINDOW (f) == wdesc)
4342 || f->output_data.x->icon_desc == wdesc)
4343 return f;
4344 #else /* not USE_X_TOOLKIT */
4345 #ifdef USE_GTK
4346 if (f->output_data.x->edit_widget)
4348 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4349 struct x_output *x = f->output_data.x;
4350 if (gwdesc != 0 && gwdesc == x->edit_widget)
4351 return f;
4353 #endif /* USE_GTK */
4354 if (FRAME_X_WINDOW (f) == wdesc
4355 || f->output_data.x->icon_desc == wdesc)
4356 return f;
4357 #endif /* not USE_X_TOOLKIT */
4359 return 0;
4362 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4364 /* Like x_window_to_frame but also compares the window with the widget's
4365 windows. */
4367 static struct frame *
4368 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4370 Lisp_Object tail, frame;
4371 struct frame *f, *found = NULL;
4372 struct x_output *x;
4374 if (wdesc == None)
4375 return NULL;
4377 FOR_EACH_FRAME (tail, frame)
4379 if (found)
4380 break;
4381 f = XFRAME (frame);
4382 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4384 /* This frame matches if the window is any of its widgets. */
4385 x = f->output_data.x;
4386 if (x->hourglass_window == wdesc)
4387 found = f;
4388 else if (x->widget)
4390 #ifdef USE_GTK
4391 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4392 if (gwdesc != 0
4393 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4394 found = f;
4395 #else
4396 if (wdesc == XtWindow (x->widget)
4397 || wdesc == XtWindow (x->column_widget)
4398 || wdesc == XtWindow (x->edit_widget))
4399 found = f;
4400 /* Match if the window is this frame's menubar. */
4401 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4402 found = f;
4403 #endif
4405 else if (FRAME_X_WINDOW (f) == wdesc)
4406 /* A tooltip frame. */
4407 found = f;
4411 return found;
4414 /* Likewise, but consider only the menu bar widget. */
4416 static struct frame *
4417 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4418 const XEvent *event)
4420 Window wdesc = event->xany.window;
4421 Lisp_Object tail, frame;
4422 struct frame *f;
4423 struct x_output *x;
4425 if (wdesc == None)
4426 return NULL;
4428 FOR_EACH_FRAME (tail, frame)
4430 f = XFRAME (frame);
4431 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4432 continue;
4433 x = f->output_data.x;
4434 #ifdef USE_GTK
4435 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4436 return f;
4437 #else
4438 /* Match if the window is this frame's menubar. */
4439 if (x->menubar_widget
4440 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4441 return f;
4442 #endif
4444 return 0;
4447 /* Return the frame whose principal (outermost) window is WDESC.
4448 If WDESC is some other (smaller) window, we return 0. */
4450 struct frame *
4451 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4453 Lisp_Object tail, frame;
4454 struct frame *f;
4455 struct x_output *x;
4457 if (wdesc == None)
4458 return NULL;
4460 FOR_EACH_FRAME (tail, frame)
4462 f = XFRAME (frame);
4463 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4464 continue;
4465 x = f->output_data.x;
4467 if (x->widget)
4469 /* This frame matches if the window is its topmost widget. */
4470 #ifdef USE_GTK
4471 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4472 if (gwdesc == x->widget)
4473 return f;
4474 #else
4475 if (wdesc == XtWindow (x->widget))
4476 return f;
4477 #endif
4479 else if (FRAME_X_WINDOW (f) == wdesc)
4480 /* Tooltip frame. */
4481 return f;
4483 return 0;
4486 #else /* !USE_X_TOOLKIT && !USE_GTK */
4488 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4489 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4491 #endif /* USE_X_TOOLKIT || USE_GTK */
4493 /* The focus may have changed. Figure out if it is a real focus change,
4494 by checking both FocusIn/Out and Enter/LeaveNotify events.
4496 Returns FOCUS_IN_EVENT event in *BUFP. */
4498 static void
4499 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4500 const XEvent *event, struct input_event *bufp)
4502 if (!frame)
4503 return;
4505 switch (event->type)
4507 case EnterNotify:
4508 case LeaveNotify:
4510 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4511 int focus_state
4512 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4514 if (event->xcrossing.detail != NotifyInferior
4515 && event->xcrossing.focus
4516 && ! (focus_state & FOCUS_EXPLICIT))
4517 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4518 FOCUS_IMPLICIT,
4519 dpyinfo, frame, bufp);
4521 break;
4523 case FocusIn:
4524 case FocusOut:
4525 x_focus_changed (event->type,
4526 (event->xfocus.detail == NotifyPointer ?
4527 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4528 dpyinfo, frame, bufp);
4529 break;
4531 case ClientMessage:
4532 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4534 enum xembed_message msg = event->xclient.data.l[1];
4535 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4536 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4538 break;
4543 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4544 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4546 void
4547 x_mouse_leave (struct x_display_info *dpyinfo)
4549 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4551 #endif
4553 /* The focus has changed, or we have redirected a frame's focus to
4554 another frame (this happens when a frame uses a surrogate
4555 mini-buffer frame). Shift the highlight as appropriate.
4557 The FRAME argument doesn't necessarily have anything to do with which
4558 frame is being highlighted or un-highlighted; we only use it to find
4559 the appropriate X display info. */
4561 static void
4562 XTframe_rehighlight (struct frame *frame)
4564 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4567 static void
4568 x_frame_rehighlight (struct x_display_info *dpyinfo)
4570 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4572 if (dpyinfo->x_focus_frame)
4574 dpyinfo->x_highlight_frame
4575 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4576 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4577 : dpyinfo->x_focus_frame);
4578 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4580 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4581 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4584 else
4585 dpyinfo->x_highlight_frame = 0;
4587 if (dpyinfo->x_highlight_frame != old_highlight)
4589 if (old_highlight)
4590 frame_unhighlight (old_highlight);
4591 if (dpyinfo->x_highlight_frame)
4592 frame_highlight (dpyinfo->x_highlight_frame);
4598 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4600 /* Initialize mode_switch_bit and modifier_meaning. */
4601 static void
4602 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4604 int min_code, max_code;
4605 KeySym *syms;
4606 int syms_per_code;
4607 XModifierKeymap *mods;
4609 dpyinfo->meta_mod_mask = 0;
4610 dpyinfo->shift_lock_mask = 0;
4611 dpyinfo->alt_mod_mask = 0;
4612 dpyinfo->super_mod_mask = 0;
4613 dpyinfo->hyper_mod_mask = 0;
4615 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4617 syms = XGetKeyboardMapping (dpyinfo->display,
4618 min_code, max_code - min_code + 1,
4619 &syms_per_code);
4620 mods = XGetModifierMapping (dpyinfo->display);
4622 /* Scan the modifier table to see which modifier bits the Meta and
4623 Alt keysyms are on. */
4625 int row, col; /* The row and column in the modifier table. */
4626 bool found_alt_or_meta;
4628 for (row = 3; row < 8; row++)
4630 found_alt_or_meta = false;
4631 for (col = 0; col < mods->max_keypermod; col++)
4633 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4635 /* Zeroes are used for filler. Skip them. */
4636 if (code == 0)
4637 continue;
4639 /* Are any of this keycode's keysyms a meta key? */
4641 int code_col;
4643 for (code_col = 0; code_col < syms_per_code; code_col++)
4645 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4647 switch (sym)
4649 case XK_Meta_L:
4650 case XK_Meta_R:
4651 found_alt_or_meta = true;
4652 dpyinfo->meta_mod_mask |= (1 << row);
4653 break;
4655 case XK_Alt_L:
4656 case XK_Alt_R:
4657 found_alt_or_meta = true;
4658 dpyinfo->alt_mod_mask |= (1 << row);
4659 break;
4661 case XK_Hyper_L:
4662 case XK_Hyper_R:
4663 if (!found_alt_or_meta)
4664 dpyinfo->hyper_mod_mask |= (1 << row);
4665 code_col = syms_per_code;
4666 col = mods->max_keypermod;
4667 break;
4669 case XK_Super_L:
4670 case XK_Super_R:
4671 if (!found_alt_or_meta)
4672 dpyinfo->super_mod_mask |= (1 << row);
4673 code_col = syms_per_code;
4674 col = mods->max_keypermod;
4675 break;
4677 case XK_Shift_Lock:
4678 /* Ignore this if it's not on the lock modifier. */
4679 if (!found_alt_or_meta && ((1 << row) == LockMask))
4680 dpyinfo->shift_lock_mask = LockMask;
4681 code_col = syms_per_code;
4682 col = mods->max_keypermod;
4683 break;
4691 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4692 if (! dpyinfo->meta_mod_mask)
4694 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4695 dpyinfo->alt_mod_mask = 0;
4698 /* If some keys are both alt and meta,
4699 make them just meta, not alt. */
4700 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4702 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4705 XFree (syms);
4706 XFreeModifiermap (mods);
4709 /* Convert between the modifier bits X uses and the modifier bits
4710 Emacs uses. */
4713 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4715 int mod_ctrl = ctrl_modifier;
4716 int mod_meta = meta_modifier;
4717 int mod_alt = alt_modifier;
4718 int mod_hyper = hyper_modifier;
4719 int mod_super = super_modifier;
4720 Lisp_Object tem;
4722 tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
4723 if (INTEGERP (tem)) mod_ctrl = XINT (tem) & INT_MAX;
4724 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4725 if (INTEGERP (tem)) mod_alt = XINT (tem) & INT_MAX;
4726 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4727 if (INTEGERP (tem)) mod_meta = XINT (tem) & INT_MAX;
4728 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4729 if (INTEGERP (tem)) mod_hyper = XINT (tem) & INT_MAX;
4730 tem = Fget (Vx_super_keysym, Qmodifier_value);
4731 if (INTEGERP (tem)) mod_super = XINT (tem) & INT_MAX;
4733 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
4734 | ((state & ControlMask) ? mod_ctrl : 0)
4735 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
4736 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
4737 | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
4738 | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
4741 static int
4742 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
4744 EMACS_INT mod_ctrl = ctrl_modifier;
4745 EMACS_INT mod_meta = meta_modifier;
4746 EMACS_INT mod_alt = alt_modifier;
4747 EMACS_INT mod_hyper = hyper_modifier;
4748 EMACS_INT mod_super = super_modifier;
4750 Lisp_Object tem;
4752 tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
4753 if (INTEGERP (tem)) mod_ctrl = XINT (tem);
4754 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4755 if (INTEGERP (tem)) mod_alt = XINT (<