* lisp/url/url-history.el: Use lexical-binding
[emacs.git] / src / xterm.c
bloba214cd81031a45c40a24d403feaf4210e7a9c53a
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 ptrdiff_t 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 if (!FRAME_PARENT_FRAME (f))
950 parent = x_find_topmost_parent (f);
951 if (parent != None)
952 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
953 XA_CARDINAL, 32, PropModeReplace,
954 (unsigned char *) &opac, 1);
957 /* return unless necessary */
959 unsigned char *data;
960 Atom actual;
961 int rc, format;
962 unsigned long n, left;
964 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
965 0, 1, False, XA_CARDINAL,
966 &actual, &format, &n, &left,
967 &data);
969 if (rc == Success && actual != None)
971 unsigned long value = *(unsigned long *)data;
972 XFree (data);
973 if (value == opac)
975 x_uncatch_errors ();
976 return;
981 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
982 XA_CARDINAL, 32, PropModeReplace,
983 (unsigned char *) &opac, 1);
984 x_uncatch_errors ();
987 /***********************************************************************
988 Starting and ending an update
989 ***********************************************************************/
991 /* Start an update of frame F. This function is installed as a hook
992 for update_begin, i.e. it is called when update_begin is called.
993 This function is called prior to calls to x_update_window_begin for
994 each window being updated. Currently, there is nothing to do here
995 because all interesting stuff is done on a window basis. */
997 static void
998 x_update_begin (struct frame *f)
1000 #ifdef USE_CAIRO
1001 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
1002 && ! FRAME_VISIBLE_P (f))
1003 return;
1005 if (! FRAME_CR_SURFACE (f))
1007 int width, height;
1008 #ifdef USE_GTK
1009 if (FRAME_GTK_WIDGET (f))
1011 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1012 width = gdk_window_get_width (w);
1013 height = gdk_window_get_height (w);
1015 else
1016 #endif
1018 width = FRAME_PIXEL_WIDTH (f);
1019 height = FRAME_PIXEL_HEIGHT (f);
1020 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1021 height += FRAME_TOOL_BAR_HEIGHT (f);
1022 if (! FRAME_EXTERNAL_MENU_BAR (f))
1023 height += FRAME_MENU_BAR_HEIGHT (f);
1026 if (width > 0 && height > 0)
1028 block_input();
1029 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1030 (CAIRO_FORMAT_ARGB32, width, height);
1031 unblock_input();
1034 #endif /* USE_CAIRO */
1037 /* Start update of window W. */
1039 static void
1040 x_update_window_begin (struct window *w)
1042 struct frame *f = XFRAME (WINDOW_FRAME (w));
1043 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1045 w->output_cursor = w->cursor;
1047 block_input ();
1049 if (f == hlinfo->mouse_face_mouse_frame)
1051 /* Don't do highlighting for mouse motion during the update. */
1052 hlinfo->mouse_face_defer = true;
1054 /* If F needs to be redrawn, simply forget about any prior mouse
1055 highlighting. */
1056 if (FRAME_GARBAGED_P (f))
1057 hlinfo->mouse_face_window = Qnil;
1060 unblock_input ();
1064 /* Draw a vertical window border from (x,y0) to (x,y1) */
1066 static void
1067 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1069 struct frame *f = XFRAME (WINDOW_FRAME (w));
1070 struct face *face;
1072 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1073 if (face)
1074 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1075 face->foreground);
1077 #ifdef USE_CAIRO
1078 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1079 #else
1080 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
1081 f->output_data.x->normal_gc, x, y0, x, y1);
1082 #endif
1085 /* Draw a window divider from (x0,y0) to (x1,y1) */
1087 static void
1088 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1090 struct frame *f = XFRAME (WINDOW_FRAME (w));
1091 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1092 struct face *face_first
1093 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1094 struct face *face_last
1095 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1096 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1097 unsigned long color_first = (face_first
1098 ? face_first->foreground
1099 : FRAME_FOREGROUND_PIXEL (f));
1100 unsigned long color_last = (face_last
1101 ? face_last->foreground
1102 : FRAME_FOREGROUND_PIXEL (f));
1103 Display *display = FRAME_X_DISPLAY (f);
1105 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1106 /* Vertical. */
1108 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1109 x_fill_rectangle (f, f->output_data.x->normal_gc,
1110 x0, y0, 1, y1 - y0);
1111 XSetForeground (display, f->output_data.x->normal_gc, color);
1112 x_fill_rectangle (f, f->output_data.x->normal_gc,
1113 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1114 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1115 x_fill_rectangle (f, f->output_data.x->normal_gc,
1116 x1 - 1, y0, 1, y1 - y0);
1118 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1119 /* Horizontal. */
1121 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1122 x_fill_rectangle (f, f->output_data.x->normal_gc,
1123 x0, y0, x1 - x0, 1);
1124 XSetForeground (display, f->output_data.x->normal_gc, color);
1125 x_fill_rectangle (f, f->output_data.x->normal_gc,
1126 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1127 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1128 x_fill_rectangle (f, f->output_data.x->normal_gc,
1129 x0, y1 - 1, x1 - x0, 1);
1131 else
1133 XSetForeground (display, f->output_data.x->normal_gc, color);
1134 x_fill_rectangle (f, f->output_data.x->normal_gc,
1135 x0, y0, x1 - x0, y1 - y0);
1139 /* End update of window W.
1141 Draw vertical borders between horizontally adjacent windows, and
1142 display W's cursor if CURSOR_ON_P is non-zero.
1144 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1145 glyphs in mouse-face were overwritten. In that case we have to
1146 make sure that the mouse-highlight is properly redrawn.
1148 W may be a menu bar pseudo-window in case we don't have X toolkit
1149 support. Such windows don't have a cursor, so don't display it
1150 here. */
1152 static void
1153 x_update_window_end (struct window *w, bool cursor_on_p,
1154 bool mouse_face_overwritten_p)
1156 if (!w->pseudo_window_p)
1158 block_input ();
1160 if (cursor_on_p)
1161 display_and_set_cursor (w, true,
1162 w->output_cursor.hpos, w->output_cursor.vpos,
1163 w->output_cursor.x, w->output_cursor.y);
1165 if (draw_window_fringes (w, true))
1167 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1168 x_draw_right_divider (w);
1169 else
1170 x_draw_vertical_border (w);
1173 unblock_input ();
1176 /* If a row with mouse-face was overwritten, arrange for
1177 XTframe_up_to_date to redisplay the mouse highlight. */
1178 if (mouse_face_overwritten_p)
1180 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1182 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1183 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1184 hlinfo->mouse_face_window = Qnil;
1188 /* Show the frame back buffer. If frame is double-buffered,
1189 atomically publish to the user's screen graphics updates made since
1190 the last call to show_back_buffer. */
1191 static void
1192 show_back_buffer (struct frame *f)
1194 block_input ();
1195 if (FRAME_X_DOUBLE_BUFFERED_P (f))
1197 #ifdef HAVE_XDBE
1198 XdbeSwapInfo swap_info;
1199 memset (&swap_info, 0, sizeof (swap_info));
1200 swap_info.swap_window = FRAME_X_WINDOW (f);
1201 swap_info.swap_action = XdbeCopied;
1202 XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
1203 #else
1204 eassert (!"should have back-buffer only with XDBE");
1205 #endif
1207 FRAME_X_NEED_BUFFER_FLIP (f) = false;
1208 unblock_input ();
1211 /* Updates back buffer and flushes changes to display. Called from
1212 minibuf read code. Note that we display the back buffer even if
1213 buffer flipping is blocked. */
1214 static void
1215 x_flip_and_flush (struct frame *f)
1217 block_input ();
1218 if (FRAME_X_NEED_BUFFER_FLIP (f))
1219 show_back_buffer (f);
1220 x_flush (f);
1221 unblock_input ();
1224 /* End update of frame F. This function is installed as a hook in
1225 update_end. */
1227 static void
1228 x_update_end (struct frame *f)
1230 /* Mouse highlight may be displayed again. */
1231 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1233 #ifdef USE_CAIRO
1234 if (FRAME_CR_SURFACE (f))
1236 cairo_t *cr = 0;
1237 block_input();
1238 #if defined (USE_GTK) && defined (HAVE_GTK3)
1239 if (FRAME_GTK_WIDGET (f))
1241 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1242 cr = gdk_cairo_create (w);
1244 else
1245 #endif
1247 cairo_surface_t *surface;
1248 int width = FRAME_PIXEL_WIDTH (f);
1249 int height = FRAME_PIXEL_HEIGHT (f);
1250 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1251 height += FRAME_TOOL_BAR_HEIGHT (f);
1252 if (! FRAME_EXTERNAL_MENU_BAR (f))
1253 height += FRAME_MENU_BAR_HEIGHT (f);
1254 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1255 FRAME_X_DRAWABLE (f),
1256 FRAME_DISPLAY_INFO (f)->visual,
1257 width,
1258 height);
1259 cr = cairo_create (surface);
1260 cairo_surface_destroy (surface);
1263 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1264 cairo_paint (cr);
1265 cairo_destroy (cr);
1266 unblock_input ();
1268 #endif
1270 #ifndef XFlush
1271 block_input ();
1272 XFlush (FRAME_X_DISPLAY (f));
1273 unblock_input ();
1274 #endif
1277 /* This function is called from various places in xdisp.c
1278 whenever a complete update has been performed. */
1280 static void
1281 XTframe_up_to_date (struct frame *f)
1283 eassert (FRAME_X_P (f));
1284 block_input ();
1285 FRAME_MOUSE_UPDATE (f);
1286 if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
1287 show_back_buffer (f);
1288 unblock_input ();
1291 static void
1292 XTbuffer_flipping_unblocked_hook (struct frame *f)
1294 if (FRAME_X_NEED_BUFFER_FLIP (f))
1295 show_back_buffer (f);
1299 * x_clear_under_internal_border:
1301 * Clear area of frame F's internal border. If the internal border face
1302 * of F has been specified (is not null), fill the area with that face.
1304 void
1305 x_clear_under_internal_border (struct frame *f)
1307 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1309 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1310 int width = FRAME_PIXEL_WIDTH (f);
1311 int height = FRAME_PIXEL_HEIGHT (f);
1312 #ifdef USE_GTK
1313 int margin = 0;
1314 #else
1315 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1316 #endif
1317 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1319 block_input ();
1321 if (face)
1323 unsigned long color = face->background;
1324 Display *display = FRAME_X_DISPLAY (f);
1325 GC gc = f->output_data.x->normal_gc;
1327 XSetForeground (display, gc, color);
1328 x_fill_rectangle (f, gc, 0, margin, width, border);
1329 x_fill_rectangle (f, gc, 0, 0, border, height);
1330 x_fill_rectangle (f, gc, width - border, 0, border, height);
1331 x_fill_rectangle (f, gc, 0, height - border, width, border);
1332 XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
1334 else
1336 x_clear_area (f, 0, 0, border, height);
1337 x_clear_area (f, 0, margin, width, border);
1338 x_clear_area (f, width - border, 0, border, height);
1339 x_clear_area (f, 0, height - border, width, border);
1342 unblock_input ();
1346 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1347 arrow bitmaps, or clear the fringes if no bitmaps are required
1348 before DESIRED_ROW is made current. This function is called from
1349 update_window_line only if it is known that there are differences
1350 between bitmaps to be drawn between current row and DESIRED_ROW. */
1352 static void
1353 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1355 eassert (w);
1357 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1358 desired_row->redraw_fringe_bitmaps_p = true;
1360 #ifdef USE_X_TOOLKIT
1361 /* When a window has disappeared, make sure that no rest of
1362 full-width rows stays visible in the internal border. Could
1363 check here if updated window is the leftmost/rightmost window,
1364 but I guess it's not worth doing since vertically split windows
1365 are almost never used, internal border is rarely set, and the
1366 overhead is very small. */
1368 struct frame *f;
1369 int width, height;
1371 if (windows_or_buffers_changed
1372 && desired_row->full_width_p
1373 && (f = XFRAME (w->frame),
1374 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1375 width != 0)
1376 && (height = desired_row->visible_height,
1377 height > 0))
1379 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1380 struct face *face = FACE_FROM_ID_OR_NULL (f, INTERNAL_BORDER_FACE_ID);
1382 block_input ();
1383 if (face)
1385 unsigned long color = face->background;
1386 Display *display = FRAME_X_DISPLAY (f);
1388 XSetForeground (display, f->output_data.x->normal_gc, color);
1389 x_fill_rectangle (f, f->output_data.x->normal_gc,
1390 0, y, width, height);
1391 x_fill_rectangle (f, f->output_data.x->normal_gc,
1392 FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1394 else
1396 x_clear_area (f, 0, y, width, height);
1397 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1399 unblock_input ();
1402 #endif
1405 static void
1406 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1408 struct frame *f = XFRAME (WINDOW_FRAME (w));
1409 Display *display = FRAME_X_DISPLAY (f);
1410 GC gc = f->output_data.x->normal_gc;
1411 struct face *face = p->face;
1413 /* Must clip because of partially visible lines. */
1414 x_clip_to_row (w, row, ANY_AREA, gc);
1416 if (p->bx >= 0 && !p->overlay_p)
1418 /* In case the same realized face is used for fringes and
1419 for something displayed in the text (e.g. face `region' on
1420 mono-displays, the fill style may have been changed to
1421 FillSolid in x_draw_glyph_string_background. */
1422 if (face->stipple)
1423 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1424 else
1425 XSetForeground (display, face->gc, face->background);
1427 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1429 if (!face->stipple)
1430 XSetForeground (display, face->gc, face->foreground);
1433 #ifdef USE_CAIRO
1434 if (p->which && p->which < max_fringe_bmp)
1436 XGCValues gcv;
1438 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1439 XSetForeground (display, gc, (p->cursor_p
1440 ? (p->overlay_p ? face->background
1441 : f->output_data.x->cursor_pixel)
1442 : face->foreground));
1443 XSetBackground (display, gc, face->background);
1444 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1445 p->wd, p->h, p->x, p->y, p->overlay_p);
1446 XSetForeground (display, gc, gcv.foreground);
1447 XSetBackground (display, gc, gcv.background);
1449 #else /* not USE_CAIRO */
1450 if (p->which)
1452 Drawable drawable = FRAME_X_DRAWABLE (f);
1453 char *bits;
1454 Pixmap pixmap, clipmask = (Pixmap) 0;
1455 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1456 XGCValues gcv;
1458 if (p->wd > 8)
1459 bits = (char *) (p->bits + p->dh);
1460 else
1461 bits = (char *) p->bits + p->dh;
1463 /* Draw the bitmap. I believe these small pixmaps can be cached
1464 by the server. */
1465 pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
1466 (p->cursor_p
1467 ? (p->overlay_p ? face->background
1468 : f->output_data.x->cursor_pixel)
1469 : face->foreground),
1470 face->background, depth);
1472 if (p->overlay_p)
1474 clipmask = XCreatePixmapFromBitmapData (display,
1475 FRAME_DISPLAY_INFO (f)->root_window,
1476 bits, p->wd, p->h,
1477 1, 0, 1);
1478 gcv.clip_mask = clipmask;
1479 gcv.clip_x_origin = p->x;
1480 gcv.clip_y_origin = p->y;
1481 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1484 XCopyArea (display, pixmap, drawable, gc, 0, 0,
1485 p->wd, p->h, p->x, p->y);
1486 XFreePixmap (display, pixmap);
1488 if (p->overlay_p)
1490 gcv.clip_mask = (Pixmap) 0;
1491 XChangeGC (display, gc, GCClipMask, &gcv);
1492 XFreePixmap (display, clipmask);
1495 #endif /* not USE_CAIRO */
1497 x_reset_clip_rectangles (f, gc);
1500 /***********************************************************************
1501 Glyph display
1502 ***********************************************************************/
1506 static void x_set_glyph_string_clipping (struct glyph_string *);
1507 static void x_set_glyph_string_gc (struct glyph_string *);
1508 static void x_draw_glyph_string_foreground (struct glyph_string *);
1509 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1510 static void x_draw_glyph_string_box (struct glyph_string *);
1511 static void x_draw_glyph_string (struct glyph_string *);
1512 static _Noreturn void x_delete_glyphs (struct frame *, int);
1513 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1514 static void x_set_cursor_gc (struct glyph_string *);
1515 static void x_set_mode_line_face_gc (struct glyph_string *);
1516 static void x_set_mouse_face_gc (struct glyph_string *);
1517 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1518 unsigned long *, double, int);
1519 static void x_setup_relief_color (struct frame *, struct relief *,
1520 double, int, unsigned long);
1521 static void x_setup_relief_colors (struct glyph_string *);
1522 static void x_draw_image_glyph_string (struct glyph_string *);
1523 static void x_draw_image_relief (struct glyph_string *);
1524 static void x_draw_image_foreground (struct glyph_string *);
1525 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1526 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1527 int, int, int);
1528 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1529 int, bool, bool, bool, bool, bool,
1530 XRectangle *);
1531 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1532 int, bool, bool, XRectangle *);
1533 static void x_scroll_bar_clear (struct frame *);
1535 #ifdef GLYPH_DEBUG
1536 static void x_check_font (struct frame *, struct font *);
1537 #endif
1540 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1541 face. */
1543 static void
1544 x_set_cursor_gc (struct glyph_string *s)
1546 if (s->font == FRAME_FONT (s->f)
1547 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1548 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1549 && !s->cmp)
1550 s->gc = s->f->output_data.x->cursor_gc;
1551 else
1553 /* Cursor on non-default face: must merge. */
1554 XGCValues xgcv;
1555 unsigned long mask;
1557 xgcv.background = s->f->output_data.x->cursor_pixel;
1558 xgcv.foreground = s->face->background;
1560 /* If the glyph would be invisible, try a different foreground. */
1561 if (xgcv.foreground == xgcv.background)
1562 xgcv.foreground = s->face->foreground;
1563 if (xgcv.foreground == xgcv.background)
1564 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1565 if (xgcv.foreground == xgcv.background)
1566 xgcv.foreground = s->face->foreground;
1568 /* Make sure the cursor is distinct from text in this face. */
1569 if (xgcv.background == s->face->background
1570 && xgcv.foreground == s->face->foreground)
1572 xgcv.background = s->face->foreground;
1573 xgcv.foreground = s->face->background;
1576 IF_DEBUG (x_check_font (s->f, s->font));
1577 xgcv.graphics_exposures = False;
1578 mask = GCForeground | GCBackground | GCGraphicsExposures;
1580 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1581 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1582 mask, &xgcv);
1583 else
1584 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1585 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1587 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1592 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1594 static void
1595 x_set_mouse_face_gc (struct glyph_string *s)
1597 int face_id;
1598 struct face *face;
1600 /* What face has to be used last for the mouse face? */
1601 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1602 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1603 if (face == NULL)
1604 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1606 if (s->first_glyph->type == CHAR_GLYPH)
1607 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1608 else
1609 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1610 s->face = FACE_FROM_ID (s->f, face_id);
1611 prepare_face_for_display (s->f, s->face);
1613 if (s->font == s->face->font)
1614 s->gc = s->face->gc;
1615 else
1617 /* Otherwise construct scratch_cursor_gc with values from FACE
1618 except for FONT. */
1619 XGCValues xgcv;
1620 unsigned long mask;
1622 xgcv.background = s->face->background;
1623 xgcv.foreground = s->face->foreground;
1624 xgcv.graphics_exposures = False;
1625 mask = GCForeground | GCBackground | GCGraphicsExposures;
1627 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1628 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1629 mask, &xgcv);
1630 else
1631 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1632 = XCreateGC (s->display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
1634 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1637 eassert (s->gc != 0);
1641 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1642 Faces to use in the mode line have already been computed when the
1643 matrix was built, so there isn't much to do, here. */
1645 static void
1646 x_set_mode_line_face_gc (struct glyph_string *s)
1648 s->gc = s->face->gc;
1652 /* Set S->gc of glyph string S for drawing that glyph string. Set
1653 S->stippled_p to a non-zero value if the face of S has a stipple
1654 pattern. */
1656 static void
1657 x_set_glyph_string_gc (struct glyph_string *s)
1659 prepare_face_for_display (s->f, s->face);
1661 if (s->hl == DRAW_NORMAL_TEXT)
1663 s->gc = s->face->gc;
1664 s->stippled_p = s->face->stipple != 0;
1666 else if (s->hl == DRAW_INVERSE_VIDEO)
1668 x_set_mode_line_face_gc (s);
1669 s->stippled_p = s->face->stipple != 0;
1671 else if (s->hl == DRAW_CURSOR)
1673 x_set_cursor_gc (s);
1674 s->stippled_p = false;
1676 else if (s->hl == DRAW_MOUSE_FACE)
1678 x_set_mouse_face_gc (s);
1679 s->stippled_p = s->face->stipple != 0;
1681 else if (s->hl == DRAW_IMAGE_RAISED
1682 || s->hl == DRAW_IMAGE_SUNKEN)
1684 s->gc = s->face->gc;
1685 s->stippled_p = s->face->stipple != 0;
1687 else
1688 emacs_abort ();
1690 /* GC must have been set. */
1691 eassert (s->gc != 0);
1695 /* Set clipping for output of glyph string S. S may be part of a mode
1696 line or menu if we don't have X toolkit support. */
1698 static void
1699 x_set_glyph_string_clipping (struct glyph_string *s)
1701 XRectangle *r = s->clip;
1702 int n = get_glyph_string_clip_rects (s, r, 2);
1704 if (n > 0)
1705 x_set_clip_rectangles (s->f, s->gc, r, n);
1706 s->num_clips = n;
1710 /* Set SRC's clipping for output of glyph string DST. This is called
1711 when we are drawing DST's left_overhang or right_overhang only in
1712 the area of SRC. */
1714 static void
1715 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1717 XRectangle r;
1719 r.x = src->x;
1720 r.width = src->width;
1721 r.y = src->y;
1722 r.height = src->height;
1723 dst->clip[0] = r;
1724 dst->num_clips = 1;
1725 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1729 /* RIF:
1730 Compute left and right overhang of glyph string S. */
1732 static void
1733 x_compute_glyph_string_overhangs (struct glyph_string *s)
1735 if (s->cmp == NULL
1736 && (s->first_glyph->type == CHAR_GLYPH
1737 || s->first_glyph->type == COMPOSITE_GLYPH))
1739 struct font_metrics metrics;
1741 if (s->first_glyph->type == CHAR_GLYPH)
1743 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1744 struct font *font = s->font;
1745 int i;
1747 for (i = 0; i < s->nchars; i++)
1748 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1749 font->driver->text_extents (font, code, s->nchars, &metrics);
1751 else
1753 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1755 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1757 s->right_overhang = (metrics.rbearing > metrics.width
1758 ? metrics.rbearing - metrics.width : 0);
1759 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1761 else if (s->cmp)
1763 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1764 s->left_overhang = - s->cmp->lbearing;
1769 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1771 static void
1772 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1774 XGCValues xgcv;
1775 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1776 XSetForeground (s->display, s->gc, xgcv.background);
1777 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1778 XSetForeground (s->display, s->gc, xgcv.foreground);
1782 /* Draw the background of glyph_string S. If S->background_filled_p
1783 is non-zero don't draw it. FORCE_P non-zero means draw the
1784 background even if it wouldn't be drawn normally. This is used
1785 when a string preceding S draws into the background of S, or S
1786 contains the first component of a composition. */
1788 static void
1789 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1791 /* Nothing to do if background has already been drawn or if it
1792 shouldn't be drawn in the first place. */
1793 if (!s->background_filled_p)
1795 int box_line_width = max (s->face->box_line_width, 0);
1797 if (s->stippled_p)
1799 /* Fill background with a stipple pattern. */
1800 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1801 x_fill_rectangle (s->f, s->gc, s->x,
1802 s->y + box_line_width,
1803 s->background_width,
1804 s->height - 2 * box_line_width);
1805 XSetFillStyle (s->display, s->gc, FillSolid);
1806 s->background_filled_p = true;
1808 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1809 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1810 font dimensions, since the actual glyphs might be
1811 much smaller. So in that case we always clear the
1812 rectangle with background color. */
1813 || FONT_TOO_HIGH (s->font)
1814 || s->font_not_found_p
1815 || s->extends_to_end_of_line_p
1816 || force_p)
1818 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1819 s->background_width,
1820 s->height - 2 * box_line_width);
1821 s->background_filled_p = true;
1827 /* Draw the foreground of glyph string S. */
1829 static void
1830 x_draw_glyph_string_foreground (struct glyph_string *s)
1832 int i, x;
1834 /* If first glyph of S has a left box line, start drawing the text
1835 of S to the right of that box line. */
1836 if (s->face->box != FACE_NO_BOX
1837 && s->first_glyph->left_box_line_p)
1838 x = s->x + eabs (s->face->box_line_width);
1839 else
1840 x = s->x;
1842 /* Draw characters of S as rectangles if S's font could not be
1843 loaded. */
1844 if (s->font_not_found_p)
1846 for (i = 0; i < s->nchars; ++i)
1848 struct glyph *g = s->first_glyph + i;
1849 x_draw_rectangle (s->f,
1850 s->gc, x, s->y, g->pixel_width - 1,
1851 s->height - 1);
1852 x += g->pixel_width;
1855 else
1857 struct font *font = s->font;
1858 int boff = font->baseline_offset;
1859 int y;
1861 if (font->vertical_centering)
1862 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1864 y = s->ybase - boff;
1865 if (s->for_overlaps
1866 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1867 font->driver->draw (s, 0, s->nchars, x, y, false);
1868 else
1869 font->driver->draw (s, 0, s->nchars, x, y, true);
1870 if (s->face->overstrike)
1871 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1875 /* Draw the foreground of composite glyph string S. */
1877 static void
1878 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1880 int i, j, x;
1881 struct font *font = s->font;
1883 /* If first glyph of S has a left box line, start drawing the text
1884 of S to the right of that box line. */
1885 if (s->face && s->face->box != FACE_NO_BOX
1886 && s->first_glyph->left_box_line_p)
1887 x = s->x + eabs (s->face->box_line_width);
1888 else
1889 x = s->x;
1891 /* S is a glyph string for a composition. S->cmp_from is the index
1892 of the first character drawn for glyphs of this composition.
1893 S->cmp_from == 0 means we are drawing the very first character of
1894 this composition. */
1896 /* Draw a rectangle for the composition if the font for the very
1897 first character of the composition could not be loaded. */
1898 if (s->font_not_found_p)
1900 if (s->cmp_from == 0)
1901 x_draw_rectangle (s->f, s->gc, x, s->y,
1902 s->width - 1, s->height - 1);
1904 else if (! s->first_glyph->u.cmp.automatic)
1906 int y = s->ybase;
1908 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1909 /* TAB in a composition means display glyphs with padding
1910 space on the left or right. */
1911 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1913 int xx = x + s->cmp->offsets[j * 2];
1914 int yy = y - s->cmp->offsets[j * 2 + 1];
1916 font->driver->draw (s, j, j + 1, xx, yy, false);
1917 if (s->face->overstrike)
1918 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1921 else
1923 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1924 Lisp_Object glyph;
1925 int y = s->ybase;
1926 int width = 0;
1928 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1930 glyph = LGSTRING_GLYPH (gstring, i);
1931 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1932 width += LGLYPH_WIDTH (glyph);
1933 else
1935 int xoff, yoff, wadjust;
1937 if (j < i)
1939 font->driver->draw (s, j, i, x, y, false);
1940 if (s->face->overstrike)
1941 font->driver->draw (s, j, i, x + 1, y, false);
1942 x += width;
1944 xoff = LGLYPH_XOFF (glyph);
1945 yoff = LGLYPH_YOFF (glyph);
1946 wadjust = LGLYPH_WADJUST (glyph);
1947 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1948 if (s->face->overstrike)
1949 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1950 false);
1951 x += wadjust;
1952 j = i + 1;
1953 width = 0;
1956 if (j < i)
1958 font->driver->draw (s, j, i, x, y, false);
1959 if (s->face->overstrike)
1960 font->driver->draw (s, j, i, x + 1, y, false);
1966 /* Draw the foreground of glyph string S for glyphless characters. */
1968 static void
1969 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1971 struct glyph *glyph = s->first_glyph;
1972 XChar2b char2b[8];
1973 int x, i, j;
1975 /* If first glyph of S has a left box line, start drawing the text
1976 of S to the right of that box line. */
1977 if (s->face && s->face->box != FACE_NO_BOX
1978 && s->first_glyph->left_box_line_p)
1979 x = s->x + eabs (s->face->box_line_width);
1980 else
1981 x = s->x;
1983 s->char2b = char2b;
1985 for (i = 0; i < s->nchars; i++, glyph++)
1987 char buf[7], *str = NULL;
1988 int len = glyph->u.glyphless.len;
1990 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1992 if (len > 0
1993 && CHAR_TABLE_P (Vglyphless_char_display)
1994 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1995 >= 1))
1997 Lisp_Object acronym
1998 = (! glyph->u.glyphless.for_no_font
1999 ? CHAR_TABLE_REF (Vglyphless_char_display,
2000 glyph->u.glyphless.ch)
2001 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
2002 if (STRINGP (acronym))
2003 str = SSDATA (acronym);
2006 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
2008 unsigned int ch = glyph->u.glyphless.ch;
2009 eassume (ch <= MAX_CHAR);
2010 sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
2011 str = buf;
2014 if (str)
2016 int upper_len = (len + 1) / 2;
2017 unsigned code;
2019 /* It is assured that all LEN characters in STR is ASCII. */
2020 for (j = 0; j < len; j++)
2022 code = s->font->driver->encode_char (s->font, str[j]);
2023 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
2025 s->font->driver->draw (s, 0, upper_len,
2026 x + glyph->slice.glyphless.upper_xoff,
2027 s->ybase + glyph->slice.glyphless.upper_yoff,
2028 false);
2029 s->font->driver->draw (s, upper_len, len,
2030 x + glyph->slice.glyphless.lower_xoff,
2031 s->ybase + glyph->slice.glyphless.lower_yoff,
2032 false);
2034 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
2035 x_draw_rectangle (s->f, s->gc,
2036 x, s->ybase - glyph->ascent,
2037 glyph->pixel_width - 1,
2038 glyph->ascent + glyph->descent - 1);
2039 x += glyph->pixel_width;
2043 #ifdef USE_X_TOOLKIT
2045 #ifdef USE_LUCID
2047 /* Return the frame on which widget WIDGET is used.. Abort if frame
2048 cannot be determined. */
2050 static struct frame *
2051 x_frame_of_widget (Widget widget)
2053 struct x_display_info *dpyinfo;
2054 Lisp_Object tail, frame;
2055 struct frame *f;
2057 dpyinfo = x_display_info_for_display (XtDisplay (widget));
2059 /* Find the top-level shell of the widget. Note that this function
2060 can be called when the widget is not yet realized, so XtWindow
2061 (widget) == 0. That's the reason we can't simply use
2062 x_any_window_to_frame. */
2063 while (!XtIsTopLevelShell (widget))
2064 widget = XtParent (widget);
2066 /* Look for a frame with that top-level widget. Allocate the color
2067 on that frame to get the right gamma correction value. */
2068 FOR_EACH_FRAME (tail, frame)
2070 f = XFRAME (frame);
2071 if (FRAME_X_P (f)
2072 && f->output_data.nothing != 1
2073 && FRAME_DISPLAY_INFO (f) == dpyinfo
2074 && f->output_data.x->widget == widget)
2075 return f;
2077 emacs_abort ();
2080 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2081 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2082 If this produces the same color as PIXEL, try a color where all RGB
2083 values have DELTA added. Return the allocated color in *PIXEL.
2084 DISPLAY is the X display, CMAP is the colormap to operate on.
2085 Value is true if successful. */
2087 bool
2088 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2089 unsigned long *pixel, double factor, int delta)
2091 struct frame *f = x_frame_of_widget (widget);
2092 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2095 #endif /* USE_LUCID */
2098 /* Structure specifying which arguments should be passed by Xt to
2099 cvt_string_to_pixel. We want the widget's screen and colormap. */
2101 static XtConvertArgRec cvt_string_to_pixel_args[] =
2103 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2104 sizeof (Screen *)},
2105 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2106 sizeof (Colormap)}
2110 /* The address of this variable is returned by
2111 cvt_string_to_pixel. */
2113 static Pixel cvt_string_to_pixel_value;
2116 /* Convert a color name to a pixel color.
2118 DPY is the display we are working on.
2120 ARGS is an array of *NARGS XrmValue structures holding additional
2121 information about the widget for which the conversion takes place.
2122 The contents of this array are determined by the specification
2123 in cvt_string_to_pixel_args.
2125 FROM is a pointer to an XrmValue which points to the color name to
2126 convert. TO is an XrmValue in which to return the pixel color.
2128 CLOSURE_RET is a pointer to user-data, in which we record if
2129 we allocated the color or not.
2131 Value is True if successful, False otherwise. */
2133 static Boolean
2134 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2135 XrmValue *from, XrmValue *to,
2136 XtPointer *closure_ret)
2138 Screen *screen;
2139 Colormap cmap;
2140 Pixel pixel;
2141 String color_name;
2142 XColor color;
2144 if (*nargs != 2)
2146 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2147 "wrongParameters", "cvt_string_to_pixel",
2148 "XtToolkitError",
2149 "Screen and colormap args required", NULL, NULL);
2150 return False;
2153 screen = *(Screen **) args[0].addr;
2154 cmap = *(Colormap *) args[1].addr;
2155 color_name = (String) from->addr;
2157 if (strcmp (color_name, XtDefaultBackground) == 0)
2159 *closure_ret = (XtPointer) False;
2160 pixel = WhitePixelOfScreen (screen);
2162 else if (strcmp (color_name, XtDefaultForeground) == 0)
2164 *closure_ret = (XtPointer) False;
2165 pixel = BlackPixelOfScreen (screen);
2167 else if (XParseColor (dpy, cmap, color_name, &color)
2168 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2170 pixel = color.pixel;
2171 *closure_ret = (XtPointer) True;
2173 else
2175 String params[1];
2176 Cardinal nparams = 1;
2178 params[0] = color_name;
2179 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2180 "badValue", "cvt_string_to_pixel",
2181 "XtToolkitError", "Invalid color '%s'",
2182 params, &nparams);
2183 return False;
2186 if (to->addr != NULL)
2188 if (to->size < sizeof (Pixel))
2190 to->size = sizeof (Pixel);
2191 return False;
2194 *(Pixel *) to->addr = pixel;
2196 else
2198 cvt_string_to_pixel_value = pixel;
2199 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2202 to->size = sizeof (Pixel);
2203 return True;
2207 /* Free a pixel color which was previously allocated via
2208 cvt_string_to_pixel. This is registered as the destructor
2209 for this type of resource via XtSetTypeConverter.
2211 APP is the application context in which we work.
2213 TO is a pointer to an XrmValue holding the color to free.
2214 CLOSURE is the value we stored in CLOSURE_RET for this color
2215 in cvt_string_to_pixel.
2217 ARGS and NARGS are like for cvt_string_to_pixel. */
2219 static void
2220 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2221 Cardinal *nargs)
2223 if (*nargs != 2)
2225 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2226 "XtToolkitError",
2227 "Screen and colormap arguments required",
2228 NULL, NULL);
2230 else if (closure != NULL)
2232 /* We did allocate the pixel, so free it. */
2233 Screen *screen = *(Screen **) args[0].addr;
2234 Colormap cmap = *(Colormap *) args[1].addr;
2235 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2236 (Pixel *) to->addr, 1);
2241 #endif /* USE_X_TOOLKIT */
2244 /* Value is an array of XColor structures for the contents of the
2245 color map of display DPY. Set *NCELLS to the size of the array.
2246 Note that this probably shouldn't be called for large color maps,
2247 say a 24-bit TrueColor map. */
2249 static const XColor *
2250 x_color_cells (Display *dpy, int *ncells)
2252 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2253 eassume (dpyinfo);
2255 if (dpyinfo->color_cells == NULL)
2257 Screen *screen = dpyinfo->screen;
2258 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2259 int i;
2261 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2262 sizeof *dpyinfo->color_cells);
2263 dpyinfo->ncolor_cells = ncolor_cells;
2265 for (i = 0; i < ncolor_cells; ++i)
2266 dpyinfo->color_cells[i].pixel = i;
2268 XQueryColors (dpy, dpyinfo->cmap,
2269 dpyinfo->color_cells, ncolor_cells);
2272 *ncells = dpyinfo->ncolor_cells;
2273 return dpyinfo->color_cells;
2277 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2278 colors in COLORS. Use cached information, if available. */
2280 void
2281 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2283 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2285 if (dpyinfo->red_bits > 0)
2287 /* For TrueColor displays, we can decompose the RGB value
2288 directly. */
2289 int i;
2290 unsigned int rmult, gmult, bmult;
2291 unsigned int rmask, gmask, bmask;
2293 rmask = (1 << dpyinfo->red_bits) - 1;
2294 gmask = (1 << dpyinfo->green_bits) - 1;
2295 bmask = (1 << dpyinfo->blue_bits) - 1;
2296 /* If we're widening, for example, 8 bits in the pixel value to
2297 16 bits for the separate-color representation, we want to
2298 extrapolate the lower bits based on those bits available --
2299 in other words, we'd like 0xff to become 0xffff instead of
2300 the 0xff00 we'd get by just zero-filling the lower bits.
2302 We generate a 32-bit scaled-up value and shift it, in case
2303 the bit count doesn't divide 16 evenly (e.g., when dealing
2304 with a 3-3-2 bit RGB display), to get more of the lower bits
2305 correct.
2307 Should we cache the multipliers in dpyinfo? Maybe
2308 special-case the 8-8-8 common case? */
2309 rmult = 0xffffffff / rmask;
2310 gmult = 0xffffffff / gmask;
2311 bmult = 0xffffffff / bmask;
2313 for (i = 0; i < ncolors; ++i)
2315 unsigned int r, g, b;
2316 unsigned long pixel = colors[i].pixel;
2318 r = (pixel >> dpyinfo->red_offset) & rmask;
2319 g = (pixel >> dpyinfo->green_offset) & gmask;
2320 b = (pixel >> dpyinfo->blue_offset) & bmask;
2322 colors[i].red = (r * rmult) >> 16;
2323 colors[i].green = (g * gmult) >> 16;
2324 colors[i].blue = (b * bmult) >> 16;
2326 return;
2329 if (dpyinfo->color_cells)
2331 int i;
2332 for (i = 0; i < ncolors; ++i)
2334 unsigned long pixel = colors[i].pixel;
2335 eassert (pixel < dpyinfo->ncolor_cells);
2336 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2337 colors[i] = dpyinfo->color_cells[pixel];
2339 return;
2342 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2346 /* On frame F, translate pixel color to RGB values for the color in
2347 COLOR. Use cached information, if available. */
2349 void
2350 x_query_color (struct frame *f, XColor *color)
2352 x_query_colors (f, color, 1);
2356 /* On frame F, translate the color name to RGB values. Use cached
2357 information, if possible.
2359 Note that there is currently no way to clean old entries out of the
2360 cache. However, it is limited to names in the server's database,
2361 and names we've actually looked up; list-colors-display is probably
2362 the most color-intensive case we're likely to hit. */
2364 Status x_parse_color (struct frame *f, const char *color_name,
2365 XColor *color)
2367 Display *dpy = FRAME_X_DISPLAY (f);
2368 Colormap cmap = FRAME_X_COLORMAP (f);
2369 struct color_name_cache_entry *cache_entry;
2371 if (color_name[0] == '#')
2373 /* The hex form is parsed directly by XParseColor without
2374 talking to the X server. No need for caching. */
2375 return XParseColor (dpy, cmap, color_name, color);
2378 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2379 cache_entry = cache_entry->next)
2381 if (!xstrcasecmp(cache_entry->name, color_name))
2383 *color = cache_entry->rgb;
2384 return 1;
2388 if (XParseColor (dpy, cmap, color_name, color) == 0)
2389 /* No caching of negative results, currently. */
2390 return 0;
2392 cache_entry = xzalloc (sizeof *cache_entry);
2393 cache_entry->rgb = *color;
2394 cache_entry->name = xstrdup (color_name);
2395 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2396 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2397 return 1;
2401 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2402 exact match can't be allocated, try the nearest color available.
2403 Value is true if successful. Set *COLOR to the color
2404 allocated. */
2406 static bool
2407 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2409 bool rc;
2411 rc = XAllocColor (dpy, cmap, color) != 0;
2412 if (rc == 0)
2414 /* If we got to this point, the colormap is full, so we're going
2415 to try to get the next closest color. The algorithm used is
2416 a least-squares matching, which is what X uses for closest
2417 color matching with StaticColor visuals. */
2418 int nearest, i;
2419 int max_color_delta = 255;
2420 int max_delta = 3 * max_color_delta;
2421 int nearest_delta = max_delta + 1;
2422 int ncells;
2423 const XColor *cells = x_color_cells (dpy, &ncells);
2425 for (nearest = i = 0; i < ncells; ++i)
2427 int dred = (color->red >> 8) - (cells[i].red >> 8);
2428 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2429 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2430 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2432 if (delta < nearest_delta)
2434 nearest = i;
2435 nearest_delta = delta;
2439 color->red = cells[nearest].red;
2440 color->green = cells[nearest].green;
2441 color->blue = cells[nearest].blue;
2442 rc = XAllocColor (dpy, cmap, color) != 0;
2444 else
2446 /* If allocation succeeded, and the allocated pixel color is not
2447 equal to a cached pixel color recorded earlier, there was a
2448 change in the colormap, so clear the color cache. */
2449 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2450 eassume (dpyinfo);
2452 if (dpyinfo->color_cells)
2454 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2455 if (cached_color->red != color->red
2456 || cached_color->blue != color->blue
2457 || cached_color->green != color->green)
2459 xfree (dpyinfo->color_cells);
2460 dpyinfo->color_cells = NULL;
2461 dpyinfo->ncolor_cells = 0;
2466 #ifdef DEBUG_X_COLORS
2467 if (rc)
2468 register_color (color->pixel);
2469 #endif /* DEBUG_X_COLORS */
2471 return rc;
2475 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2476 gamma correction. If an exact match can't be allocated, try the
2477 nearest color available. Value is true if successful. Set *COLOR
2478 to the color allocated. */
2480 bool
2481 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2483 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2485 gamma_correct (f, color);
2487 if (dpyinfo->red_bits > 0)
2489 color->pixel = x_make_truecolor_pixel (dpyinfo,
2490 color->red,
2491 color->green,
2492 color->blue);
2493 return true;
2496 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2500 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2501 It's necessary to do this instead of just using PIXEL directly to
2502 get color reference counts right. */
2504 unsigned long
2505 x_copy_color (struct frame *f, unsigned long pixel)
2507 XColor color;
2509 /* If display has an immutable color map, freeing colors is not
2510 necessary and some servers don't allow it. Since we won't free a
2511 color once we've allocated it, we don't need to re-allocate it to
2512 maintain the server's reference count. */
2513 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2514 return pixel;
2516 color.pixel = pixel;
2517 block_input ();
2518 /* The color could still be found in the color_cells array. */
2519 x_query_color (f, &color);
2520 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2521 unblock_input ();
2522 #ifdef DEBUG_X_COLORS
2523 register_color (pixel);
2524 #endif
2525 return color.pixel;
2529 /* Brightness beyond which a color won't have its highlight brightness
2530 boosted.
2532 Nominally, highlight colors for `3d' faces are calculated by
2533 brightening an object's color by a constant scale factor, but this
2534 doesn't yield good results for dark colors, so for colors who's
2535 brightness is less than this value (on a scale of 0-65535) have an
2536 use an additional additive factor.
2538 The value here is set so that the default menu-bar/mode-line color
2539 (grey75) will not have its highlights changed at all. */
2540 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2543 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2544 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2545 If this produces the same color as PIXEL, try a color where all RGB
2546 values have DELTA added. Return the allocated color in *PIXEL.
2547 DISPLAY is the X display, CMAP is the colormap to operate on.
2548 Value is non-zero if successful. */
2550 static bool
2551 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2552 unsigned long *pixel, double factor, int delta)
2554 XColor color, new;
2555 long bright;
2556 bool success_p;
2558 /* Get RGB color values. */
2559 color.pixel = *pixel;
2560 x_query_color (f, &color);
2562 /* Change RGB values by specified FACTOR. Avoid overflow! */
2563 eassert (factor >= 0);
2564 new.red = min (0xffff, factor * color.red);
2565 new.green = min (0xffff, factor * color.green);
2566 new.blue = min (0xffff, factor * color.blue);
2568 /* Calculate brightness of COLOR. */
2569 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2571 /* We only boost colors that are darker than
2572 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2573 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2574 /* Make an additive adjustment to NEW, because it's dark enough so
2575 that scaling by FACTOR alone isn't enough. */
2577 /* How far below the limit this color is (0 - 1, 1 being darker). */
2578 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2579 /* The additive adjustment. */
2580 int min_delta = delta * dimness * factor / 2;
2582 if (factor < 1)
2584 new.red = max (0, new.red - min_delta);
2585 new.green = max (0, new.green - min_delta);
2586 new.blue = max (0, new.blue - min_delta);
2588 else
2590 new.red = min (0xffff, min_delta + new.red);
2591 new.green = min (0xffff, min_delta + new.green);
2592 new.blue = min (0xffff, min_delta + new.blue);
2596 /* Try to allocate the color. */
2597 success_p = x_alloc_nearest_color (f, cmap, &new);
2598 if (success_p)
2600 if (new.pixel == *pixel)
2602 /* If we end up with the same color as before, try adding
2603 delta to the RGB values. */
2604 x_free_colors (f, &new.pixel, 1);
2606 new.red = min (0xffff, delta + color.red);
2607 new.green = min (0xffff, delta + color.green);
2608 new.blue = min (0xffff, delta + color.blue);
2609 success_p = x_alloc_nearest_color (f, cmap, &new);
2611 else
2612 success_p = true;
2613 *pixel = new.pixel;
2616 return success_p;
2620 /* Set up the foreground color for drawing relief lines of glyph
2621 string S. RELIEF is a pointer to a struct relief containing the GC
2622 with which lines will be drawn. Use a color that is FACTOR or
2623 DELTA lighter or darker than the relief's background which is found
2624 in S->f->output_data.x->relief_background. If such a color cannot
2625 be allocated, use DEFAULT_PIXEL, instead. */
2627 static void
2628 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2629 int delta, unsigned long default_pixel)
2631 XGCValues xgcv;
2632 struct x_output *di = f->output_data.x;
2633 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2634 unsigned long pixel;
2635 unsigned long background = di->relief_background;
2636 Colormap cmap = FRAME_X_COLORMAP (f);
2637 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2638 Display *dpy = FRAME_X_DISPLAY (f);
2640 xgcv.graphics_exposures = False;
2641 xgcv.line_width = 1;
2643 /* Free previously allocated color. The color cell will be reused
2644 when it has been freed as many times as it was allocated, so this
2645 doesn't affect faces using the same colors. */
2646 if (relief->gc && relief->pixel != -1)
2648 x_free_colors (f, &relief->pixel, 1);
2649 relief->pixel = -1;
2652 /* Allocate new color. */
2653 xgcv.foreground = default_pixel;
2654 pixel = background;
2655 if (dpyinfo->n_planes != 1
2656 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2657 xgcv.foreground = relief->pixel = pixel;
2659 if (relief->gc == 0)
2661 xgcv.stipple = dpyinfo->gray;
2662 mask |= GCStipple;
2663 relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
2665 else
2666 XChangeGC (dpy, relief->gc, mask, &xgcv);
2670 /* Set up colors for the relief lines around glyph string S. */
2672 static void
2673 x_setup_relief_colors (struct glyph_string *s)
2675 struct x_output *di = s->f->output_data.x;
2676 unsigned long color;
2678 if (s->face->use_box_color_for_shadows_p)
2679 color = s->face->box_color;
2680 else if (s->first_glyph->type == IMAGE_GLYPH
2681 && s->img->pixmap
2682 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2683 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2684 else
2686 XGCValues xgcv;
2688 /* Get the background color of the face. */
2689 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2690 color = xgcv.background;
2693 if (di->white_relief.gc == 0
2694 || color != di->relief_background)
2696 di->relief_background = color;
2697 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2698 WHITE_PIX_DEFAULT (s->f));
2699 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2700 BLACK_PIX_DEFAULT (s->f));
2705 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2706 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2707 to draw, it must be >= 0. RAISED_P means draw a raised
2708 relief. LEFT_P means draw a relief on the left side of
2709 the rectangle. RIGHT_P means draw a relief on the right
2710 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2711 when drawing. */
2713 static void
2714 x_draw_relief_rect (struct frame *f,
2715 int left_x, int top_y, int right_x, int bottom_y,
2716 int width, bool raised_p, bool top_p, bool bot_p,
2717 bool left_p, bool right_p,
2718 XRectangle *clip_rect)
2720 #ifdef USE_CAIRO
2721 GC top_left_gc, bottom_right_gc;
2722 int corners = 0;
2724 if (raised_p)
2726 top_left_gc = f->output_data.x->white_relief.gc;
2727 bottom_right_gc = f->output_data.x->black_relief.gc;
2729 else
2731 top_left_gc = f->output_data.x->black_relief.gc;
2732 bottom_right_gc = f->output_data.x->white_relief.gc;
2735 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2736 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2738 if (left_p)
2740 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2741 width, bottom_y + 1 - top_y);
2742 if (top_p)
2743 corners |= 1 << CORNER_TOP_LEFT;
2744 if (bot_p)
2745 corners |= 1 << CORNER_BOTTOM_LEFT;
2747 if (right_p)
2749 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2750 width, bottom_y + 1 - top_y);
2751 if (top_p)
2752 corners |= 1 << CORNER_TOP_RIGHT;
2753 if (bot_p)
2754 corners |= 1 << CORNER_BOTTOM_RIGHT;
2756 if (top_p)
2758 if (!right_p)
2759 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2760 right_x + 1 - left_x, width);
2761 else
2762 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2763 right_x + 1 - left_x, width, 1);
2765 if (bot_p)
2767 if (!left_p)
2768 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2769 right_x + 1 - left_x, width);
2770 else
2771 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2772 left_x, bottom_y + 1 - width,
2773 right_x + 1 - left_x, width, 0);
2775 if (left_p && width != 1)
2776 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2777 1, bottom_y + 1 - top_y);
2778 if (top_p && width != 1)
2779 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2780 right_x + 1 - left_x, 1);
2781 if (corners)
2783 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2784 FRAME_BACKGROUND_PIXEL (f));
2785 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2786 right_x - left_x + 1, bottom_y - top_y + 1,
2787 6, 1, corners);
2790 x_reset_clip_rectangles (f, top_left_gc);
2791 x_reset_clip_rectangles (f, bottom_right_gc);
2792 #else
2793 Display *dpy = FRAME_X_DISPLAY (f);
2794 Drawable drawable = FRAME_X_DRAWABLE (f);
2795 int i;
2796 GC gc;
2798 if (raised_p)
2799 gc = f->output_data.x->white_relief.gc;
2800 else
2801 gc = f->output_data.x->black_relief.gc;
2802 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2804 /* This code is more complicated than it has to be, because of two
2805 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2806 the outermost line using the black relief. (ii) Omit the four
2807 corner pixels. */
2809 /* Top. */
2810 if (top_p)
2812 if (width == 1)
2813 XDrawLine (dpy, drawable, gc,
2814 left_x + left_p, top_y,
2815 right_x + !right_p, top_y);
2817 for (i = 1; i < width; ++i)
2818 XDrawLine (dpy, drawable, gc,
2819 left_x + i * left_p, top_y + i,
2820 right_x + 1 - i * right_p, top_y + i);
2823 /* Left. */
2824 if (left_p)
2826 if (width == 1)
2827 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2829 x_clear_area(f, left_x, top_y, 1, 1);
2830 x_clear_area(f, left_x, bottom_y, 1, 1);
2832 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2833 XDrawLine (dpy, drawable, gc,
2834 left_x + i, top_y + (i + 1) * top_p,
2835 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2838 XSetClipMask (dpy, gc, None);
2839 if (raised_p)
2840 gc = f->output_data.x->black_relief.gc;
2841 else
2842 gc = f->output_data.x->white_relief.gc;
2843 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2845 if (width > 1)
2847 /* Outermost top line. */
2848 if (top_p)
2849 XDrawLine (dpy, drawable, gc,
2850 left_x + left_p, top_y,
2851 right_x + !right_p, top_y);
2853 /* Outermost left line. */
2854 if (left_p)
2855 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2858 /* Bottom. */
2859 if (bot_p)
2861 XDrawLine (dpy, drawable, gc,
2862 left_x + left_p, bottom_y,
2863 right_x + !right_p, bottom_y);
2864 for (i = 1; i < width; ++i)
2865 XDrawLine (dpy, drawable, gc,
2866 left_x + i * left_p, bottom_y - i,
2867 right_x + 1 - i * right_p, bottom_y - i);
2870 /* Right. */
2871 if (right_p)
2873 x_clear_area(f, right_x, top_y, 1, 1);
2874 x_clear_area(f, right_x, bottom_y, 1, 1);
2875 for (i = 0; i < width; ++i)
2876 XDrawLine (dpy, drawable, gc,
2877 right_x - i, top_y + (i + 1) * top_p,
2878 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2881 x_reset_clip_rectangles (f, gc);
2883 #endif
2887 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2888 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2889 draw, it must be >= 0. LEFT_P means draw a line on the
2890 left side of the rectangle. RIGHT_P means draw a line
2891 on the right side of the rectangle. CLIP_RECT is the clipping
2892 rectangle to use when drawing. */
2894 static void
2895 x_draw_box_rect (struct glyph_string *s,
2896 int left_x, int top_y, int right_x, int bottom_y, int width,
2897 bool left_p, bool right_p, XRectangle *clip_rect)
2899 XGCValues xgcv;
2901 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2902 XSetForeground (s->display, s->gc, s->face->box_color);
2903 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2905 /* Top. */
2906 x_fill_rectangle (s->f, s->gc,
2907 left_x, top_y, right_x - left_x + 1, width);
2909 /* Left. */
2910 if (left_p)
2911 x_fill_rectangle (s->f, s->gc,
2912 left_x, top_y, width, bottom_y - top_y + 1);
2914 /* Bottom. */
2915 x_fill_rectangle (s->f, s->gc,
2916 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2918 /* Right. */
2919 if (right_p)
2920 x_fill_rectangle (s->f, s->gc,
2921 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2923 XSetForeground (s->display, s->gc, xgcv.foreground);
2924 x_reset_clip_rectangles (s->f, s->gc);
2928 /* Draw a box around glyph string S. */
2930 static void
2931 x_draw_glyph_string_box (struct glyph_string *s)
2933 int width, left_x, right_x, top_y, bottom_y, last_x;
2934 bool raised_p, left_p, right_p;
2935 struct glyph *last_glyph;
2936 XRectangle clip_rect;
2938 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2939 ? WINDOW_RIGHT_EDGE_X (s->w)
2940 : window_box_right (s->w, s->area));
2942 /* The glyph that may have a right box line. */
2943 last_glyph = (s->cmp || s->img
2944 ? s->first_glyph
2945 : s->first_glyph + s->nchars - 1);
2947 width = eabs (s->face->box_line_width);
2948 raised_p = s->face->box == FACE_RAISED_BOX;
2949 left_x = s->x;
2950 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2951 ? last_x - 1
2952 : min (last_x, s->x + s->background_width) - 1);
2953 top_y = s->y;
2954 bottom_y = top_y + s->height - 1;
2956 left_p = (s->first_glyph->left_box_line_p
2957 || (s->hl == DRAW_MOUSE_FACE
2958 && (s->prev == NULL
2959 || s->prev->hl != s->hl)));
2960 right_p = (last_glyph->right_box_line_p
2961 || (s->hl == DRAW_MOUSE_FACE
2962 && (s->next == NULL
2963 || s->next->hl != s->hl)));
2965 get_glyph_string_clip_rect (s, &clip_rect);
2967 if (s->face->box == FACE_SIMPLE_BOX)
2968 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2969 left_p, right_p, &clip_rect);
2970 else
2972 x_setup_relief_colors (s);
2973 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2974 width, raised_p, true, true, left_p, right_p,
2975 &clip_rect);
2980 /* Draw foreground of image glyph string S. */
2982 static void
2983 x_draw_image_foreground (struct glyph_string *s)
2985 int x = s->x;
2986 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2988 /* If first glyph of S has a left box line, start drawing it to the
2989 right of that line. */
2990 if (s->face->box != FACE_NO_BOX
2991 && s->first_glyph->left_box_line_p
2992 && s->slice.x == 0)
2993 x += eabs (s->face->box_line_width);
2995 /* If there is a margin around the image, adjust x- and y-position
2996 by that margin. */
2997 if (s->slice.x == 0)
2998 x += s->img->hmargin;
2999 if (s->slice.y == 0)
3000 y += s->img->vmargin;
3002 if (s->img->pixmap)
3004 if (s->img->mask)
3006 /* We can't set both a clip mask and use XSetClipRectangles
3007 because the latter also sets a clip mask. We also can't
3008 trust on the shape extension to be available
3009 (XShapeCombineRegion). So, compute the rectangle to draw
3010 manually. */
3011 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3012 | GCFunction);
3013 XGCValues xgcv;
3014 XRectangle clip_rect, image_rect, r;
3016 xgcv.clip_mask = s->img->mask;
3017 xgcv.clip_x_origin = x;
3018 xgcv.clip_y_origin = y;
3019 xgcv.function = GXcopy;
3020 XChangeGC (s->display, s->gc, mask, &xgcv);
3022 get_glyph_string_clip_rect (s, &clip_rect);
3023 image_rect.x = x;
3024 image_rect.y = y;
3025 image_rect.width = s->slice.width;
3026 image_rect.height = s->slice.height;
3027 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3028 XCopyArea (s->display, s->img->pixmap,
3029 FRAME_X_DRAWABLE (s->f), s->gc,
3030 s->slice.x + r.x - x, s->slice.y + r.y - y,
3031 r.width, r.height, r.x, r.y);
3033 else
3035 XRectangle clip_rect, image_rect, r;
3037 get_glyph_string_clip_rect (s, &clip_rect);
3038 image_rect.x = x;
3039 image_rect.y = y;
3040 image_rect.width = s->slice.width;
3041 image_rect.height = s->slice.height;
3042 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
3043 XCopyArea (s->display, s->img->pixmap,
3044 FRAME_X_DRAWABLE (s->f), s->gc,
3045 s->slice.x + r.x - x, s->slice.y + r.y - y,
3046 r.width, r.height, r.x, r.y);
3048 /* When the image has a mask, we can expect that at
3049 least part of a mouse highlight or a block cursor will
3050 be visible. If the image doesn't have a mask, make
3051 a block cursor visible by drawing a rectangle around
3052 the image. I believe it's looking better if we do
3053 nothing here for mouse-face. */
3054 if (s->hl == DRAW_CURSOR)
3056 int relief = eabs (s->img->relief);
3057 x_draw_rectangle (s->f, s->gc,
3058 x - relief, y - relief,
3059 s->slice.width + relief*2 - 1,
3060 s->slice.height + relief*2 - 1);
3064 else
3065 /* Draw a rectangle if image could not be loaded. */
3066 x_draw_rectangle (s->f, s->gc, x, y,
3067 s->slice.width - 1, s->slice.height - 1);
3071 /* Draw a relief around the image glyph string S. */
3073 static void
3074 x_draw_image_relief (struct glyph_string *s)
3076 int x1, y1, thick;
3077 bool raised_p, top_p, bot_p, left_p, right_p;
3078 int extra_x, extra_y;
3079 XRectangle r;
3080 int x = s->x;
3081 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3083 /* If first glyph of S has a left box line, start drawing it to the
3084 right of that line. */
3085 if (s->face->box != FACE_NO_BOX
3086 && s->first_glyph->left_box_line_p
3087 && s->slice.x == 0)
3088 x += eabs (s->face->box_line_width);
3090 /* If there is a margin around the image, adjust x- and y-position
3091 by that margin. */
3092 if (s->slice.x == 0)
3093 x += s->img->hmargin;
3094 if (s->slice.y == 0)
3095 y += s->img->vmargin;
3097 if (s->hl == DRAW_IMAGE_SUNKEN
3098 || s->hl == DRAW_IMAGE_RAISED)
3100 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3101 raised_p = s->hl == DRAW_IMAGE_RAISED;
3103 else
3105 thick = eabs (s->img->relief);
3106 raised_p = s->img->relief > 0;
3109 x1 = x + s->slice.width - 1;
3110 y1 = y + s->slice.height - 1;
3112 extra_x = extra_y = 0;
3113 if (s->face->id == TOOL_BAR_FACE_ID)
3115 if (CONSP (Vtool_bar_button_margin)
3116 && INTEGERP (XCAR (Vtool_bar_button_margin))
3117 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3119 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3120 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3122 else if (INTEGERP (Vtool_bar_button_margin))
3123 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3126 top_p = bot_p = left_p = right_p = false;
3128 if (s->slice.x == 0)
3129 x -= thick + extra_x, left_p = true;
3130 if (s->slice.y == 0)
3131 y -= thick + extra_y, top_p = true;
3132 if (s->slice.x + s->slice.width == s->img->width)
3133 x1 += thick + extra_x, right_p = true;
3134 if (s->slice.y + s->slice.height == s->img->height)
3135 y1 += thick + extra_y, bot_p = true;
3137 x_setup_relief_colors (s);
3138 get_glyph_string_clip_rect (s, &r);
3139 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3140 top_p, bot_p, left_p, right_p, &r);
3144 /* Draw the foreground of image glyph string S to PIXMAP. */
3146 static void
3147 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3149 int x = 0;
3150 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3152 /* If first glyph of S has a left box line, start drawing it to the
3153 right of that line. */
3154 if (s->face->box != FACE_NO_BOX
3155 && s->first_glyph->left_box_line_p
3156 && s->slice.x == 0)
3157 x += eabs (s->face->box_line_width);
3159 /* If there is a margin around the image, adjust x- and y-position
3160 by that margin. */
3161 if (s->slice.x == 0)
3162 x += s->img->hmargin;
3163 if (s->slice.y == 0)
3164 y += s->img->vmargin;
3166 if (s->img->pixmap)
3168 if (s->img->mask)
3170 /* We can't set both a clip mask and use XSetClipRectangles
3171 because the latter also sets a clip mask. We also can't
3172 trust on the shape extension to be available
3173 (XShapeCombineRegion). So, compute the rectangle to draw
3174 manually. */
3175 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3176 | GCFunction);
3177 XGCValues xgcv;
3179 xgcv.clip_mask = s->img->mask;
3180 xgcv.clip_x_origin = x - s->slice.x;
3181 xgcv.clip_y_origin = y - s->slice.y;
3182 xgcv.function = GXcopy;
3183 XChangeGC (s->display, s->gc, mask, &xgcv);
3185 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3186 s->slice.x, s->slice.y,
3187 s->slice.width, s->slice.height, x, y);
3188 XSetClipMask (s->display, s->gc, None);
3190 else
3192 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3193 s->slice.x, s->slice.y,
3194 s->slice.width, s->slice.height, x, y);
3196 /* When the image has a mask, we can expect that at
3197 least part of a mouse highlight or a block cursor will
3198 be visible. If the image doesn't have a mask, make
3199 a block cursor visible by drawing a rectangle around
3200 the image. I believe it's looking better if we do
3201 nothing here for mouse-face. */
3202 if (s->hl == DRAW_CURSOR)
3204 int r = eabs (s->img->relief);
3205 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3206 s->slice.width + r*2 - 1,
3207 s->slice.height + r*2 - 1);
3211 else
3212 /* Draw a rectangle if image could not be loaded. */
3213 x_draw_rectangle (s->f, s->gc, x, y,
3214 s->slice.width - 1, s->slice.height - 1);
3218 /* Draw part of the background of glyph string S. X, Y, W, and H
3219 give the rectangle to draw. */
3221 static void
3222 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3224 if (s->stippled_p)
3226 /* Fill background with a stipple pattern. */
3227 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3228 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3229 XSetFillStyle (s->display, s->gc, FillSolid);
3231 else
3232 x_clear_glyph_string_rect (s, x, y, w, h);
3236 /* Draw image glyph string S.
3238 s->y
3239 s->x +-------------------------
3240 | s->face->box
3242 | +-------------------------
3243 | | s->img->margin
3245 | | +-------------------
3246 | | | the image
3250 static void
3251 x_draw_image_glyph_string (struct glyph_string *s)
3253 int box_line_hwidth = eabs (s->face->box_line_width);
3254 int box_line_vwidth = max (s->face->box_line_width, 0);
3255 int height;
3256 Pixmap pixmap = None;
3258 height = s->height;
3259 if (s->slice.y == 0)
3260 height -= box_line_vwidth;
3261 if (s->slice.y + s->slice.height >= s->img->height)
3262 height -= box_line_vwidth;
3264 /* Fill background with face under the image. Do it only if row is
3265 taller than image or if image has a clip mask to reduce
3266 flickering. */
3267 s->stippled_p = s->face->stipple != 0;
3268 if (height > s->slice.height
3269 || s->img->hmargin
3270 || s->img->vmargin
3271 || s->img->mask
3272 || s->img->pixmap == 0
3273 || s->width != s->background_width)
3275 if (s->img->mask)
3277 /* Create a pixmap as large as the glyph string. Fill it
3278 with the background color. Copy the image to it, using
3279 its mask. Copy the temporary pixmap to the display. */
3280 Screen *screen = FRAME_X_SCREEN (s->f);
3281 int depth = DefaultDepthOfScreen (screen);
3283 /* Create a pixmap as large as the glyph string. */
3284 pixmap = XCreatePixmap (s->display, FRAME_X_DRAWABLE (s->f),
3285 s->background_width,
3286 s->height, depth);
3288 /* Don't clip in the following because we're working on the
3289 pixmap. */
3290 XSetClipMask (s->display, s->gc, None);
3292 /* Fill the pixmap with the background color/stipple. */
3293 if (s->stippled_p)
3295 /* Fill background with a stipple pattern. */
3296 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3297 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3298 XFillRectangle (s->display, pixmap, s->gc,
3299 0, 0, s->background_width, s->height);
3300 XSetFillStyle (s->display, s->gc, FillSolid);
3301 XSetTSOrigin (s->display, s->gc, 0, 0);
3303 else
3305 XGCValues xgcv;
3306 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3307 &xgcv);
3308 XSetForeground (s->display, s->gc, xgcv.background);
3309 XFillRectangle (s->display, pixmap, s->gc,
3310 0, 0, s->background_width, s->height);
3311 XSetForeground (s->display, s->gc, xgcv.foreground);
3314 else
3316 int x = s->x;
3317 int y = s->y;
3318 int width = s->background_width;
3320 if (s->first_glyph->left_box_line_p
3321 && s->slice.x == 0)
3323 x += box_line_hwidth;
3324 width -= box_line_hwidth;
3327 if (s->slice.y == 0)
3328 y += box_line_vwidth;
3330 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3333 s->background_filled_p = true;
3336 /* Draw the foreground. */
3337 #ifdef USE_CAIRO
3338 if (s->img->cr_data)
3340 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3342 int x = s->x + s->img->hmargin;
3343 int y = s->y + s->img->vmargin;
3344 int width = s->background_width;
3346 cairo_set_source_surface (cr, s->img->cr_data,
3347 x - s->slice.x,
3348 y - s->slice.y);
3349 cairo_rectangle (cr, x, y, width, height);
3350 cairo_fill (cr);
3351 x_end_cr_clip (s->f);
3353 else
3354 #endif
3355 if (pixmap != None)
3357 x_draw_image_foreground_1 (s, pixmap);
3358 x_set_glyph_string_clipping (s);
3359 XCopyArea (s->display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
3360 0, 0, s->background_width, s->height, s->x, s->y);
3361 XFreePixmap (s->display, pixmap);
3363 else
3364 x_draw_image_foreground (s);
3366 /* If we must draw a relief around the image, do it. */
3367 if (s->img->relief
3368 || s->hl == DRAW_IMAGE_RAISED
3369 || s->hl == DRAW_IMAGE_SUNKEN)
3370 x_draw_image_relief (s);
3374 /* Draw stretch glyph string S. */
3376 static void
3377 x_draw_stretch_glyph_string (struct glyph_string *s)
3379 eassert (s->first_glyph->type == STRETCH_GLYPH);
3381 if (s->hl == DRAW_CURSOR
3382 && !x_stretch_cursor_p)
3384 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3385 wide as the stretch glyph. */
3386 int width, background_width = s->background_width;
3387 int x = s->x;
3389 if (!s->row->reversed_p)
3391 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3393 if (x < left_x)
3395 background_width -= left_x - x;
3396 x = left_x;
3399 else
3401 /* In R2L rows, draw the cursor on the right edge of the
3402 stretch glyph. */
3403 int right_x = window_box_right (s->w, TEXT_AREA);
3405 if (x + background_width > right_x)
3406 background_width -= x - right_x;
3407 x += background_width;
3409 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3410 if (s->row->reversed_p)
3411 x -= width;
3413 /* Draw cursor. */
3414 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3416 /* Clear rest using the GC of the original non-cursor face. */
3417 if (width < background_width)
3419 int y = s->y;
3420 int w = background_width - width, h = s->height;
3421 XRectangle r;
3422 GC gc;
3424 if (!s->row->reversed_p)
3425 x += width;
3426 else
3427 x = s->x;
3428 if (s->row->mouse_face_p
3429 && cursor_in_mouse_face_p (s->w))
3431 x_set_mouse_face_gc (s);
3432 gc = s->gc;
3434 else
3435 gc = s->face->gc;
3437 get_glyph_string_clip_rect (s, &r);
3438 x_set_clip_rectangles (s->f, gc, &r, 1);
3440 if (s->face->stipple)
3442 /* Fill background with a stipple pattern. */
3443 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3444 x_fill_rectangle (s->f, gc, x, y, w, h);
3445 XSetFillStyle (s->display, gc, FillSolid);
3447 else
3449 XGCValues xgcv;
3450 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3451 XSetForeground (s->display, gc, xgcv.background);
3452 x_fill_rectangle (s->f, gc, x, y, w, h);
3453 XSetForeground (s->display, gc, xgcv.foreground);
3456 x_reset_clip_rectangles (s->f, gc);
3459 else if (!s->background_filled_p)
3461 int background_width = s->background_width;
3462 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3464 /* Don't draw into left margin, fringe or scrollbar area
3465 except for header line and mode line. */
3466 if (x < left_x && !s->row->mode_line_p)
3468 background_width -= left_x - x;
3469 x = left_x;
3471 if (background_width > 0)
3472 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3475 s->background_filled_p = true;
3479 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3481 x0 wave_length = 2
3483 y0 * * * * *
3484 |* * * * * * * * *
3485 wave_height = 3 | * * * *
3489 static void
3490 x_draw_underwave (struct glyph_string *s)
3492 int wave_height = 3, wave_length = 2;
3493 #ifdef USE_CAIRO
3494 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3495 s->width, wave_height, wave_length);
3496 #else /* not USE_CAIRO */
3497 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3498 bool odd;
3499 XRectangle wave_clip, string_clip, final_clip;
3501 dx = wave_length;
3502 dy = wave_height - 1;
3503 x0 = s->x;
3504 y0 = s->ybase - wave_height + 3;
3505 width = s->width;
3506 xmax = x0 + width;
3508 /* Find and set clipping rectangle */
3510 wave_clip.x = x0;
3511 wave_clip.y = y0;
3512 wave_clip.width = width;
3513 wave_clip.height = wave_height;
3514 get_glyph_string_clip_rect (s, &string_clip);
3516 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3517 return;
3519 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3521 /* Draw the waves */
3523 x1 = x0 - (x0 % dx);
3524 x2 = x1 + dx;
3525 odd = (x1 / dx) & 1;
3526 y1 = y2 = y0;
3528 if (odd)
3529 y1 += dy;
3530 else
3531 y2 += dy;
3533 if (INT_MAX - dx < xmax)
3534 emacs_abort ();
3536 while (x1 <= xmax)
3538 XDrawLine (s->display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
3539 x1 = x2, y1 = y2;
3540 x2 += dx, y2 = y0 + odd*dy;
3541 odd = !odd;
3544 /* Restore previous clipping rectangle(s) */
3545 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3546 #endif /* not USE_CAIRO */
3550 /* Draw glyph string S. */
3552 static void
3553 x_draw_glyph_string (struct glyph_string *s)
3555 bool relief_drawn_p = false;
3557 /* If S draws into the background of its successors, draw the
3558 background of the successors first so that S can draw into it.
3559 This makes S->next use XDrawString instead of XDrawImageString. */
3560 if (s->next && s->right_overhang && !s->for_overlaps)
3562 int width;
3563 struct glyph_string *next;
3565 for (width = 0, next = s->next;
3566 next && width < s->right_overhang;
3567 width += next->width, next = next->next)
3568 if (next->first_glyph->type != IMAGE_GLYPH)
3570 x_set_glyph_string_gc (next);
3571 x_set_glyph_string_clipping (next);
3572 if (next->first_glyph->type == STRETCH_GLYPH)
3573 x_draw_stretch_glyph_string (next);
3574 else
3575 x_draw_glyph_string_background (next, true);
3576 next->num_clips = 0;
3580 /* Set up S->gc, set clipping and draw S. */
3581 x_set_glyph_string_gc (s);
3583 /* Draw relief (if any) in advance for char/composition so that the
3584 glyph string can be drawn over it. */
3585 if (!s->for_overlaps
3586 && s->face->box != FACE_NO_BOX
3587 && (s->first_glyph->type == CHAR_GLYPH
3588 || s->first_glyph->type == COMPOSITE_GLYPH))
3591 x_set_glyph_string_clipping (s);
3592 x_draw_glyph_string_background (s, true);
3593 x_draw_glyph_string_box (s);
3594 x_set_glyph_string_clipping (s);
3595 relief_drawn_p = true;
3597 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3598 && !s->clip_tail
3599 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3600 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3601 /* We must clip just this glyph. left_overhang part has already
3602 drawn when s->prev was drawn, and right_overhang part will be
3603 drawn later when s->next is drawn. */
3604 x_set_glyph_string_clipping_exactly (s, s);
3605 else
3606 x_set_glyph_string_clipping (s);
3608 switch (s->first_glyph->type)
3610 case IMAGE_GLYPH:
3611 x_draw_image_glyph_string (s);
3612 break;
3614 case XWIDGET_GLYPH:
3615 x_draw_xwidget_glyph_string (s);
3616 break;
3618 case STRETCH_GLYPH:
3619 x_draw_stretch_glyph_string (s);
3620 break;
3622 case CHAR_GLYPH:
3623 if (s->for_overlaps)
3624 s->background_filled_p = true;
3625 else
3626 x_draw_glyph_string_background (s, false);
3627 x_draw_glyph_string_foreground (s);
3628 break;
3630 case COMPOSITE_GLYPH:
3631 if (s->for_overlaps || (s->cmp_from > 0
3632 && ! s->first_glyph->u.cmp.automatic))
3633 s->background_filled_p = true;
3634 else
3635 x_draw_glyph_string_background (s, true);
3636 x_draw_composite_glyph_string_foreground (s);
3637 break;
3639 case GLYPHLESS_GLYPH:
3640 if (s->for_overlaps)
3641 s->background_filled_p = true;
3642 else
3643 x_draw_glyph_string_background (s, true);
3644 x_draw_glyphless_glyph_string_foreground (s);
3645 break;
3647 default:
3648 emacs_abort ();
3651 if (!s->for_overlaps)
3653 /* Draw underline. */
3654 if (s->face->underline_p)
3656 if (s->face->underline_type == FACE_UNDER_WAVE)
3658 if (s->face->underline_defaulted_p)
3659 x_draw_underwave (s);
3660 else
3662 XGCValues xgcv;
3663 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3664 XSetForeground (s->display, s->gc, s->face->underline_color);
3665 x_draw_underwave (s);
3666 XSetForeground (s->display, s->gc, xgcv.foreground);
3669 else if (s->face->underline_type == FACE_UNDER_LINE)
3671 unsigned long thickness, position;
3672 int y;
3674 if (s->prev && s->prev->face->underline_p
3675 && s->prev->face->underline_type == FACE_UNDER_LINE)
3677 /* We use the same underline style as the previous one. */
3678 thickness = s->prev->underline_thickness;
3679 position = s->prev->underline_position;
3681 else
3683 struct font *font = font_for_underline_metrics (s);
3685 /* Get the underline thickness. Default is 1 pixel. */
3686 if (font && font->underline_thickness > 0)
3687 thickness = font->underline_thickness;
3688 else
3689 thickness = 1;
3690 if (x_underline_at_descent_line)
3691 position = (s->height - thickness) - (s->ybase - s->y);
3692 else
3694 /* Get the underline position. This is the recommended
3695 vertical offset in pixels from the baseline to the top of
3696 the underline. This is a signed value according to the
3697 specs, and its default is
3699 ROUND ((maximum descent) / 2), with
3700 ROUND(x) = floor (x + 0.5) */
3702 if (x_use_underline_position_properties
3703 && font && font->underline_position >= 0)
3704 position = font->underline_position;
3705 else if (font)
3706 position = (font->descent + 1) / 2;
3707 else
3708 position = underline_minimum_offset;
3710 position = max (position, underline_minimum_offset);
3712 /* Check the sanity of thickness and position. We should
3713 avoid drawing underline out of the current line area. */
3714 if (s->y + s->height <= s->ybase + position)
3715 position = (s->height - 1) - (s->ybase - s->y);
3716 if (s->y + s->height < s->ybase + position + thickness)
3717 thickness = (s->y + s->height) - (s->ybase + position);
3718 s->underline_thickness = thickness;
3719 s->underline_position = position;
3720 y = s->ybase + position;
3721 if (s->face->underline_defaulted_p)
3722 x_fill_rectangle (s->f, s->gc,
3723 s->x, y, s->width, thickness);
3724 else
3726 XGCValues xgcv;
3727 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3728 XSetForeground (s->display, s->gc, s->face->underline_color);
3729 x_fill_rectangle (s->f, s->gc,
3730 s->x, y, s->width, thickness);
3731 XSetForeground (s->display, s->gc, xgcv.foreground);
3735 /* Draw overline. */
3736 if (s->face->overline_p)
3738 unsigned long dy = 0, h = 1;
3740 if (s->face->overline_color_defaulted_p)
3741 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3742 s->width, h);
3743 else
3745 XGCValues xgcv;
3746 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3747 XSetForeground (s->display, s->gc, s->face->overline_color);
3748 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3749 s->width, h);
3750 XSetForeground (s->display, s->gc, xgcv.foreground);
3754 /* Draw strike-through. */
3755 if (s->face->strike_through_p)
3757 /* Y-coordinate and height of the glyph string's first
3758 glyph. We cannot use s->y and s->height because those
3759 could be larger if there are taller display elements
3760 (e.g., characters displayed with a larger font) in the
3761 same glyph row. */
3762 int glyph_y = s->ybase - s->first_glyph->ascent;
3763 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
3764 /* Strike-through width and offset from the glyph string's
3765 top edge. */
3766 unsigned long h = 1;
3767 unsigned long dy = (glyph_height - h) / 2;
3769 if (s->face->strike_through_color_defaulted_p)
3770 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3771 s->width, h);
3772 else
3774 XGCValues xgcv;
3775 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3776 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3777 x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
3778 s->width, h);
3779 XSetForeground (s->display, s->gc, xgcv.foreground);
3783 /* Draw relief if not yet drawn. */
3784 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3785 x_draw_glyph_string_box (s);
3787 if (s->prev)
3789 struct glyph_string *prev;
3791 for (prev = s->prev; prev; prev = prev->prev)
3792 if (prev->hl != s->hl
3793 && prev->x + prev->width + prev->right_overhang > s->x)
3795 /* As prev was drawn while clipped to its own area, we
3796 must draw the right_overhang part using s->hl now. */
3797 enum draw_glyphs_face save = prev->hl;
3799 prev->hl = s->hl;
3800 x_set_glyph_string_gc (prev);
3801 x_set_glyph_string_clipping_exactly (s, prev);
3802 if (prev->first_glyph->type == CHAR_GLYPH)
3803 x_draw_glyph_string_foreground (prev);
3804 else
3805 x_draw_composite_glyph_string_foreground (prev);
3806 x_reset_clip_rectangles (prev->f, prev->gc);
3807 prev->hl = save;
3808 prev->num_clips = 0;
3812 if (s->next)
3814 struct glyph_string *next;
3816 for (next = s->next; next; next = next->next)
3817 if (next->hl != s->hl
3818 && next->x - next->left_overhang < s->x + s->width)
3820 /* As next will be drawn while clipped to its own area,
3821 we must draw the left_overhang part using s->hl now. */
3822 enum draw_glyphs_face save = next->hl;
3824 next->hl = s->hl;
3825 x_set_glyph_string_gc (next);
3826 x_set_glyph_string_clipping_exactly (s, next);
3827 if (next->first_glyph->type == CHAR_GLYPH)
3828 x_draw_glyph_string_foreground (next);
3829 else
3830 x_draw_composite_glyph_string_foreground (next);
3831 x_reset_clip_rectangles (next->f, next->gc);
3832 next->hl = save;
3833 next->num_clips = 0;
3834 next->clip_head = s->next;
3839 /* Reset clipping. */
3840 x_reset_clip_rectangles (s->f, s->gc);
3841 s->num_clips = 0;
3844 /* Shift display to make room for inserted glyphs. */
3846 static void
3847 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3849 /* Never called on a GUI frame, see
3850 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3852 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
3853 f->output_data.x->normal_gc,
3854 x, y, width, height,
3855 x + shift_by, y);
3858 /* Delete N glyphs at the nominal cursor position. Not implemented
3859 for X frames. */
3861 static void
3862 x_delete_glyphs (struct frame *f, register int n)
3864 emacs_abort ();
3868 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3869 If they are <= 0, this is probably an error. */
3871 static ATTRIBUTE_UNUSED void
3872 x_clear_area1 (Display *dpy, Window window,
3873 int x, int y, int width, int height, int exposures)
3875 eassert (width > 0 && height > 0);
3876 XClearArea (dpy, window, x, y, width, height, exposures);
3879 void
3880 x_clear_area (struct frame *f, int x, int y, int width, int height)
3882 #ifdef USE_CAIRO
3883 cairo_t *cr;
3885 eassert (width > 0 && height > 0);
3887 cr = x_begin_cr_clip (f, NULL);
3888 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3889 cairo_rectangle (cr, x, y, width, height);
3890 cairo_fill (cr);
3891 x_end_cr_clip (f);
3892 #else
3893 if (FRAME_X_DOUBLE_BUFFERED_P (f))
3894 XFillRectangle (FRAME_X_DISPLAY (f),
3895 FRAME_X_DRAWABLE (f),
3896 f->output_data.x->reverse_gc,
3897 x, y, width, height);
3898 else
3899 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3900 x, y, width, height, False);
3901 #endif
3905 /* Clear an entire frame. */
3907 static void
3908 x_clear_frame (struct frame *f)
3910 /* Clearing the frame will erase any cursor, so mark them all as no
3911 longer visible. */
3912 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3914 block_input ();
3916 font_drop_xrender_surfaces (f);
3917 x_clear_window (f);
3919 /* We have to clear the scroll bars. If we have changed colors or
3920 something like that, then they should be notified. */
3921 x_scroll_bar_clear (f);
3923 XFlush (FRAME_X_DISPLAY (f));
3925 unblock_input ();
3928 /* RIF: Show hourglass cursor on frame F. */
3930 static void
3931 x_show_hourglass (struct frame *f)
3933 Display *dpy = FRAME_X_DISPLAY (f);
3935 if (dpy)
3937 struct x_output *x = FRAME_X_OUTPUT (f);
3938 #ifdef USE_X_TOOLKIT
3939 if (x->widget)
3940 #else
3941 if (FRAME_OUTER_WINDOW (f))
3942 #endif
3944 x->hourglass_p = true;
3946 if (!x->hourglass_window)
3948 unsigned long mask = CWCursor;
3949 XSetWindowAttributes attrs;
3950 #ifdef USE_GTK
3951 Window parent = FRAME_X_WINDOW (f);
3952 #else
3953 Window parent = FRAME_OUTER_WINDOW (f);
3954 #endif
3955 attrs.cursor = x->hourglass_cursor;
3957 x->hourglass_window = XCreateWindow
3958 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3959 InputOnly, CopyFromParent, mask, &attrs);
3962 XMapRaised (dpy, x->hourglass_window);
3963 XFlush (dpy);
3968 /* RIF: Cancel hourglass cursor on frame F. */
3970 static void
3971 x_hide_hourglass (struct frame *f)
3973 struct x_output *x = FRAME_X_OUTPUT (f);
3975 /* Watch out for newly created frames. */
3976 if (x->hourglass_window)
3978 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3979 /* Sync here because XTread_socket looks at the
3980 hourglass_p flag that is reset to zero below. */
3981 XSync (FRAME_X_DISPLAY (f), False);
3982 x->hourglass_p = false;
3986 /* Invert the middle quarter of the frame for .15 sec. */
3988 static void
3989 XTflash (struct frame *f)
3991 block_input ();
3994 #ifdef USE_GTK
3995 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3996 when the scroll bars and the edit widget share the same X window. */
3997 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3998 #ifdef HAVE_GTK3
3999 cairo_t *cr = gdk_cairo_create (window);
4000 cairo_set_source_rgb (cr, 1, 1, 1);
4001 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
4002 #define XFillRectangle(d, win, gc, x, y, w, h) \
4003 do { \
4004 cairo_rectangle (cr, x, y, w, h); \
4005 cairo_fill (cr); \
4007 while (false)
4008 #else /* ! HAVE_GTK3 */
4009 GdkGCValues vals;
4010 GdkGC *gc;
4011 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
4012 ^ FRAME_BACKGROUND_PIXEL (f));
4013 vals.function = GDK_XOR;
4014 gc = gdk_gc_new_with_values (window,
4015 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
4016 #define XFillRectangle(d, win, gc, x, y, w, h) \
4017 gdk_draw_rectangle (window, gc, true, x, y, w, h)
4018 #endif /* ! HAVE_GTK3 */
4019 #else /* ! USE_GTK */
4020 GC gc;
4022 /* Create a GC that will use the GXxor function to flip foreground
4023 pixels into background pixels. */
4025 XGCValues values;
4027 values.function = GXxor;
4028 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
4029 ^ FRAME_BACKGROUND_PIXEL (f));
4031 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4032 GCFunction | GCForeground, &values);
4034 #endif
4036 /* Get the height not including a menu bar widget. */
4037 int height = FRAME_PIXEL_HEIGHT (f);
4038 /* Height of each line to flash. */
4039 int flash_height = FRAME_LINE_HEIGHT (f);
4040 /* These will be the left and right margins of the rectangles. */
4041 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
4042 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
4043 int width = flash_right - flash_left;
4045 /* If window is tall, flash top and bottom line. */
4046 if (height > 3 * FRAME_LINE_HEIGHT (f))
4048 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4049 flash_left,
4050 (FRAME_INTERNAL_BORDER_WIDTH (f)
4051 + FRAME_TOP_MARGIN_HEIGHT (f)),
4052 width, flash_height);
4053 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4054 flash_left,
4055 (height - flash_height
4056 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4057 width, flash_height);
4060 else
4061 /* If it is short, flash it all. */
4062 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4063 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4064 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4066 x_flush (f);
4069 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
4070 struct timespec wakeup = timespec_add (current_timespec (), delay);
4072 /* Keep waiting until past the time wakeup or any input gets
4073 available. */
4074 while (! detect_input_pending ())
4076 struct timespec current = current_timespec ();
4077 struct timespec timeout;
4079 /* Break if result would not be positive. */
4080 if (timespec_cmp (wakeup, current) <= 0)
4081 break;
4083 /* How long `select' should wait. */
4084 timeout = make_timespec (0, 10 * 1000 * 1000);
4086 /* Try to wait that long--but we might wake up sooner. */
4087 pselect (0, NULL, NULL, NULL, &timeout, NULL);
4091 /* If window is tall, flash top and bottom line. */
4092 if (height > 3 * FRAME_LINE_HEIGHT (f))
4094 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4095 flash_left,
4096 (FRAME_INTERNAL_BORDER_WIDTH (f)
4097 + FRAME_TOP_MARGIN_HEIGHT (f)),
4098 width, flash_height);
4099 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4100 flash_left,
4101 (height - flash_height
4102 - FRAME_INTERNAL_BORDER_WIDTH (f)),
4103 width, flash_height);
4105 else
4106 /* If it is short, flash it all. */
4107 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4108 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4109 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4111 #ifdef USE_GTK
4112 #ifdef HAVE_GTK3
4113 cairo_destroy (cr);
4114 #else
4115 g_object_unref (G_OBJECT (gc));
4116 #endif
4117 #undef XFillRectangle
4118 #else
4119 XFreeGC (FRAME_X_DISPLAY (f), gc);
4120 #endif
4121 x_flush (f);
4125 unblock_input ();
4129 static void
4130 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4132 block_input ();
4133 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4134 unblock_input ();
4138 /* Make audible bell. */
4140 static void
4141 XTring_bell (struct frame *f)
4143 if (FRAME_X_DISPLAY (f))
4145 if (visible_bell)
4146 XTflash (f);
4147 else
4149 block_input ();
4150 #ifdef HAVE_XKB
4151 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4152 #else
4153 XBell (FRAME_X_DISPLAY (f), 0);
4154 #endif
4155 XFlush (FRAME_X_DISPLAY (f));
4156 unblock_input ();
4161 /***********************************************************************
4162 Line Dance
4163 ***********************************************************************/
4165 /* Perform an insert-lines or delete-lines operation, inserting N
4166 lines or deleting -N lines at vertical position VPOS. */
4168 static void
4169 x_ins_del_lines (struct frame *f, int vpos, int n)
4171 emacs_abort ();
4175 /* Scroll part of the display as described by RUN. */
4177 static void
4178 x_scroll_run (struct window *w, struct run *run)
4180 struct frame *f = XFRAME (w->frame);
4181 int x, y, width, height, from_y, to_y, bottom_y;
4183 /* Get frame-relative bounding box of the text display area of W,
4184 without mode lines. Include in this box the left and right
4185 fringe of W. */
4186 window_box (w, ANY_AREA, &x, &y, &width, &height);
4188 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4189 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4190 bottom_y = y + height;
4192 if (to_y < from_y)
4194 /* Scrolling up. Make sure we don't copy part of the mode
4195 line at the bottom. */
4196 if (from_y + run->height > bottom_y)
4197 height = bottom_y - from_y;
4198 else
4199 height = run->height;
4201 else
4203 /* Scrolling down. Make sure we don't copy over the mode line.
4204 at the bottom. */
4205 if (to_y + run->height > bottom_y)
4206 height = bottom_y - to_y;
4207 else
4208 height = run->height;
4211 block_input ();
4213 /* Cursor off. Will be switched on again in x_update_window_end. */
4214 x_clear_cursor (w);
4216 #ifdef USE_CAIRO
4217 SET_FRAME_GARBAGED (f);
4218 #else
4219 XCopyArea (FRAME_X_DISPLAY (f),
4220 FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
4221 f->output_data.x->normal_gc,
4222 x, from_y,
4223 width, height,
4224 x, to_y);
4225 #endif
4227 unblock_input ();
4232 /***********************************************************************
4233 Exposure Events
4234 ***********************************************************************/
4237 static void
4238 frame_highlight (struct frame *f)
4240 /* We used to only do this if Vx_no_window_manager was non-nil, but
4241 the ICCCM (section 4.1.6) says that the window's border pixmap
4242 and border pixel are window attributes which are "private to the
4243 client", so we can always change it to whatever we want. */
4244 block_input ();
4245 /* I recently started to get errors in this XSetWindowBorder, depending on
4246 the window-manager in use, tho something more is at play since I've been
4247 using that same window-manager binary for ever. Let's not crash just
4248 because of this (bug#9310). */
4249 x_catch_errors (FRAME_X_DISPLAY (f));
4250 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4251 f->output_data.x->border_pixel);
4252 x_uncatch_errors ();
4253 unblock_input ();
4254 x_update_cursor (f, true);
4255 x_set_frame_alpha (f);
4258 static void
4259 frame_unhighlight (struct frame *f)
4261 /* We used to only do this if Vx_no_window_manager was non-nil, but
4262 the ICCCM (section 4.1.6) says that the window's border pixmap
4263 and border pixel are window attributes which are "private to the
4264 client", so we can always change it to whatever we want. */
4265 block_input ();
4266 /* Same as above for XSetWindowBorder (bug#9310). */
4267 x_catch_errors (FRAME_X_DISPLAY (f));
4268 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4269 f->output_data.x->border_tile);
4270 x_uncatch_errors ();
4271 unblock_input ();
4272 x_update_cursor (f, true);
4273 x_set_frame_alpha (f);
4276 /* The focus has changed. Update the frames as necessary to reflect
4277 the new situation. Note that we can't change the selected frame
4278 here, because the Lisp code we are interrupting might become confused.
4279 Each event gets marked with the frame in which it occurred, so the
4280 Lisp code can tell when the switch took place by examining the events. */
4282 static void
4283 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4285 struct frame *old_focus = dpyinfo->x_focus_frame;
4287 if (frame != dpyinfo->x_focus_frame)
4289 /* Set this before calling other routines, so that they see
4290 the correct value of x_focus_frame. */
4291 dpyinfo->x_focus_frame = frame;
4293 if (old_focus && old_focus->auto_lower)
4294 x_lower_frame (old_focus);
4296 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4297 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4298 else
4299 dpyinfo->x_pending_autoraise_frame = NULL;
4302 x_frame_rehighlight (dpyinfo);
4305 /* Handle FocusIn and FocusOut state changes for FRAME.
4306 If FRAME has focus and there exists more than one frame, puts
4307 a FOCUS_IN_EVENT into *BUFP. */
4309 static void
4310 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4312 if (type == FocusIn)
4314 if (dpyinfo->x_focus_event_frame != frame)
4316 x_new_focus_frame (dpyinfo, frame);
4317 dpyinfo->x_focus_event_frame = frame;
4319 /* Don't stop displaying the initial startup message
4320 for a switch-frame event we don't need. */
4321 /* When run as a daemon, Vterminal_frame is always NIL. */
4322 bufp->arg = (((NILP (Vterminal_frame)
4323 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4324 || EQ (Fdaemonp (), Qt))
4325 && CONSP (Vframe_list)
4326 && !NILP (XCDR (Vframe_list)))
4327 ? Qt : Qnil);
4328 bufp->kind = FOCUS_IN_EVENT;
4329 XSETFRAME (bufp->frame_or_window, frame);
4332 frame->output_data.x->focus_state |= state;
4334 #ifdef HAVE_X_I18N
4335 if (FRAME_XIC (frame))
4336 XSetICFocus (FRAME_XIC (frame));
4337 #endif
4339 else if (type == FocusOut)
4341 frame->output_data.x->focus_state &= ~state;
4343 if (dpyinfo->x_focus_event_frame == frame)
4345 dpyinfo->x_focus_event_frame = 0;
4346 x_new_focus_frame (dpyinfo, 0);
4348 bufp->kind = FOCUS_OUT_EVENT;
4349 XSETFRAME (bufp->frame_or_window, frame);
4352 #ifdef HAVE_X_I18N
4353 if (FRAME_XIC (frame))
4354 XUnsetICFocus (FRAME_XIC (frame));
4355 #endif
4356 if (frame->pointer_invisible)
4357 XTtoggle_invisible_pointer (frame, false);
4361 /* Return the Emacs frame-object corresponding to an X window.
4362 It could be the frame's main window or an icon window. */
4364 static struct frame *
4365 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4367 Lisp_Object tail, frame;
4368 struct frame *f;
4370 if (wdesc == None)
4371 return NULL;
4373 FOR_EACH_FRAME (tail, frame)
4375 f = XFRAME (frame);
4376 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4377 continue;
4378 if (f->output_data.x->hourglass_window == wdesc)
4379 return f;
4380 #ifdef USE_X_TOOLKIT
4381 if ((f->output_data.x->edit_widget
4382 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4383 /* A tooltip frame? */
4384 || (!f->output_data.x->edit_widget
4385 && FRAME_X_WINDOW (f) == wdesc)
4386 || f->output_data.x->icon_desc == wdesc)
4387 return f;
4388 #else /* not USE_X_TOOLKIT */
4389 #ifdef USE_GTK
4390 if (f->output_data.x->edit_widget)
4392 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4393 struct x_output *x = f->output_data.x;
4394 if (gwdesc != 0 && gwdesc == x->edit_widget)
4395 return f;
4397 #endif /* USE_GTK */
4398 if (FRAME_X_WINDOW (f) == wdesc
4399 || f->output_data.x->icon_desc == wdesc)
4400 return f;
4401 #endif /* not USE_X_TOOLKIT */
4403 return 0;
4406 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4408 /* Like x_window_to_frame but also compares the window with the widget's
4409 windows. */
4411 static struct frame *
4412 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4414 Lisp_Object tail, frame;
4415 struct frame *f, *found = NULL;
4416 struct x_output *x;
4418 if (wdesc == None)
4419 return NULL;
4421 FOR_EACH_FRAME (tail, frame)
4423 if (found)
4424 break;
4425 f = XFRAME (frame);
4426 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4428 /* This frame matches if the window is any of its widgets. */
4429 x = f->output_data.x;
4430 if (x->hourglass_window == wdesc)
4431 found = f;
4432 else if (x->widget)
4434 #ifdef USE_GTK
4435 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4436 if (gwdesc != 0
4437 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4438 found = f;
4439 #else
4440 if (wdesc == XtWindow (x->widget)
4441 || wdesc == XtWindow (x->column_widget)
4442 || wdesc == XtWindow (x->edit_widget))
4443 found = f;
4444 /* Match if the window is this frame's menubar. */
4445 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4446 found = f;
4447 #endif
4449 else if (FRAME_X_WINDOW (f) == wdesc)
4450 /* A tooltip frame. */
4451 found = f;
4455 return found;
4458 /* Likewise, but consider only the menu bar widget. */
4460 static struct frame *
4461 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4462 const XEvent *event)
4464 Window wdesc = event->xany.window;
4465 Lisp_Object tail, frame;
4466 struct frame *f;
4467 struct x_output *x;
4469 if (wdesc == None)
4470 return NULL;
4472 FOR_EACH_FRAME (tail, frame)
4474 f = XFRAME (frame);
4475 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4476 continue;
4477 x = f->output_data.x;
4478 #ifdef USE_GTK
4479 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4480 return f;
4481 #else
4482 /* Match if the window is this frame's menubar. */
4483 if (x->menubar_widget
4484 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4485 return f;
4486 #endif
4488 return 0;
4491 /* Return the frame whose principal (outermost) window is WDESC.
4492 If WDESC is some other (smaller) window, we return 0. */
4494 struct frame *
4495 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4497 Lisp_Object tail, frame;
4498 struct frame *f;
4499 struct x_output *x;
4501 if (wdesc == None)
4502 return NULL;
4504 FOR_EACH_FRAME (tail, frame)
4506 f = XFRAME (frame);
4507 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4508 continue;
4509 x = f->output_data.x;
4511 if (x->widget)
4513 /* This frame matches if the window is its topmost widget. */
4514 #ifdef USE_GTK
4515 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4516 if (gwdesc == x->widget)
4517 return f;
4518 #else
4519 if (wdesc == XtWindow (x->widget))
4520 return f;
4521 #endif
4523 else if (FRAME_X_WINDOW (f) == wdesc)
4524 /* Tooltip frame. */
4525 return f;
4527 return 0;
4530 #else /* !USE_X_TOOLKIT && !USE_GTK */
4532 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4533 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4535 #endif /* USE_X_TOOLKIT || USE_GTK */
4537 /* The focus may have changed. Figure out if it is a real focus change,
4538 by checking both FocusIn/Out and Enter/LeaveNotify events.
4540 Returns FOCUS_IN_EVENT event in *BUFP. */
4542 static void
4543 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4544 const XEvent *event, struct input_event *bufp)
4546 if (!frame)
4547 return;
4549 switch (event->type)
4551 case EnterNotify:
4552 case LeaveNotify:
4554 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4555 int focus_state
4556 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4558 if (event->xcrossing.detail != NotifyInferior
4559 && event->xcrossing.focus
4560 && ! (focus_state & FOCUS_EXPLICIT))
4561 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4562 FOCUS_IMPLICIT,
4563 dpyinfo, frame, bufp);
4565 break;
4567 case FocusIn:
4568 case FocusOut:
4569 x_focus_changed (event->type,
4570 (event->xfocus.detail == NotifyPointer ?
4571 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4572 dpyinfo, frame, bufp);
4573 break;
4575 case ClientMessage:
4576 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4578 enum xembed_message msg = event->xclient.data.l[1];
4579 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4580 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4582 break;
4587 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4588 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4590 void
4591 x_mouse_leave (struct x_display_info *dpyinfo)
4593 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4595 #endif
4597 /* The focus has changed, or we have redirected a frame's focus to
4598 another frame (this happens when a frame uses a surrogate
4599 mini-buffer frame). Shift the highlight as appropriate.
4601 The FRAME argument doesn't necessarily have anything to do with which
4602 frame is being highlighted or un-highlighted; we only use it to find
4603 the appropriate X display info. */
4605 static void
4606 XTframe_rehighlight (struct frame *frame)
4608 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4611 static void
4612 x_frame_rehighlight (struct x_display_info *dpyinfo)
4614 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4616 if (dpyinfo->x_focus_frame)
4618 dpyinfo->x_highlight_frame
4619 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4620 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4621 : dpyinfo->x_focus_frame);
4622 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4624 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4625 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4628 else
4629 dpyinfo->x_highlight_frame = 0;
4631 if (dpyinfo->x_highlight_frame != old_highlight)
4633 if (old_highlight)
4634 frame_unhighlight (old_highlight);
4635 if (dpyinfo->x_highlight_frame)
4636 frame_highlight (dpyinfo->x_highlight_frame);
4642 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4644 /* Initialize mode_switch_bit and modifier_meaning. */
4645 static void
4646 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4648 int min_code, max_code;
4649 KeySym *syms;
4650 int syms_per_code;
4651 XModifierKeymap *mods;
4653 dpyinfo->meta_mod_mask = 0;
4654 dpyinfo->shift_lock_mask = 0;
4655 dpyinfo->alt_mod_mask = 0;
4656 dpyinfo->super_mod_mask = 0;
4657 dpyinfo->hyper_mod_mask = 0;
4659 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4661 syms = XGetKeyboardMapping (dpyinfo->display,
4662 min_code, max_code - min_code + 1,
4663 &syms_per_code);
4664 mods = XGetModifierMapping (dpyinfo->display);
4666 /* Scan the modifier table to see which modifier bits the Meta and
4667 Alt keysyms are on. */
4669 int row, col; /* The row and column in the modifier table. */
4670 bool found_alt_or_meta;
4672 for (row = 3; row < 8; row++)
4674 found_alt_or_meta = false;
4675 for (col = 0; col < mods->max_keypermod; col++)
4677 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4679 /* Zeroes are used for filler. Skip them. */
4680 if (code == 0)
4681 continue;
4683 /* Are any of this keycode's keysyms a meta key? */
4685 int code_col;
4687 for (code_col = 0; code_col < syms_per_code; code_col++)
4689 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4691 switch (sym)
4693 case XK_Meta_L:
4694 case XK_Meta_R:
4695 found_alt_or_meta = true;
4696 dpyinfo->meta_mod_mask |= (1 << row);
4697 break;
4699 case XK_Alt_L:
4700 case XK_Alt_R:
4701 found_alt_or_meta = true;
4702 dpyinfo->alt_mod_mask |= (1 << row);
4703 break;
4705 case XK_Hyper_L:
4706 case XK_Hyper_R:
4707 if (!found_alt_or_meta)
4708 dpyinfo->hyper_mod_mask |= (1 << row);
4709 code_col = syms_per_code;
4710 col = mods->max_keypermod;
4711 break;
4713 case XK_Super_L:
4714 case XK_Super_R:
4715 if (!found_alt_or_meta)
4716 dpyinfo->super_mod_mask |= (1 << row);
4717 code_col = syms_per_code;
4718 col = mods->max_keypermod;
4719 break;
4721 case XK_Shift_Lock:
4722 /* Ignore this if it's not on the lock modifier. */
4723 if (!found_alt_or_meta && ((1 << row) == LockMask))
4724 dpyinfo->shift_lock_mask = LockMask;
4725 code_col = syms_per_code;
4726 col = mods->max_keypermod;
4727 break;
4735 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4736 if (! dpyinfo->meta_mod_mask)
4738 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4739 dpyinfo->alt_mod_mask = 0;
4742 /* If some keys are both alt and meta,
4743 make them just meta, not alt. */
4744 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4746 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4749 XFree (syms);
4750 XFreeModifiermap (mods);
4753 /* Convert between the modifier bits X uses and the modifier bits
4754 Emacs uses. */
4757 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4759 int mod_ctrl = ctrl_modifier;
4760 int mod_meta = meta_modifier;