‘signal’ no longer returns
[emacs.git] / src / xterm.c
blobcd1d712f39ad28cd07bc1caa9871d2d10d63df9c
1 /* X Communication module for terminals which understand the X protocol.
3 Copyright (C) 1989, 1993-2016 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 #ifdef USE_CAIRO
26 #include <math.h>
27 #endif
29 #include "lisp.h"
30 #include "blockinput.h"
32 /* This may include sys/types.h, and that somehow loses
33 if this is not done before the other system files. */
34 #include "xterm.h"
35 #include <X11/cursorfont.h>
37 /* If we have Xfixes extension, use it for pointer blanking. */
38 #ifdef HAVE_XFIXES
39 #include <X11/extensions/Xfixes.h>
40 #endif
42 /* Using Xft implies that XRender is available. */
43 #ifdef HAVE_XFT
44 #include <X11/extensions/Xrender.h>
45 #endif
47 /* Load sys/types.h if not already loaded.
48 In some systems loading it twice is suicidal. */
49 #ifndef makedev
50 #include <sys/types.h>
51 #endif /* makedev */
53 #include <sys/ioctl.h>
55 #include "systime.h"
57 #include <fcntl.h>
58 #include <errno.h>
59 #include <sys/stat.h>
60 #include "character.h"
61 #include "coding.h"
62 #include "composite.h"
63 #include "frame.h"
64 #include "dispextern.h"
65 #include "xwidget.h"
66 #include "fontset.h"
67 #include "termhooks.h"
68 #include "termopts.h"
69 #include "termchar.h"
70 #include "emacs-icon.h"
71 #include "buffer.h"
72 #include "window.h"
73 #include "keyboard.h"
74 #include "atimer.h"
75 #include "font.h"
76 #include "xsettings.h"
77 #include "sysselect.h"
78 #include "menu.h"
80 #ifdef USE_X_TOOLKIT
81 #include <X11/Shell.h>
82 #endif
84 #include <unistd.h>
86 #ifdef USE_GTK
87 #include "gtkutil.h"
88 #ifdef HAVE_GTK3
89 #include <X11/Xproto.h>
90 #endif
91 #endif
93 #if defined (USE_LUCID) || defined (USE_MOTIF)
94 #include "../lwlib/xlwmenu.h"
95 #endif
97 #ifdef USE_X_TOOLKIT
99 /* Include toolkit specific headers for the scroll bar widget. */
101 #ifdef USE_TOOLKIT_SCROLL_BARS
102 #if defined USE_MOTIF
103 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
104 #include <Xm/ScrollBar.h>
105 #else /* !USE_MOTIF i.e. use Xaw */
107 #ifdef HAVE_XAW3D
108 #include <X11/Xaw3d/Simple.h>
109 #include <X11/Xaw3d/Scrollbar.h>
110 #include <X11/Xaw3d/ThreeD.h>
111 #else /* !HAVE_XAW3D */
112 #include <X11/Xaw/Simple.h>
113 #include <X11/Xaw/Scrollbar.h>
114 #endif /* !HAVE_XAW3D */
115 #ifndef XtNpickTop
116 #define XtNpickTop "pickTop"
117 #endif /* !XtNpickTop */
118 #endif /* !USE_MOTIF */
119 #endif /* USE_TOOLKIT_SCROLL_BARS */
121 #endif /* USE_X_TOOLKIT */
123 #ifdef USE_X_TOOLKIT
124 #include "widget.h"
125 #ifndef XtNinitialState
126 #define XtNinitialState "initialState"
127 #endif
128 #endif
130 #include "bitmaps/gray.xbm"
132 #ifdef HAVE_XKB
133 #include <X11/XKBlib.h>
134 #endif
136 /* Default to using XIM if available. */
137 #ifdef USE_XIM
138 bool use_xim = true;
139 #else
140 bool use_xim = false; /* configure --without-xim */
141 #endif
143 /* Non-zero means that a HELP_EVENT has been generated since Emacs
144 start. */
146 static bool any_help_event_p;
148 /* This is a chain of structures for all the X displays currently in
149 use. */
151 struct x_display_info *x_display_list;
153 #ifdef USE_X_TOOLKIT
155 /* The application context for Xt use. */
156 XtAppContext Xt_app_con;
157 static String Xt_default_resources[] = {0};
159 /* Non-zero means user is interacting with a toolkit scroll bar. */
160 static bool toolkit_scroll_bar_interaction;
162 #endif /* USE_X_TOOLKIT */
164 /* Non-zero timeout value means ignore next mouse click if it arrives
165 before that timeout elapses (i.e. as part of the same sequence of
166 events resulting from clicking on a frame to select it). */
168 static Time ignore_next_mouse_click_timeout;
170 /* Used locally within XTread_socket. */
172 static int x_noop_count;
174 #ifdef USE_GTK
175 /* The name of the Emacs icon file. */
176 static Lisp_Object xg_default_icon_file;
177 #endif
179 /* Some functions take this as char *, not const char *. */
180 static char emacs_class[] = EMACS_CLASS;
182 enum xembed_info
184 XEMBED_MAPPED = 1 << 0
187 enum xembed_message
189 XEMBED_EMBEDDED_NOTIFY = 0,
190 XEMBED_WINDOW_ACTIVATE = 1,
191 XEMBED_WINDOW_DEACTIVATE = 2,
192 XEMBED_REQUEST_FOCUS = 3,
193 XEMBED_FOCUS_IN = 4,
194 XEMBED_FOCUS_OUT = 5,
195 XEMBED_FOCUS_NEXT = 6,
196 XEMBED_FOCUS_PREV = 7,
198 XEMBED_MODALITY_ON = 10,
199 XEMBED_MODALITY_OFF = 11,
200 XEMBED_REGISTER_ACCELERATOR = 12,
201 XEMBED_UNREGISTER_ACCELERATOR = 13,
202 XEMBED_ACTIVATE_ACCELERATOR = 14
205 static void x_free_cr_resources (struct frame *);
206 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
207 static void x_raise_frame (struct frame *);
208 static void x_lower_frame (struct frame *);
209 static int x_io_error_quitter (Display *);
210 static struct terminal *x_create_terminal (struct x_display_info *);
211 static void x_frame_rehighlight (struct x_display_info *);
213 static void x_clip_to_row (struct window *, struct glyph_row *,
214 enum glyph_row_area, GC);
215 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
216 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
217 enum scroll_bar_part *,
218 Lisp_Object *, Lisp_Object *,
219 Time *);
220 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
221 enum scroll_bar_part *,
222 Lisp_Object *, Lisp_Object *,
223 Time *);
224 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
225 static void x_check_fullscreen (struct frame *);
226 static void x_check_expected_move (struct frame *, int, int);
227 static void x_sync_with_move (struct frame *, int, int, bool);
228 static int handle_one_xevent (struct x_display_info *,
229 const XEvent *, int *,
230 struct input_event *);
231 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
232 static int x_dispatch_event (XEvent *, Display *);
233 #endif
234 static void x_wm_set_window_state (struct frame *, int);
235 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
236 static void x_initialize (void);
238 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
240 /* Flush display of frame F. */
242 static void
243 x_flush (struct frame *f)
245 eassert (f && FRAME_X_P (f));
246 /* Don't call XFlush when it is not safe to redisplay; the X
247 connection may be broken. */
248 if (!NILP (Vinhibit_redisplay))
249 return;
251 block_input ();
252 XFlush (FRAME_X_DISPLAY (f));
253 unblock_input ();
257 /* Remove calls to XFlush by defining XFlush to an empty replacement.
258 Calls to XFlush should be unnecessary because the X output buffer
259 is flushed automatically as needed by calls to XPending,
260 XNextEvent, or XWindowEvent according to the XFlush man page.
261 XTread_socket calls XPending. Removing XFlush improves
262 performance. */
264 #define XFlush(DISPLAY) (void) 0
267 /***********************************************************************
268 Debugging
269 ***********************************************************************/
271 #if false
273 /* This is a function useful for recording debugging information about
274 the sequence of occurrences in this file. */
276 struct record
278 char *locus;
279 int type;
282 struct record event_record[100];
284 int event_record_index;
286 void
287 record_event (char *locus, int type)
289 if (event_record_index == ARRAYELTS (event_record))
290 event_record_index = 0;
292 event_record[event_record_index].locus = locus;
293 event_record[event_record_index].type = type;
294 event_record_index++;
297 #endif
299 #ifdef USE_CAIRO
301 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
302 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
304 static struct x_gc_ext_data *
305 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
307 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
308 XEDataObject object;
309 XExtData **head, *ext_data;
311 object.gc = gc;
312 head = XEHeadOfExtensionList (object);
313 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
314 if (ext_data == NULL)
316 if (!create_if_not_found_p)
317 return NULL;
318 else
320 ext_data = xzalloc (sizeof (*ext_data));
321 ext_data->number = dpyinfo->ext_codes->extension;
322 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
323 XAddToExtensionList (head, ext_data);
326 return (struct x_gc_ext_data *) ext_data->private_data;
329 static void
330 x_extension_initialize (struct x_display_info *dpyinfo)
332 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
334 dpyinfo->ext_codes = ext_codes;
337 static void
338 x_cr_destroy_surface (struct frame *f)
340 if (FRAME_CR_SURFACE (f))
342 cairo_t *cr = FRAME_CR_CONTEXT (f);
343 cairo_surface_destroy (FRAME_CR_SURFACE (f));
344 FRAME_CR_SURFACE (f) = 0;
345 if (cr) cairo_destroy (cr);
346 FRAME_CR_CONTEXT (f) = NULL;
350 cairo_t *
351 x_begin_cr_clip (struct frame *f, GC gc)
353 cairo_t *cr = FRAME_CR_CONTEXT (f);
355 if (!cr)
358 if (! FRAME_CR_SURFACE (f))
360 cairo_surface_t *surface;
361 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
362 FRAME_X_WINDOW (f),
363 FRAME_DISPLAY_INFO (f)->visual,
364 FRAME_PIXEL_WIDTH (f),
365 FRAME_PIXEL_HEIGHT (f));
366 cr = cairo_create (surface);
367 cairo_surface_destroy (surface);
369 else
370 cr = cairo_create (FRAME_CR_SURFACE (f));
371 FRAME_CR_CONTEXT (f) = cr;
373 cairo_save (cr);
375 if (gc)
377 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
379 if (gc_ext && gc_ext->n_clip_rects)
381 int i;
383 for (i = 0; i < gc_ext->n_clip_rects; i++)
384 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
385 gc_ext->clip_rects[i].y,
386 gc_ext->clip_rects[i].width,
387 gc_ext->clip_rects[i].height);
388 cairo_clip (cr);
392 return cr;
395 void
396 x_end_cr_clip (struct frame *f)
398 cairo_restore (FRAME_CR_CONTEXT (f));
401 void
402 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
404 XGCValues xgcv;
405 XColor color;
407 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
408 color.pixel = xgcv.foreground;
409 x_query_color (f, &color);
410 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
411 color.green / 65535.0, color.blue / 65535.0);
414 void
415 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
417 XGCValues xgcv;
418 XColor color;
420 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
421 color.pixel = xgcv.background;
422 x_query_color (f, &color);
423 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
424 color.green / 65535.0, color.blue / 65535.0);
427 /* Fringe bitmaps. */
429 static int max_fringe_bmp = 0;
430 static cairo_pattern_t **fringe_bmp = 0;
432 static void
433 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
435 int i, stride;
436 cairo_surface_t *surface;
437 unsigned char *data;
438 cairo_pattern_t *pattern;
440 if (which >= max_fringe_bmp)
442 i = max_fringe_bmp;
443 max_fringe_bmp = which + 20;
444 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
445 while (i < max_fringe_bmp)
446 fringe_bmp[i++] = 0;
449 block_input ();
451 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
452 stride = cairo_image_surface_get_stride (surface);
453 data = cairo_image_surface_get_data (surface);
455 for (i = 0; i < h; i++)
457 *((unsigned short *) data) = bits[i];
458 data += stride;
461 cairo_surface_mark_dirty (surface);
462 pattern = cairo_pattern_create_for_surface (surface);
463 cairo_surface_destroy (surface);
465 unblock_input ();
467 fringe_bmp[which] = pattern;
470 static void
471 x_cr_destroy_fringe_bitmap (int which)
473 if (which >= max_fringe_bmp)
474 return;
476 if (fringe_bmp[which])
478 block_input ();
479 cairo_pattern_destroy (fringe_bmp[which]);
480 unblock_input ();
482 fringe_bmp[which] = 0;
485 static void
486 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
487 int src_x, int src_y, int width, int height,
488 int dest_x, int dest_y, bool overlay_p)
490 cairo_t *cr;
491 cairo_matrix_t matrix;
492 cairo_surface_t *surface;
493 cairo_format_t format;
495 cr = x_begin_cr_clip (f, gc);
496 if (overlay_p)
497 cairo_rectangle (cr, dest_x, dest_y, width, height);
498 else
500 x_set_cr_source_with_gc_background (f, gc);
501 cairo_rectangle (cr, dest_x, dest_y, width, height);
502 cairo_fill_preserve (cr);
504 cairo_clip (cr);
505 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
506 cairo_pattern_set_matrix (image, &matrix);
507 cairo_pattern_get_surface (image, &surface);
508 format = cairo_image_surface_get_format (surface);
509 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
511 cairo_set_source (cr, image);
512 cairo_fill (cr);
514 else
516 x_set_cr_source_with_gc_foreground (f, gc);
517 cairo_mask (cr, image);
519 x_end_cr_clip (f);
522 void
523 x_cr_draw_frame (cairo_t *cr, struct frame *f)
525 int width, height;
527 width = FRAME_PIXEL_WIDTH (f);
528 height = FRAME_PIXEL_HEIGHT (f);
530 x_free_cr_resources (f);
531 FRAME_CR_CONTEXT (f) = cr;
532 x_clear_area (f, 0, 0, width, height);
533 expose_frame (f, 0, 0, width, height);
534 FRAME_CR_CONTEXT (f) = NULL;
537 static cairo_status_t
538 x_cr_accumulate_data (void *closure, const unsigned char *data,
539 unsigned int length)
541 Lisp_Object *acc = (Lisp_Object *) closure;
543 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
545 return CAIRO_STATUS_SUCCESS;
548 static void
549 x_cr_destroy (Lisp_Object arg)
551 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
553 block_input ();
554 cairo_destroy (cr);
555 unblock_input ();
558 Lisp_Object
559 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
561 struct frame *f;
562 cairo_surface_t *surface;
563 cairo_t *cr;
564 int width, height;
565 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
566 Lisp_Object acc = Qnil;
567 int count = SPECPDL_INDEX ();
569 specbind (Qredisplay_dont_pause, Qt);
570 redisplay_preserve_echo_area (31);
572 f = XFRAME (XCAR (frames));
573 frames = XCDR (frames);
574 width = FRAME_PIXEL_WIDTH (f);
575 height = FRAME_PIXEL_HEIGHT (f);
577 block_input ();
578 #ifdef CAIRO_HAS_PDF_SURFACE
579 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
581 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
582 width, height);
583 surface_set_size_func = cairo_pdf_surface_set_size;
585 else
586 #endif
587 #ifdef CAIRO_HAS_PNG_FUNCTIONS
588 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
589 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
590 else
591 #endif
592 #ifdef CAIRO_HAS_PS_SURFACE
593 if (surface_type == CAIRO_SURFACE_TYPE_PS)
595 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
596 width, height);
597 surface_set_size_func = cairo_ps_surface_set_size;
599 else
600 #endif
601 #ifdef CAIRO_HAS_SVG_SURFACE
602 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
603 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
604 width, height);
605 else
606 #endif
607 abort ();
609 cr = cairo_create (surface);
610 cairo_surface_destroy (surface);
611 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
613 while (1)
615 x_free_cr_resources (f);
616 FRAME_CR_CONTEXT (f) = cr;
617 x_clear_area (f, 0, 0, width, height);
618 expose_frame (f, 0, 0, width, height);
619 FRAME_CR_CONTEXT (f) = NULL;
621 if (NILP (frames))
622 break;
624 cairo_surface_show_page (surface);
625 f = XFRAME (XCAR (frames));
626 frames = XCDR (frames);
627 width = FRAME_PIXEL_WIDTH (f);
628 height = FRAME_PIXEL_HEIGHT (f);
629 if (surface_set_size_func)
630 (*surface_set_size_func) (surface, width, height);
632 unblock_input ();
633 QUIT;
634 block_input ();
637 #ifdef CAIRO_HAS_PNG_FUNCTIONS
638 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
640 cairo_surface_flush (surface);
641 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
643 #endif
644 unblock_input ();
646 unbind_to (count, Qnil);
648 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
651 #endif /* USE_CAIRO */
653 static void
654 x_free_cr_resources (struct frame *f)
656 #ifdef USE_CAIRO
657 if (f == NULL)
659 Lisp_Object rest, frame;
660 FOR_EACH_FRAME (rest, frame)
661 if (FRAME_X_P (XFRAME (frame)))
662 x_free_cr_resources (XFRAME (frame));
664 else
666 cairo_t *cr = FRAME_CR_CONTEXT (f);
668 if (cr)
670 cairo_surface_t *surface = cairo_get_target (cr);
672 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
674 cairo_destroy (cr);
675 FRAME_CR_CONTEXT (f) = NULL;
679 #endif
682 static void
683 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
685 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
686 #ifdef USE_CAIRO
687 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
690 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
692 gc_ext->n_clip_rects = n;
693 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
695 #endif
698 static void
699 x_reset_clip_rectangles (struct frame *f, GC gc)
701 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
702 #ifdef USE_CAIRO
704 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
706 if (gc_ext)
707 gc_ext->n_clip_rects = 0;
709 #endif
712 static void
713 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
715 #ifdef USE_CAIRO
716 cairo_t *cr;
718 cr = x_begin_cr_clip (f, gc);
719 x_set_cr_source_with_gc_foreground (f, gc);
720 cairo_rectangle (cr, x, y, width, height);
721 cairo_fill (cr);
722 x_end_cr_clip (f);
723 #else
724 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
725 gc, x, y, width, height);
726 #endif
729 static void
730 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
732 #ifdef USE_CAIRO
733 cairo_t *cr;
735 cr = x_begin_cr_clip (f, gc);
736 x_set_cr_source_with_gc_foreground (f, gc);
737 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
738 cairo_set_line_width (cr, 1);
739 cairo_stroke (cr);
740 x_end_cr_clip (f);
741 #else
742 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
743 gc, x, y, width, height);
744 #endif
747 static void
748 x_clear_window (struct frame *f)
750 #ifdef USE_CAIRO
751 cairo_t *cr;
753 cr = x_begin_cr_clip (f, NULL);
754 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
755 cairo_paint (cr);
756 x_end_cr_clip (f);
757 #else
758 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
759 #endif
762 #ifdef USE_CAIRO
763 static void
764 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
765 int width, int height, int top_p)
767 cairo_t *cr;
769 cr = x_begin_cr_clip (f, gc);
770 x_set_cr_source_with_gc_foreground (f, gc);
771 cairo_move_to (cr, top_p ? x : x + height, y);
772 cairo_line_to (cr, x, y + height);
773 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
774 cairo_line_to (cr, x + width, y);
775 cairo_fill (cr);
776 x_end_cr_clip (f);
779 enum corners
781 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
782 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
783 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
784 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
785 CORNER_LAST
788 static void
789 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
790 int width, int height,
791 double radius, double margin, int corners)
793 cairo_t *cr;
794 int i;
796 cr = x_begin_cr_clip (f, gc);
797 x_set_cr_source_with_gc_background (f, gc);
798 for (i = 0; i < CORNER_LAST; i++)
799 if (corners & (1 << i))
801 double xm, ym, xc, yc;
803 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
804 xm = x - margin, xc = xm + radius;
805 else
806 xm = x + width + margin, xc = xm - radius;
807 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
808 ym = y - margin, yc = ym + radius;
809 else
810 ym = y + height + margin, yc = ym - radius;
812 cairo_move_to (cr, xm, ym);
813 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
815 cairo_clip (cr);
816 cairo_rectangle (cr, x, y, width, height);
817 cairo_fill (cr);
818 x_end_cr_clip (f);
821 static void
822 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
823 int width, int height, int wave_length)
825 cairo_t *cr;
826 double dx = wave_length, dy = height - 1;
827 int xoffset, n;
829 cr = x_begin_cr_clip (f, gc);
830 x_set_cr_source_with_gc_foreground (f, gc);
831 cairo_rectangle (cr, x, y, width, height);
832 cairo_clip (cr);
834 if (x >= 0)
836 xoffset = x % (wave_length * 2);
837 if (xoffset == 0)
838 xoffset = wave_length * 2;
840 else
841 xoffset = x % (wave_length * 2) + wave_length * 2;
842 n = (width + xoffset) / wave_length + 1;
843 if (xoffset > wave_length)
845 xoffset -= wave_length;
846 --n;
847 y += height - 1;
848 dy = -dy;
851 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
852 while (--n >= 0)
854 cairo_rel_line_to (cr, dx, dy);
855 dy = -dy;
857 cairo_set_line_width (cr, 1);
858 cairo_stroke (cr);
859 x_end_cr_clip (f);
861 #endif
864 /* Return the struct x_display_info corresponding to DPY. */
866 struct x_display_info *
867 x_display_info_for_display (Display *dpy)
869 struct x_display_info *dpyinfo;
871 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
872 if (dpyinfo->display == dpy)
873 return dpyinfo;
875 return 0;
878 static Window
879 x_find_topmost_parent (struct frame *f)
881 struct x_output *x = f->output_data.x;
882 Window win = None, wi = x->parent_desc;
883 Display *dpy = FRAME_X_DISPLAY (f);
885 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
887 Window root;
888 Window *children;
889 unsigned int nchildren;
891 win = wi;
892 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
893 XFree (children);
894 else
895 break;
898 return win;
901 #define OPAQUE 0xffffffff
903 void
904 x_set_frame_alpha (struct frame *f)
906 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
907 Display *dpy = FRAME_X_DISPLAY (f);
908 Window win = FRAME_OUTER_WINDOW (f);
909 double alpha = 1.0;
910 double alpha_min = 1.0;
911 unsigned long opac;
912 Window parent;
914 if (dpyinfo->x_highlight_frame == f)
915 alpha = f->alpha[0];
916 else
917 alpha = f->alpha[1];
919 if (FLOATP (Vframe_alpha_lower_limit))
920 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
921 else if (INTEGERP (Vframe_alpha_lower_limit))
922 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
924 if (alpha < 0.0)
925 return;
926 else if (alpha > 1.0)
927 alpha = 1.0;
928 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
929 alpha = alpha_min;
931 opac = alpha * OPAQUE;
933 x_catch_errors (dpy);
935 /* If there is a parent from the window manager, put the property there
936 also, to work around broken window managers that fail to do that.
937 Do this unconditionally as this function is called on reparent when
938 alpha has not changed on the frame. */
940 parent = x_find_topmost_parent (f);
941 if (parent != None)
942 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
943 XA_CARDINAL, 32, PropModeReplace,
944 (unsigned char *) &opac, 1);
946 /* return unless necessary */
948 unsigned char *data;
949 Atom actual;
950 int rc, format;
951 unsigned long n, left;
953 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
954 0, 1, False, XA_CARDINAL,
955 &actual, &format, &n, &left,
956 &data);
958 if (rc == Success && actual != None)
960 unsigned long value = *(unsigned long *)data;
961 XFree (data);
962 if (value == opac)
964 x_uncatch_errors ();
965 return;
970 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
971 XA_CARDINAL, 32, PropModeReplace,
972 (unsigned char *) &opac, 1);
973 x_uncatch_errors ();
976 /***********************************************************************
977 Starting and ending an update
978 ***********************************************************************/
980 /* Start an update of frame F. This function is installed as a hook
981 for update_begin, i.e. it is called when update_begin is called.
982 This function is called prior to calls to x_update_window_begin for
983 each window being updated. Currently, there is nothing to do here
984 because all interesting stuff is done on a window basis. */
986 static void
987 x_update_begin (struct frame *f)
989 #ifdef USE_CAIRO
990 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
991 && ! FRAME_VISIBLE_P (f))
992 return;
994 if (! FRAME_CR_SURFACE (f))
996 int width, height;
997 #ifdef USE_GTK
998 if (FRAME_GTK_WIDGET (f))
1000 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1001 width = gdk_window_get_width (w);
1002 height = gdk_window_get_height (w);
1004 else
1005 #endif
1007 width = FRAME_PIXEL_WIDTH (f);
1008 height = FRAME_PIXEL_HEIGHT (f);
1009 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1010 height += FRAME_TOOL_BAR_HEIGHT (f);
1011 if (! FRAME_EXTERNAL_MENU_BAR (f))
1012 height += FRAME_MENU_BAR_HEIGHT (f);
1015 if (width > 0 && height > 0)
1017 block_input();
1018 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1019 (CAIRO_FORMAT_ARGB32, width, height);
1020 unblock_input();
1023 #endif /* USE_CAIRO */
1026 /* Start update of window W. */
1028 static void
1029 x_update_window_begin (struct window *w)
1031 struct frame *f = XFRAME (WINDOW_FRAME (w));
1032 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1034 w->output_cursor = w->cursor;
1036 block_input ();
1038 if (f == hlinfo->mouse_face_mouse_frame)
1040 /* Don't do highlighting for mouse motion during the update. */
1041 hlinfo->mouse_face_defer = true;
1043 /* If F needs to be redrawn, simply forget about any prior mouse
1044 highlighting. */
1045 if (FRAME_GARBAGED_P (f))
1046 hlinfo->mouse_face_window = Qnil;
1049 unblock_input ();
1053 /* Draw a vertical window border from (x,y0) to (x,y1) */
1055 static void
1056 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1058 struct frame *f = XFRAME (WINDOW_FRAME (w));
1059 struct face *face;
1061 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1062 if (face)
1063 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1064 face->foreground);
1066 #ifdef USE_CAIRO
1067 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1068 #else
1069 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1070 f->output_data.x->normal_gc, x, y0, x, y1);
1071 #endif
1074 /* Draw a window divider from (x0,y0) to (x1,y1) */
1076 static void
1077 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1079 struct frame *f = XFRAME (WINDOW_FRAME (w));
1080 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1081 struct face *face_first
1082 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1083 struct face *face_last
1084 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1085 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1086 unsigned long color_first = (face_first
1087 ? face_first->foreground
1088 : FRAME_FOREGROUND_PIXEL (f));
1089 unsigned long color_last = (face_last
1090 ? face_last->foreground
1091 : FRAME_FOREGROUND_PIXEL (f));
1092 Display *display = FRAME_X_DISPLAY (f);
1094 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1095 /* Vertical. */
1097 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1098 x_fill_rectangle (f, f->output_data.x->normal_gc,
1099 x0, y0, 1, y1 - y0);
1100 XSetForeground (display, f->output_data.x->normal_gc, color);
1101 x_fill_rectangle (f, f->output_data.x->normal_gc,
1102 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1103 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1104 x_fill_rectangle (f, f->output_data.x->normal_gc,
1105 x1 - 1, y0, 1, y1 - y0);
1107 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1108 /* Horizontal. */
1110 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1111 x_fill_rectangle (f, f->output_data.x->normal_gc,
1112 x0, y0, x1 - x0, 1);
1113 XSetForeground (display, f->output_data.x->normal_gc, color);
1114 x_fill_rectangle (f, f->output_data.x->normal_gc,
1115 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1116 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1117 x_fill_rectangle (f, f->output_data.x->normal_gc,
1118 x0, y1 - 1, x1 - x0, 1);
1120 else
1122 XSetForeground (display, f->output_data.x->normal_gc, color);
1123 x_fill_rectangle (f, f->output_data.x->normal_gc,
1124 x0, y0, x1 - x0, y1 - y0);
1128 /* End update of window W.
1130 Draw vertical borders between horizontally adjacent windows, and
1131 display W's cursor if CURSOR_ON_P is non-zero.
1133 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1134 glyphs in mouse-face were overwritten. In that case we have to
1135 make sure that the mouse-highlight is properly redrawn.
1137 W may be a menu bar pseudo-window in case we don't have X toolkit
1138 support. Such windows don't have a cursor, so don't display it
1139 here. */
1141 static void
1142 x_update_window_end (struct window *w, bool cursor_on_p,
1143 bool mouse_face_overwritten_p)
1145 if (!w->pseudo_window_p)
1147 block_input ();
1149 if (cursor_on_p)
1150 display_and_set_cursor (w, true,
1151 w->output_cursor.hpos, w->output_cursor.vpos,
1152 w->output_cursor.x, w->output_cursor.y);
1154 if (draw_window_fringes (w, true))
1156 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1157 x_draw_right_divider (w);
1158 else
1159 x_draw_vertical_border (w);
1162 unblock_input ();
1165 /* If a row with mouse-face was overwritten, arrange for
1166 XTframe_up_to_date to redisplay the mouse highlight. */
1167 if (mouse_face_overwritten_p)
1169 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1171 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1172 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1173 hlinfo->mouse_face_window = Qnil;
1178 /* End update of frame F. This function is installed as a hook in
1179 update_end. */
1181 static void
1182 x_update_end (struct frame *f)
1184 /* Mouse highlight may be displayed again. */
1185 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1187 #ifdef USE_CAIRO
1188 if (FRAME_CR_SURFACE (f))
1190 cairo_t *cr = 0;
1191 block_input();
1192 #if defined (USE_GTK) && defined (HAVE_GTK3)
1193 if (FRAME_GTK_WIDGET (f))
1195 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1196 cr = gdk_cairo_create (w);
1198 else
1199 #endif
1201 cairo_surface_t *surface;
1202 int width = FRAME_PIXEL_WIDTH (f);
1203 int height = FRAME_PIXEL_HEIGHT (f);
1204 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1205 height += FRAME_TOOL_BAR_HEIGHT (f);
1206 if (! FRAME_EXTERNAL_MENU_BAR (f))
1207 height += FRAME_MENU_BAR_HEIGHT (f);
1208 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1209 FRAME_X_WINDOW (f),
1210 FRAME_DISPLAY_INFO (f)->visual,
1211 width,
1212 height);
1213 cr = cairo_create (surface);
1214 cairo_surface_destroy (surface);
1217 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1218 cairo_paint (cr);
1219 cairo_destroy (cr);
1220 unblock_input ();
1222 #endif /* USE_CAIRO */
1224 #ifndef XFlush
1225 block_input ();
1226 XFlush (FRAME_X_DISPLAY (f));
1227 unblock_input ();
1228 #endif
1232 /* This function is called from various places in xdisp.c
1233 whenever a complete update has been performed. */
1235 static void
1236 XTframe_up_to_date (struct frame *f)
1238 if (FRAME_X_P (f))
1239 FRAME_MOUSE_UPDATE (f);
1243 /* Clear under internal border if any (GTK has its own version). */
1244 #ifndef USE_GTK
1245 void
1246 x_clear_under_internal_border (struct frame *f)
1248 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1250 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1251 int width = FRAME_PIXEL_WIDTH (f);
1252 int height = FRAME_PIXEL_HEIGHT (f);
1253 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1255 block_input ();
1256 x_clear_area (f, 0, 0, border, height);
1257 x_clear_area (f, 0, margin, width, border);
1258 x_clear_area (f, width - border, 0, border, height);
1259 x_clear_area (f, 0, height - border, width, border);
1260 unblock_input ();
1263 #endif
1265 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1266 arrow bitmaps, or clear the fringes if no bitmaps are required
1267 before DESIRED_ROW is made current. This function is called from
1268 update_window_line only if it is known that there are differences
1269 between bitmaps to be drawn between current row and DESIRED_ROW. */
1271 static void
1272 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1274 eassert (w);
1276 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1277 desired_row->redraw_fringe_bitmaps_p = true;
1279 #ifdef USE_X_TOOLKIT
1280 /* When a window has disappeared, make sure that no rest of
1281 full-width rows stays visible in the internal border. Could
1282 check here if updated window is the leftmost/rightmost window,
1283 but I guess it's not worth doing since vertically split windows
1284 are almost never used, internal border is rarely set, and the
1285 overhead is very small. */
1287 struct frame *f;
1288 int width, height;
1290 if (windows_or_buffers_changed
1291 && desired_row->full_width_p
1292 && (f = XFRAME (w->frame),
1293 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1294 width != 0)
1295 && (height = desired_row->visible_height,
1296 height > 0))
1298 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1300 block_input ();
1301 x_clear_area (f, 0, y, width, height);
1302 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1303 unblock_input ();
1306 #endif
1309 static void
1310 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1312 struct frame *f = XFRAME (WINDOW_FRAME (w));
1313 Display *display = FRAME_X_DISPLAY (f);
1314 GC gc = f->output_data.x->normal_gc;
1315 struct face *face = p->face;
1317 /* Must clip because of partially visible lines. */
1318 x_clip_to_row (w, row, ANY_AREA, gc);
1320 if (p->bx >= 0 && !p->overlay_p)
1322 /* In case the same realized face is used for fringes and
1323 for something displayed in the text (e.g. face `region' on
1324 mono-displays, the fill style may have been changed to
1325 FillSolid in x_draw_glyph_string_background. */
1326 if (face->stipple)
1327 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1328 else
1329 XSetForeground (display, face->gc, face->background);
1331 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1333 if (!face->stipple)
1334 XSetForeground (display, face->gc, face->foreground);
1337 #ifdef USE_CAIRO
1338 if (p->which && p->which < max_fringe_bmp)
1340 XGCValues gcv;
1342 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1343 XSetForeground (display, gc, (p->cursor_p
1344 ? (p->overlay_p ? face->background
1345 : f->output_data.x->cursor_pixel)
1346 : face->foreground));
1347 XSetBackground (display, gc, face->background);
1348 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1349 p->wd, p->h, p->x, p->y, p->overlay_p);
1350 XSetForeground (display, gc, gcv.foreground);
1351 XSetBackground (display, gc, gcv.background);
1353 #else /* not USE_CAIRO */
1354 if (p->which)
1356 Window window = FRAME_X_WINDOW (f);
1357 char *bits;
1358 Pixmap pixmap, clipmask = (Pixmap) 0;
1359 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1360 XGCValues gcv;
1362 if (p->wd > 8)
1363 bits = (char *) (p->bits + p->dh);
1364 else
1365 bits = (char *) p->bits + p->dh;
1367 /* Draw the bitmap. I believe these small pixmaps can be cached
1368 by the server. */
1369 pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h,
1370 (p->cursor_p
1371 ? (p->overlay_p ? face->background
1372 : f->output_data.x->cursor_pixel)
1373 : face->foreground),
1374 face->background, depth);
1376 if (p->overlay_p)
1378 clipmask = XCreatePixmapFromBitmapData (display,
1379 FRAME_DISPLAY_INFO (f)->root_window,
1380 bits, p->wd, p->h,
1381 1, 0, 1);
1382 gcv.clip_mask = clipmask;
1383 gcv.clip_x_origin = p->x;
1384 gcv.clip_y_origin = p->y;
1385 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1388 XCopyArea (display, pixmap, window, gc, 0, 0,
1389 p->wd, p->h, p->x, p->y);
1390 XFreePixmap (display, pixmap);
1392 if (p->overlay_p)
1394 gcv.clip_mask = (Pixmap) 0;
1395 XChangeGC (display, gc, GCClipMask, &gcv);
1396 XFreePixmap (display, clipmask);
1399 #endif /* not USE_CAIRO */
1401 x_reset_clip_rectangles (f, gc);
1404 /***********************************************************************
1405 Glyph display
1406 ***********************************************************************/
1410 static void x_set_glyph_string_clipping (struct glyph_string *);
1411 static void x_set_glyph_string_gc (struct glyph_string *);
1412 static void x_draw_glyph_string_foreground (struct glyph_string *);
1413 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1414 static void x_draw_glyph_string_box (struct glyph_string *);
1415 static void x_draw_glyph_string (struct glyph_string *);
1416 static _Noreturn void x_delete_glyphs (struct frame *, int);
1417 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1418 static void x_set_cursor_gc (struct glyph_string *);
1419 static void x_set_mode_line_face_gc (struct glyph_string *);
1420 static void x_set_mouse_face_gc (struct glyph_string *);
1421 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1422 unsigned long *, double, int);
1423 static void x_setup_relief_color (struct frame *, struct relief *,
1424 double, int, unsigned long);
1425 static void x_setup_relief_colors (struct glyph_string *);
1426 static void x_draw_image_glyph_string (struct glyph_string *);
1427 static void x_draw_image_relief (struct glyph_string *);
1428 static void x_draw_image_foreground (struct glyph_string *);
1429 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1430 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1431 int, int, int);
1432 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1433 int, bool, bool, bool, bool, bool,
1434 XRectangle *);
1435 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1436 int, bool, bool, XRectangle *);
1437 static void x_scroll_bar_clear (struct frame *);
1439 #ifdef GLYPH_DEBUG
1440 static void x_check_font (struct frame *, struct font *);
1441 #endif
1444 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1445 face. */
1447 static void
1448 x_set_cursor_gc (struct glyph_string *s)
1450 if (s->font == FRAME_FONT (s->f)
1451 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1452 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1453 && !s->cmp)
1454 s->gc = s->f->output_data.x->cursor_gc;
1455 else
1457 /* Cursor on non-default face: must merge. */
1458 XGCValues xgcv;
1459 unsigned long mask;
1461 xgcv.background = s->f->output_data.x->cursor_pixel;
1462 xgcv.foreground = s->face->background;
1464 /* If the glyph would be invisible, try a different foreground. */
1465 if (xgcv.foreground == xgcv.background)
1466 xgcv.foreground = s->face->foreground;
1467 if (xgcv.foreground == xgcv.background)
1468 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1469 if (xgcv.foreground == xgcv.background)
1470 xgcv.foreground = s->face->foreground;
1472 /* Make sure the cursor is distinct from text in this face. */
1473 if (xgcv.background == s->face->background
1474 && xgcv.foreground == s->face->foreground)
1476 xgcv.background = s->face->foreground;
1477 xgcv.foreground = s->face->background;
1480 IF_DEBUG (x_check_font (s->f, s->font));
1481 xgcv.graphics_exposures = False;
1482 mask = GCForeground | GCBackground | GCGraphicsExposures;
1484 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1485 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1486 mask, &xgcv);
1487 else
1488 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1489 = XCreateGC (s->display, s->window, mask, &xgcv);
1491 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1496 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1498 static void
1499 x_set_mouse_face_gc (struct glyph_string *s)
1501 int face_id;
1502 struct face *face;
1504 /* What face has to be used last for the mouse face? */
1505 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1506 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1507 if (face == NULL)
1508 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1510 if (s->first_glyph->type == CHAR_GLYPH)
1511 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1512 else
1513 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1514 s->face = FACE_FROM_ID (s->f, face_id);
1515 prepare_face_for_display (s->f, s->face);
1517 if (s->font == s->face->font)
1518 s->gc = s->face->gc;
1519 else
1521 /* Otherwise construct scratch_cursor_gc with values from FACE
1522 except for FONT. */
1523 XGCValues xgcv;
1524 unsigned long mask;
1526 xgcv.background = s->face->background;
1527 xgcv.foreground = s->face->foreground;
1528 xgcv.graphics_exposures = False;
1529 mask = GCForeground | GCBackground | GCGraphicsExposures;
1531 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1532 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1533 mask, &xgcv);
1534 else
1535 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1536 = XCreateGC (s->display, s->window, mask, &xgcv);
1538 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1541 eassert (s->gc != 0);
1545 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1546 Faces to use in the mode line have already been computed when the
1547 matrix was built, so there isn't much to do, here. */
1549 static void
1550 x_set_mode_line_face_gc (struct glyph_string *s)
1552 s->gc = s->face->gc;
1556 /* Set S->gc of glyph string S for drawing that glyph string. Set
1557 S->stippled_p to a non-zero value if the face of S has a stipple
1558 pattern. */
1560 static void
1561 x_set_glyph_string_gc (struct glyph_string *s)
1563 prepare_face_for_display (s->f, s->face);
1565 if (s->hl == DRAW_NORMAL_TEXT)
1567 s->gc = s->face->gc;
1568 s->stippled_p = s->face->stipple != 0;
1570 else if (s->hl == DRAW_INVERSE_VIDEO)
1572 x_set_mode_line_face_gc (s);
1573 s->stippled_p = s->face->stipple != 0;
1575 else if (s->hl == DRAW_CURSOR)
1577 x_set_cursor_gc (s);
1578 s->stippled_p = false;
1580 else if (s->hl == DRAW_MOUSE_FACE)
1582 x_set_mouse_face_gc (s);
1583 s->stippled_p = s->face->stipple != 0;
1585 else if (s->hl == DRAW_IMAGE_RAISED
1586 || s->hl == DRAW_IMAGE_SUNKEN)
1588 s->gc = s->face->gc;
1589 s->stippled_p = s->face->stipple != 0;
1591 else
1592 emacs_abort ();
1594 /* GC must have been set. */
1595 eassert (s->gc != 0);
1599 /* Set clipping for output of glyph string S. S may be part of a mode
1600 line or menu if we don't have X toolkit support. */
1602 static void
1603 x_set_glyph_string_clipping (struct glyph_string *s)
1605 XRectangle *r = s->clip;
1606 int n = get_glyph_string_clip_rects (s, r, 2);
1608 if (n > 0)
1609 x_set_clip_rectangles (s->f, s->gc, r, n);
1610 s->num_clips = n;
1614 /* Set SRC's clipping for output of glyph string DST. This is called
1615 when we are drawing DST's left_overhang or right_overhang only in
1616 the area of SRC. */
1618 static void
1619 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1621 XRectangle r;
1623 r.x = src->x;
1624 r.width = src->width;
1625 r.y = src->y;
1626 r.height = src->height;
1627 dst->clip[0] = r;
1628 dst->num_clips = 1;
1629 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1633 /* RIF:
1634 Compute left and right overhang of glyph string S. */
1636 static void
1637 x_compute_glyph_string_overhangs (struct glyph_string *s)
1639 if (s->cmp == NULL
1640 && (s->first_glyph->type == CHAR_GLYPH
1641 || s->first_glyph->type == COMPOSITE_GLYPH))
1643 struct font_metrics metrics;
1645 if (s->first_glyph->type == CHAR_GLYPH)
1647 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1648 struct font *font = s->font;
1649 int i;
1651 for (i = 0; i < s->nchars; i++)
1652 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1653 font->driver->text_extents (font, code, s->nchars, &metrics);
1655 else
1657 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1659 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1661 s->right_overhang = (metrics.rbearing > metrics.width
1662 ? metrics.rbearing - metrics.width : 0);
1663 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1665 else if (s->cmp)
1667 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1668 s->left_overhang = - s->cmp->lbearing;
1673 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1675 static void
1676 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1678 XGCValues xgcv;
1679 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1680 XSetForeground (s->display, s->gc, xgcv.background);
1681 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1682 XSetForeground (s->display, s->gc, xgcv.foreground);
1686 /* Draw the background of glyph_string S. If S->background_filled_p
1687 is non-zero don't draw it. FORCE_P non-zero means draw the
1688 background even if it wouldn't be drawn normally. This is used
1689 when a string preceding S draws into the background of S, or S
1690 contains the first component of a composition. */
1692 static void
1693 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1695 /* Nothing to do if background has already been drawn or if it
1696 shouldn't be drawn in the first place. */
1697 if (!s->background_filled_p)
1699 int box_line_width = max (s->face->box_line_width, 0);
1701 if (s->stippled_p)
1703 /* Fill background with a stipple pattern. */
1704 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1705 x_fill_rectangle (s->f, s->gc, s->x,
1706 s->y + box_line_width,
1707 s->background_width,
1708 s->height - 2 * box_line_width);
1709 XSetFillStyle (s->display, s->gc, FillSolid);
1710 s->background_filled_p = true;
1712 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1713 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1714 font dimensions, since the actual glyphs might be
1715 much smaller. So in that case we always clear the
1716 rectangle with background color. */
1717 || FONT_TOO_HIGH (s->font)
1718 || s->font_not_found_p
1719 || s->extends_to_end_of_line_p
1720 || force_p)
1722 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1723 s->background_width,
1724 s->height - 2 * box_line_width);
1725 s->background_filled_p = true;
1731 /* Draw the foreground of glyph string S. */
1733 static void
1734 x_draw_glyph_string_foreground (struct glyph_string *s)
1736 int i, x;
1738 /* If first glyph of S has a left box line, start drawing the text
1739 of S to the right of that box line. */
1740 if (s->face->box != FACE_NO_BOX
1741 && s->first_glyph->left_box_line_p)
1742 x = s->x + eabs (s->face->box_line_width);
1743 else
1744 x = s->x;
1746 /* Draw characters of S as rectangles if S's font could not be
1747 loaded. */
1748 if (s->font_not_found_p)
1750 for (i = 0; i < s->nchars; ++i)
1752 struct glyph *g = s->first_glyph + i;
1753 x_draw_rectangle (s->f,
1754 s->gc, x, s->y, g->pixel_width - 1,
1755 s->height - 1);
1756 x += g->pixel_width;
1759 else
1761 struct font *font = s->font;
1762 int boff = font->baseline_offset;
1763 int y;
1765 if (font->vertical_centering)
1766 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1768 y = s->ybase - boff;
1769 if (s->for_overlaps
1770 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1771 font->driver->draw (s, 0, s->nchars, x, y, false);
1772 else
1773 font->driver->draw (s, 0, s->nchars, x, y, true);
1774 if (s->face->overstrike)
1775 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1779 /* Draw the foreground of composite glyph string S. */
1781 static void
1782 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1784 int i, j, x;
1785 struct font *font = s->font;
1787 /* If first glyph of S has a left box line, start drawing the text
1788 of S to the right of that box line. */
1789 if (s->face && s->face->box != FACE_NO_BOX
1790 && s->first_glyph->left_box_line_p)
1791 x = s->x + eabs (s->face->box_line_width);
1792 else
1793 x = s->x;
1795 /* S is a glyph string for a composition. S->cmp_from is the index
1796 of the first character drawn for glyphs of this composition.
1797 S->cmp_from == 0 means we are drawing the very first character of
1798 this composition. */
1800 /* Draw a rectangle for the composition if the font for the very
1801 first character of the composition could not be loaded. */
1802 if (s->font_not_found_p)
1804 if (s->cmp_from == 0)
1805 x_draw_rectangle (s->f, s->gc, x, s->y,
1806 s->width - 1, s->height - 1);
1808 else if (! s->first_glyph->u.cmp.automatic)
1810 int y = s->ybase;
1812 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1813 /* TAB in a composition means display glyphs with padding
1814 space on the left or right. */
1815 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1817 int xx = x + s->cmp->offsets[j * 2];
1818 int yy = y - s->cmp->offsets[j * 2 + 1];
1820 font->driver->draw (s, j, j + 1, xx, yy, false);
1821 if (s->face->overstrike)
1822 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1825 else
1827 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1828 Lisp_Object glyph;
1829 int y = s->ybase;
1830 int width = 0;
1832 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1834 glyph = LGSTRING_GLYPH (gstring, i);
1835 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1836 width += LGLYPH_WIDTH (glyph);
1837 else
1839 int xoff, yoff, wadjust;
1841 if (j < i)
1843 font->driver->draw (s, j, i, x, y, false);
1844 if (s->face->overstrike)
1845 font->driver->draw (s, j, i, x + 1, y, false);
1846 x += width;
1848 xoff = LGLYPH_XOFF (glyph);
1849 yoff = LGLYPH_YOFF (glyph);
1850 wadjust = LGLYPH_WADJUST (glyph);
1851 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1852 if (s->face->overstrike)
1853 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1854 false);
1855 x += wadjust;
1856 j = i + 1;
1857 width = 0;
1860 if (j < i)
1862 font->driver->draw (s, j, i, x, y, false);
1863 if (s->face->overstrike)
1864 font->driver->draw (s, j, i, x + 1, y, false);
1870 /* Draw the foreground of glyph string S for glyphless characters. */
1872 static void
1873 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1875 struct glyph *glyph = s->first_glyph;
1876 XChar2b char2b[8];
1877 int x, i, j;
1879 /* If first glyph of S has a left box line, start drawing the text
1880 of S to the right of that box line. */
1881 if (s->face && s->face->box != FACE_NO_BOX
1882 && s->first_glyph->left_box_line_p)
1883 x = s->x + eabs (s->face->box_line_width);
1884 else
1885 x = s->x;
1887 s->char2b = char2b;
1889 for (i = 0; i < s->nchars; i++, glyph++)
1891 char buf[7], *str = NULL;
1892 int len = glyph->u.glyphless.len;
1894 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1896 if (len > 0
1897 && CHAR_TABLE_P (Vglyphless_char_display)
1898 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1899 >= 1))
1901 Lisp_Object acronym
1902 = (! glyph->u.glyphless.for_no_font
1903 ? CHAR_TABLE_REF (Vglyphless_char_display,
1904 glyph->u.glyphless.ch)
1905 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1906 if (STRINGP (acronym))
1907 str = SSDATA (acronym);
1910 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1912 sprintf (buf, "%0*X",
1913 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1914 glyph->u.glyphless.ch + 0u);
1915 str = buf;
1918 if (str)
1920 int upper_len = (len + 1) / 2;
1921 unsigned code;
1923 /* It is assured that all LEN characters in STR is ASCII. */
1924 for (j = 0; j < len; j++)
1926 code = s->font->driver->encode_char (s->font, str[j]);
1927 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
1929 s->font->driver->draw (s, 0, upper_len,
1930 x + glyph->slice.glyphless.upper_xoff,
1931 s->ybase + glyph->slice.glyphless.upper_yoff,
1932 false);
1933 s->font->driver->draw (s, upper_len, len,
1934 x + glyph->slice.glyphless.lower_xoff,
1935 s->ybase + glyph->slice.glyphless.lower_yoff,
1936 false);
1938 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1939 x_draw_rectangle (s->f, s->gc,
1940 x, s->ybase - glyph->ascent,
1941 glyph->pixel_width - 1,
1942 glyph->ascent + glyph->descent - 1);
1943 x += glyph->pixel_width;
1947 #ifdef USE_X_TOOLKIT
1949 #ifdef USE_LUCID
1951 /* Return the frame on which widget WIDGET is used.. Abort if frame
1952 cannot be determined. */
1954 static struct frame *
1955 x_frame_of_widget (Widget widget)
1957 struct x_display_info *dpyinfo;
1958 Lisp_Object tail, frame;
1959 struct frame *f;
1961 dpyinfo = x_display_info_for_display (XtDisplay (widget));
1963 /* Find the top-level shell of the widget. Note that this function
1964 can be called when the widget is not yet realized, so XtWindow
1965 (widget) == 0. That's the reason we can't simply use
1966 x_any_window_to_frame. */
1967 while (!XtIsTopLevelShell (widget))
1968 widget = XtParent (widget);
1970 /* Look for a frame with that top-level widget. Allocate the color
1971 on that frame to get the right gamma correction value. */
1972 FOR_EACH_FRAME (tail, frame)
1974 f = XFRAME (frame);
1975 if (FRAME_X_P (f)
1976 && f->output_data.nothing != 1
1977 && FRAME_DISPLAY_INFO (f) == dpyinfo
1978 && f->output_data.x->widget == widget)
1979 return f;
1981 emacs_abort ();
1984 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
1985 or DELTA. Try a color with RGB values multiplied by FACTOR first.
1986 If this produces the same color as PIXEL, try a color where all RGB
1987 values have DELTA added. Return the allocated color in *PIXEL.
1988 DISPLAY is the X display, CMAP is the colormap to operate on.
1989 Value is true if successful. */
1991 bool
1992 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
1993 unsigned long *pixel, double factor, int delta)
1995 struct frame *f = x_frame_of_widget (widget);
1996 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
1999 #endif /* USE_LUCID */
2002 /* Structure specifying which arguments should be passed by Xt to
2003 cvt_string_to_pixel. We want the widget's screen and colormap. */
2005 static XtConvertArgRec cvt_string_to_pixel_args[] =
2007 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2008 sizeof (Screen *)},
2009 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2010 sizeof (Colormap)}
2014 /* The address of this variable is returned by
2015 cvt_string_to_pixel. */
2017 static Pixel cvt_string_to_pixel_value;
2020 /* Convert a color name to a pixel color.
2022 DPY is the display we are working on.
2024 ARGS is an array of *NARGS XrmValue structures holding additional
2025 information about the widget for which the conversion takes place.
2026 The contents of this array are determined by the specification
2027 in cvt_string_to_pixel_args.
2029 FROM is a pointer to an XrmValue which points to the color name to
2030 convert. TO is an XrmValue in which to return the pixel color.
2032 CLOSURE_RET is a pointer to user-data, in which we record if
2033 we allocated the color or not.
2035 Value is True if successful, False otherwise. */
2037 static Boolean
2038 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2039 XrmValue *from, XrmValue *to,
2040 XtPointer *closure_ret)
2042 Screen *screen;
2043 Colormap cmap;
2044 Pixel pixel;
2045 String color_name;
2046 XColor color;
2048 if (*nargs != 2)
2050 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2051 "wrongParameters", "cvt_string_to_pixel",
2052 "XtToolkitError",
2053 "Screen and colormap args required", NULL, NULL);
2054 return False;
2057 screen = *(Screen **) args[0].addr;
2058 cmap = *(Colormap *) args[1].addr;
2059 color_name = (String) from->addr;
2061 if (strcmp (color_name, XtDefaultBackground) == 0)
2063 *closure_ret = (XtPointer) False;
2064 pixel = WhitePixelOfScreen (screen);
2066 else if (strcmp (color_name, XtDefaultForeground) == 0)
2068 *closure_ret = (XtPointer) False;
2069 pixel = BlackPixelOfScreen (screen);
2071 else if (XParseColor (dpy, cmap, color_name, &color)
2072 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2074 pixel = color.pixel;
2075 *closure_ret = (XtPointer) True;
2077 else
2079 String params[1];
2080 Cardinal nparams = 1;
2082 params[0] = color_name;
2083 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2084 "badValue", "cvt_string_to_pixel",
2085 "XtToolkitError", "Invalid color '%s'",
2086 params, &nparams);
2087 return False;
2090 if (to->addr != NULL)
2092 if (to->size < sizeof (Pixel))
2094 to->size = sizeof (Pixel);
2095 return False;
2098 *(Pixel *) to->addr = pixel;
2100 else
2102 cvt_string_to_pixel_value = pixel;
2103 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2106 to->size = sizeof (Pixel);
2107 return True;
2111 /* Free a pixel color which was previously allocated via
2112 cvt_string_to_pixel. This is registered as the destructor
2113 for this type of resource via XtSetTypeConverter.
2115 APP is the application context in which we work.
2117 TO is a pointer to an XrmValue holding the color to free.
2118 CLOSURE is the value we stored in CLOSURE_RET for this color
2119 in cvt_string_to_pixel.
2121 ARGS and NARGS are like for cvt_string_to_pixel. */
2123 static void
2124 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2125 Cardinal *nargs)
2127 if (*nargs != 2)
2129 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2130 "XtToolkitError",
2131 "Screen and colormap arguments required",
2132 NULL, NULL);
2134 else if (closure != NULL)
2136 /* We did allocate the pixel, so free it. */
2137 Screen *screen = *(Screen **) args[0].addr;
2138 Colormap cmap = *(Colormap *) args[1].addr;
2139 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2140 (Pixel *) to->addr, 1);
2145 #endif /* USE_X_TOOLKIT */
2148 /* Value is an array of XColor structures for the contents of the
2149 color map of display DPY. Set *NCELLS to the size of the array.
2150 Note that this probably shouldn't be called for large color maps,
2151 say a 24-bit TrueColor map. */
2153 static const XColor *
2154 x_color_cells (Display *dpy, int *ncells)
2156 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2157 eassume (dpyinfo);
2159 if (dpyinfo->color_cells == NULL)
2161 Screen *screen = dpyinfo->screen;
2162 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2163 int i;
2165 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2166 sizeof *dpyinfo->color_cells);
2167 dpyinfo->ncolor_cells = ncolor_cells;
2169 for (i = 0; i < ncolor_cells; ++i)
2170 dpyinfo->color_cells[i].pixel = i;
2172 XQueryColors (dpy, dpyinfo->cmap,
2173 dpyinfo->color_cells, ncolor_cells);
2176 *ncells = dpyinfo->ncolor_cells;
2177 return dpyinfo->color_cells;
2181 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2182 colors in COLORS. Use cached information, if available. */
2184 void
2185 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2187 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2189 if (dpyinfo->red_bits > 0)
2191 /* For TrueColor displays, we can decompose the RGB value
2192 directly. */
2193 int i;
2194 unsigned int rmult, gmult, bmult;
2195 unsigned int rmask, gmask, bmask;
2197 rmask = (1 << dpyinfo->red_bits) - 1;
2198 gmask = (1 << dpyinfo->green_bits) - 1;
2199 bmask = (1 << dpyinfo->blue_bits) - 1;
2200 /* If we're widening, for example, 8 bits in the pixel value to
2201 16 bits for the separate-color representation, we want to
2202 extrapolate the lower bits based on those bits available --
2203 in other words, we'd like 0xff to become 0xffff instead of
2204 the 0xff00 we'd get by just zero-filling the lower bits.
2206 We generate a 32-bit scaled-up value and shift it, in case
2207 the bit count doesn't divide 16 evenly (e.g., when dealing
2208 with a 3-3-2 bit RGB display), to get more of the lower bits
2209 correct.
2211 Should we cache the multipliers in dpyinfo? Maybe
2212 special-case the 8-8-8 common case? */
2213 rmult = 0xffffffff / rmask;
2214 gmult = 0xffffffff / gmask;
2215 bmult = 0xffffffff / bmask;
2217 for (i = 0; i < ncolors; ++i)
2219 unsigned int r, g, b;
2220 unsigned long pixel = colors[i].pixel;
2222 r = (pixel >> dpyinfo->red_offset) & rmask;
2223 g = (pixel >> dpyinfo->green_offset) & gmask;
2224 b = (pixel >> dpyinfo->blue_offset) & bmask;
2226 colors[i].red = (r * rmult) >> 16;
2227 colors[i].green = (g * gmult) >> 16;
2228 colors[i].blue = (b * bmult) >> 16;
2230 return;
2233 if (dpyinfo->color_cells)
2235 int i;
2236 for (i = 0; i < ncolors; ++i)
2238 unsigned long pixel = colors[i].pixel;
2239 eassert (pixel < dpyinfo->ncolor_cells);
2240 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2241 colors[i] = dpyinfo->color_cells[pixel];
2243 return;
2246 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2250 /* On frame F, translate pixel color to RGB values for the color in
2251 COLOR. Use cached information, if available. */
2253 void
2254 x_query_color (struct frame *f, XColor *color)
2256 x_query_colors (f, color, 1);
2260 /* On frame F, translate the color name to RGB values. Use cached
2261 information, if possible.
2263 Note that there is currently no way to clean old entries out of the
2264 cache. However, it is limited to names in the server's database,
2265 and names we've actually looked up; list-colors-display is probably
2266 the most color-intensive case we're likely to hit. */
2268 Status x_parse_color (struct frame *f, const char *color_name,
2269 XColor *color)
2271 Display *dpy = FRAME_X_DISPLAY (f);
2272 Colormap cmap = FRAME_X_COLORMAP (f);
2273 struct color_name_cache_entry *cache_entry;
2275 if (color_name[0] == '#')
2277 /* The hex form is parsed directly by XParseColor without
2278 talking to the X server. No need for caching. */
2279 return XParseColor (dpy, cmap, color_name, color);
2282 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2283 cache_entry = cache_entry->next)
2285 if (!xstrcasecmp(cache_entry->name, color_name))
2287 *color = cache_entry->rgb;
2288 return 1;
2292 if (XParseColor (dpy, cmap, color_name, color) == 0)
2293 /* No caching of negative results, currently. */
2294 return 0;
2296 cache_entry = xzalloc (sizeof *cache_entry);
2297 cache_entry->rgb = *color;
2298 cache_entry->name = xstrdup (color_name);
2299 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2300 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2301 return 1;
2305 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2306 exact match can't be allocated, try the nearest color available.
2307 Value is true if successful. Set *COLOR to the color
2308 allocated. */
2310 static bool
2311 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2313 bool rc;
2315 rc = XAllocColor (dpy, cmap, color) != 0;
2316 if (rc == 0)
2318 /* If we got to this point, the colormap is full, so we're going
2319 to try to get the next closest color. The algorithm used is
2320 a least-squares matching, which is what X uses for closest
2321 color matching with StaticColor visuals. */
2322 int nearest, i;
2323 int max_color_delta = 255;
2324 int max_delta = 3 * max_color_delta;
2325 int nearest_delta = max_delta + 1;
2326 int ncells;
2327 const XColor *cells = x_color_cells (dpy, &ncells);
2329 for (nearest = i = 0; i < ncells; ++i)
2331 int dred = (color->red >> 8) - (cells[i].red >> 8);
2332 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2333 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2334 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2336 if (delta < nearest_delta)
2338 nearest = i;
2339 nearest_delta = delta;
2343 color->red = cells[nearest].red;
2344 color->green = cells[nearest].green;
2345 color->blue = cells[nearest].blue;
2346 rc = XAllocColor (dpy, cmap, color) != 0;
2348 else
2350 /* If allocation succeeded, and the allocated pixel color is not
2351 equal to a cached pixel color recorded earlier, there was a
2352 change in the colormap, so clear the color cache. */
2353 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2354 eassume (dpyinfo);
2356 if (dpyinfo->color_cells)
2358 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2359 if (cached_color->red != color->red
2360 || cached_color->blue != color->blue
2361 || cached_color->green != color->green)
2363 xfree (dpyinfo->color_cells);
2364 dpyinfo->color_cells = NULL;
2365 dpyinfo->ncolor_cells = 0;
2370 #ifdef DEBUG_X_COLORS
2371 if (rc)
2372 register_color (color->pixel);
2373 #endif /* DEBUG_X_COLORS */
2375 return rc;
2379 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2380 gamma correction. If an exact match can't be allocated, try the
2381 nearest color available. Value is true if successful. Set *COLOR
2382 to the color allocated. */
2384 bool
2385 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2387 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2389 gamma_correct (f, color);
2391 if (dpyinfo->red_bits > 0)
2393 color->pixel = x_make_truecolor_pixel (dpyinfo,
2394 color->red,
2395 color->green,
2396 color->blue);
2397 return true;
2400 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2404 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2405 It's necessary to do this instead of just using PIXEL directly to
2406 get color reference counts right. */
2408 unsigned long
2409 x_copy_color (struct frame *f, unsigned long pixel)
2411 XColor color;
2413 /* If display has an immutable color map, freeing colors is not
2414 necessary and some servers don't allow it. Since we won't free a
2415 color once we've allocated it, we don't need to re-allocate it to
2416 maintain the server's reference count. */
2417 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2418 return pixel;
2420 color.pixel = pixel;
2421 block_input ();
2422 /* The color could still be found in the color_cells array. */
2423 x_query_color (f, &color);
2424 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2425 unblock_input ();
2426 #ifdef DEBUG_X_COLORS
2427 register_color (pixel);
2428 #endif
2429 return color.pixel;
2433 /* Brightness beyond which a color won't have its highlight brightness
2434 boosted.
2436 Nominally, highlight colors for `3d' faces are calculated by
2437 brightening an object's color by a constant scale factor, but this
2438 doesn't yield good results for dark colors, so for colors who's
2439 brightness is less than this value (on a scale of 0-65535) have an
2440 use an additional additive factor.
2442 The value here is set so that the default menu-bar/mode-line color
2443 (grey75) will not have its highlights changed at all. */
2444 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2447 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2448 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2449 If this produces the same color as PIXEL, try a color where all RGB
2450 values have DELTA added. Return the allocated color in *PIXEL.
2451 DISPLAY is the X display, CMAP is the colormap to operate on.
2452 Value is non-zero if successful. */
2454 static bool
2455 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2456 unsigned long *pixel, double factor, int delta)
2458 XColor color, new;
2459 long bright;
2460 bool success_p;
2462 /* Get RGB color values. */
2463 color.pixel = *pixel;
2464 x_query_color (f, &color);
2466 /* Change RGB values by specified FACTOR. Avoid overflow! */
2467 eassert (factor >= 0);
2468 new.red = min (0xffff, factor * color.red);
2469 new.green = min (0xffff, factor * color.green);
2470 new.blue = min (0xffff, factor * color.blue);
2472 /* Calculate brightness of COLOR. */
2473 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2475 /* We only boost colors that are darker than
2476 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2477 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2478 /* Make an additive adjustment to NEW, because it's dark enough so
2479 that scaling by FACTOR alone isn't enough. */
2481 /* How far below the limit this color is (0 - 1, 1 being darker). */
2482 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2483 /* The additive adjustment. */
2484 int min_delta = delta * dimness * factor / 2;
2486 if (factor < 1)
2488 new.red = max (0, new.red - min_delta);
2489 new.green = max (0, new.green - min_delta);
2490 new.blue = max (0, new.blue - min_delta);
2492 else
2494 new.red = min (0xffff, min_delta + new.red);
2495 new.green = min (0xffff, min_delta + new.green);
2496 new.blue = min (0xffff, min_delta + new.blue);
2500 /* Try to allocate the color. */
2501 success_p = x_alloc_nearest_color (f, cmap, &new);
2502 if (success_p)
2504 if (new.pixel == *pixel)
2506 /* If we end up with the same color as before, try adding
2507 delta to the RGB values. */
2508 x_free_colors (f, &new.pixel, 1);
2510 new.red = min (0xffff, delta + color.red);
2511 new.green = min (0xffff, delta + color.green);
2512 new.blue = min (0xffff, delta + color.blue);
2513 success_p = x_alloc_nearest_color (f, cmap, &new);
2515 else
2516 success_p = true;
2517 *pixel = new.pixel;
2520 return success_p;
2524 /* Set up the foreground color for drawing relief lines of glyph
2525 string S. RELIEF is a pointer to a struct relief containing the GC
2526 with which lines will be drawn. Use a color that is FACTOR or
2527 DELTA lighter or darker than the relief's background which is found
2528 in S->f->output_data.x->relief_background. If such a color cannot
2529 be allocated, use DEFAULT_PIXEL, instead. */
2531 static void
2532 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2533 int delta, unsigned long default_pixel)
2535 XGCValues xgcv;
2536 struct x_output *di = f->output_data.x;
2537 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2538 unsigned long pixel;
2539 unsigned long background = di->relief_background;
2540 Colormap cmap = FRAME_X_COLORMAP (f);
2541 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2542 Display *dpy = FRAME_X_DISPLAY (f);
2544 xgcv.graphics_exposures = False;
2545 xgcv.line_width = 1;
2547 /* Free previously allocated color. The color cell will be reused
2548 when it has been freed as many times as it was allocated, so this
2549 doesn't affect faces using the same colors. */
2550 if (relief->gc && relief->pixel != -1)
2552 x_free_colors (f, &relief->pixel, 1);
2553 relief->pixel = -1;
2556 /* Allocate new color. */
2557 xgcv.foreground = default_pixel;
2558 pixel = background;
2559 if (dpyinfo->n_planes != 1
2560 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2561 xgcv.foreground = relief->pixel = pixel;
2563 if (relief->gc == 0)
2565 xgcv.stipple = dpyinfo->gray;
2566 mask |= GCStipple;
2567 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
2569 else
2570 XChangeGC (dpy, relief->gc, mask, &xgcv);
2574 /* Set up colors for the relief lines around glyph string S. */
2576 static void
2577 x_setup_relief_colors (struct glyph_string *s)
2579 struct x_output *di = s->f->output_data.x;
2580 unsigned long color;
2582 if (s->face->use_box_color_for_shadows_p)
2583 color = s->face->box_color;
2584 else if (s->first_glyph->type == IMAGE_GLYPH
2585 && s->img->pixmap
2586 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2587 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2588 else
2590 XGCValues xgcv;
2592 /* Get the background color of the face. */
2593 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2594 color = xgcv.background;
2597 if (di->white_relief.gc == 0
2598 || color != di->relief_background)
2600 di->relief_background = color;
2601 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2602 WHITE_PIX_DEFAULT (s->f));
2603 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2604 BLACK_PIX_DEFAULT (s->f));
2609 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2610 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2611 to draw, it must be >= 0. RAISED_P means draw a raised
2612 relief. LEFT_P means draw a relief on the left side of
2613 the rectangle. RIGHT_P means draw a relief on the right
2614 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2615 when drawing. */
2617 static void
2618 x_draw_relief_rect (struct frame *f,
2619 int left_x, int top_y, int right_x, int bottom_y,
2620 int width, bool raised_p, bool top_p, bool bot_p,
2621 bool left_p, bool right_p,
2622 XRectangle *clip_rect)
2624 #ifdef USE_CAIRO
2625 GC top_left_gc, bottom_right_gc;
2626 int corners = 0;
2628 if (raised_p)
2630 top_left_gc = f->output_data.x->white_relief.gc;
2631 bottom_right_gc = f->output_data.x->black_relief.gc;
2633 else
2635 top_left_gc = f->output_data.x->black_relief.gc;
2636 bottom_right_gc = f->output_data.x->white_relief.gc;
2639 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2640 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2642 if (left_p)
2644 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2645 width, bottom_y + 1 - top_y);
2646 if (top_p)
2647 corners |= 1 << CORNER_TOP_LEFT;
2648 if (bot_p)
2649 corners |= 1 << CORNER_BOTTOM_LEFT;
2651 if (right_p)
2653 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2654 width, bottom_y + 1 - top_y);
2655 if (top_p)
2656 corners |= 1 << CORNER_TOP_RIGHT;
2657 if (bot_p)
2658 corners |= 1 << CORNER_BOTTOM_RIGHT;
2660 if (top_p)
2662 if (!right_p)
2663 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2664 right_x + 1 - left_x, width);
2665 else
2666 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2667 right_x + 1 - left_x, width, 1);
2669 if (bot_p)
2671 if (!left_p)
2672 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2673 right_x + 1 - left_x, width);
2674 else
2675 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2676 left_x, bottom_y + 1 - width,
2677 right_x + 1 - left_x, width, 0);
2679 if (left_p && width != 1)
2680 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2681 1, bottom_y + 1 - top_y);
2682 if (top_p && width != 1)
2683 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2684 right_x + 1 - left_x, 1);
2685 if (corners)
2687 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2688 FRAME_BACKGROUND_PIXEL (f));
2689 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2690 right_x - left_x + 1, bottom_y - top_y + 1,
2691 6, 1, corners);
2694 x_reset_clip_rectangles (f, top_left_gc);
2695 x_reset_clip_rectangles (f, bottom_right_gc);
2696 #else
2697 Display *dpy = FRAME_X_DISPLAY (f);
2698 Window window = FRAME_X_WINDOW (f);
2699 int i;
2700 GC gc;
2702 if (raised_p)
2703 gc = f->output_data.x->white_relief.gc;
2704 else
2705 gc = f->output_data.x->black_relief.gc;
2706 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2708 /* This code is more complicated than it has to be, because of two
2709 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2710 the outermost line using the black relief. (ii) Omit the four
2711 corner pixels. */
2713 /* Top. */
2714 if (top_p)
2716 if (width == 1)
2717 XDrawLine (dpy, window, gc,
2718 left_x + left_p, top_y,
2719 right_x + !right_p, top_y);
2721 for (i = 1; i < width; ++i)
2722 XDrawLine (dpy, window, gc,
2723 left_x + i * left_p, top_y + i,
2724 right_x + 1 - i * right_p, top_y + i);
2727 /* Left. */
2728 if (left_p)
2730 if (width == 1)
2731 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2733 XClearArea (dpy, window, left_x, top_y, 1, 1, False);
2734 XClearArea (dpy, window, left_x, bottom_y, 1, 1, False);
2736 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2737 XDrawLine (dpy, window, gc,
2738 left_x + i, top_y + (i + 1) * top_p,
2739 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2742 XSetClipMask (dpy, gc, None);
2743 if (raised_p)
2744 gc = f->output_data.x->black_relief.gc;
2745 else
2746 gc = f->output_data.x->white_relief.gc;
2747 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2749 if (width > 1)
2751 /* Outermost top line. */
2752 if (top_p)
2753 XDrawLine (dpy, window, gc,
2754 left_x + left_p, top_y,
2755 right_x + !right_p, top_y);
2757 /* Outermost left line. */
2758 if (left_p)
2759 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2762 /* Bottom. */
2763 if (bot_p)
2765 XDrawLine (dpy, window, gc,
2766 left_x + left_p, bottom_y,
2767 right_x + !right_p, bottom_y);
2768 for (i = 1; i < width; ++i)
2769 XDrawLine (dpy, window, gc,
2770 left_x + i * left_p, bottom_y - i,
2771 right_x + 1 - i * right_p, bottom_y - i);
2774 /* Right. */
2775 if (right_p)
2777 XClearArea (dpy, window, right_x, top_y, 1, 1, False);
2778 XClearArea (dpy, window, right_x, bottom_y, 1, 1, False);
2779 for (i = 0; i < width; ++i)
2780 XDrawLine (dpy, window, gc,
2781 right_x - i, top_y + (i + 1) * top_p,
2782 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2785 x_reset_clip_rectangles (f, gc);
2787 #endif
2791 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2792 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2793 draw, it must be >= 0. LEFT_P means draw a line on the
2794 left side of the rectangle. RIGHT_P means draw a line
2795 on the right side of the rectangle. CLIP_RECT is the clipping
2796 rectangle to use when drawing. */
2798 static void
2799 x_draw_box_rect (struct glyph_string *s,
2800 int left_x, int top_y, int right_x, int bottom_y, int width,
2801 bool left_p, bool right_p, XRectangle *clip_rect)
2803 XGCValues xgcv;
2805 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2806 XSetForeground (s->display, s->gc, s->face->box_color);
2807 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2809 /* Top. */
2810 x_fill_rectangle (s->f, s->gc,
2811 left_x, top_y, right_x - left_x + 1, width);
2813 /* Left. */
2814 if (left_p)
2815 x_fill_rectangle (s->f, s->gc,
2816 left_x, top_y, width, bottom_y - top_y + 1);
2818 /* Bottom. */
2819 x_fill_rectangle (s->f, s->gc,
2820 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2822 /* Right. */
2823 if (right_p)
2824 x_fill_rectangle (s->f, s->gc,
2825 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2827 XSetForeground (s->display, s->gc, xgcv.foreground);
2828 x_reset_clip_rectangles (s->f, s->gc);
2832 /* Draw a box around glyph string S. */
2834 static void
2835 x_draw_glyph_string_box (struct glyph_string *s)
2837 int width, left_x, right_x, top_y, bottom_y, last_x;
2838 bool raised_p, left_p, right_p;
2839 struct glyph *last_glyph;
2840 XRectangle clip_rect;
2842 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2843 ? WINDOW_RIGHT_EDGE_X (s->w)
2844 : window_box_right (s->w, s->area));
2846 /* The glyph that may have a right box line. */
2847 last_glyph = (s->cmp || s->img
2848 ? s->first_glyph
2849 : s->first_glyph + s->nchars - 1);
2851 width = eabs (s->face->box_line_width);
2852 raised_p = s->face->box == FACE_RAISED_BOX;
2853 left_x = s->x;
2854 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2855 ? last_x - 1
2856 : min (last_x, s->x + s->background_width) - 1);
2857 top_y = s->y;
2858 bottom_y = top_y + s->height - 1;
2860 left_p = (s->first_glyph->left_box_line_p
2861 || (s->hl == DRAW_MOUSE_FACE
2862 && (s->prev == NULL
2863 || s->prev->hl != s->hl)));
2864 right_p = (last_glyph->right_box_line_p
2865 || (s->hl == DRAW_MOUSE_FACE
2866 && (s->next == NULL
2867 || s->next->hl != s->hl)));
2869 get_glyph_string_clip_rect (s, &clip_rect);
2871 if (s->face->box == FACE_SIMPLE_BOX)
2872 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2873 left_p, right_p, &clip_rect);
2874 else
2876 x_setup_relief_colors (s);
2877 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2878 width, raised_p, true, true, left_p, right_p,
2879 &clip_rect);
2884 /* Draw foreground of image glyph string S. */
2886 static void
2887 x_draw_image_foreground (struct glyph_string *s)
2889 int x = s->x;
2890 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2892 /* If first glyph of S has a left box line, start drawing it to the
2893 right of that line. */
2894 if (s->face->box != FACE_NO_BOX
2895 && s->first_glyph->left_box_line_p
2896 && s->slice.x == 0)
2897 x += eabs (s->face->box_line_width);
2899 /* If there is a margin around the image, adjust x- and y-position
2900 by that margin. */
2901 if (s->slice.x == 0)
2902 x += s->img->hmargin;
2903 if (s->slice.y == 0)
2904 y += s->img->vmargin;
2906 if (s->img->pixmap)
2908 if (s->img->mask)
2910 /* We can't set both a clip mask and use XSetClipRectangles
2911 because the latter also sets a clip mask. We also can't
2912 trust on the shape extension to be available
2913 (XShapeCombineRegion). So, compute the rectangle to draw
2914 manually. */
2915 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2916 | GCFunction);
2917 XGCValues xgcv;
2918 XRectangle clip_rect, image_rect, r;
2920 xgcv.clip_mask = s->img->mask;
2921 xgcv.clip_x_origin = x;
2922 xgcv.clip_y_origin = y;
2923 xgcv.function = GXcopy;
2924 XChangeGC (s->display, s->gc, mask, &xgcv);
2926 get_glyph_string_clip_rect (s, &clip_rect);
2927 image_rect.x = x;
2928 image_rect.y = y;
2929 image_rect.width = s->slice.width;
2930 image_rect.height = s->slice.height;
2931 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2932 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2933 s->slice.x + r.x - x, s->slice.y + r.y - y,
2934 r.width, r.height, r.x, r.y);
2936 else
2938 XRectangle clip_rect, image_rect, r;
2940 get_glyph_string_clip_rect (s, &clip_rect);
2941 image_rect.x = x;
2942 image_rect.y = y;
2943 image_rect.width = s->slice.width;
2944 image_rect.height = s->slice.height;
2945 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2946 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2947 s->slice.x + r.x - x, s->slice.y + r.y - y,
2948 r.width, r.height, r.x, r.y);
2950 /* When the image has a mask, we can expect that at
2951 least part of a mouse highlight or a block cursor will
2952 be visible. If the image doesn't have a mask, make
2953 a block cursor visible by drawing a rectangle around
2954 the image. I believe it's looking better if we do
2955 nothing here for mouse-face. */
2956 if (s->hl == DRAW_CURSOR)
2958 int relief = eabs (s->img->relief);
2959 x_draw_rectangle (s->f, s->gc,
2960 x - relief, y - relief,
2961 s->slice.width + relief*2 - 1,
2962 s->slice.height + relief*2 - 1);
2966 else
2967 /* Draw a rectangle if image could not be loaded. */
2968 x_draw_rectangle (s->f, s->gc, x, y,
2969 s->slice.width - 1, s->slice.height - 1);
2973 /* Draw a relief around the image glyph string S. */
2975 static void
2976 x_draw_image_relief (struct glyph_string *s)
2978 int x1, y1, thick;
2979 bool raised_p, top_p, bot_p, left_p, right_p;
2980 int extra_x, extra_y;
2981 XRectangle r;
2982 int x = s->x;
2983 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2985 /* If first glyph of S has a left box line, start drawing it to the
2986 right of that line. */
2987 if (s->face->box != FACE_NO_BOX
2988 && s->first_glyph->left_box_line_p
2989 && s->slice.x == 0)
2990 x += eabs (s->face->box_line_width);
2992 /* If there is a margin around the image, adjust x- and y-position
2993 by that margin. */
2994 if (s->slice.x == 0)
2995 x += s->img->hmargin;
2996 if (s->slice.y == 0)
2997 y += s->img->vmargin;
2999 if (s->hl == DRAW_IMAGE_SUNKEN
3000 || s->hl == DRAW_IMAGE_RAISED)
3002 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3003 raised_p = s->hl == DRAW_IMAGE_RAISED;
3005 else
3007 thick = eabs (s->img->relief);
3008 raised_p = s->img->relief > 0;
3011 x1 = x + s->slice.width - 1;
3012 y1 = y + s->slice.height - 1;
3014 extra_x = extra_y = 0;
3015 if (s->face->id == TOOL_BAR_FACE_ID)
3017 if (CONSP (Vtool_bar_button_margin)
3018 && INTEGERP (XCAR (Vtool_bar_button_margin))
3019 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3021 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3022 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3024 else if (INTEGERP (Vtool_bar_button_margin))
3025 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3028 top_p = bot_p = left_p = right_p = false;
3030 if (s->slice.x == 0)
3031 x -= thick + extra_x, left_p = true;
3032 if (s->slice.y == 0)
3033 y -= thick + extra_y, top_p = true;
3034 if (s->slice.x + s->slice.width == s->img->width)
3035 x1 += thick + extra_x, right_p = true;
3036 if (s->slice.y + s->slice.height == s->img->height)
3037 y1 += thick + extra_y, bot_p = true;
3039 x_setup_relief_colors (s);
3040 get_glyph_string_clip_rect (s, &r);
3041 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3042 top_p, bot_p, left_p, right_p, &r);
3046 /* Draw the foreground of image glyph string S to PIXMAP. */
3048 static void
3049 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3051 int x = 0;
3052 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3054 /* If first glyph of S has a left box line, start drawing it to the
3055 right of that line. */
3056 if (s->face->box != FACE_NO_BOX
3057 && s->first_glyph->left_box_line_p
3058 && s->slice.x == 0)
3059 x += eabs (s->face->box_line_width);
3061 /* If there is a margin around the image, adjust x- and y-position
3062 by that margin. */
3063 if (s->slice.x == 0)
3064 x += s->img->hmargin;
3065 if (s->slice.y == 0)
3066 y += s->img->vmargin;
3068 if (s->img->pixmap)
3070 if (s->img->mask)
3072 /* We can't set both a clip mask and use XSetClipRectangles
3073 because the latter also sets a clip mask. We also can't
3074 trust on the shape extension to be available
3075 (XShapeCombineRegion). So, compute the rectangle to draw
3076 manually. */
3077 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3078 | GCFunction);
3079 XGCValues xgcv;
3081 xgcv.clip_mask = s->img->mask;
3082 xgcv.clip_x_origin = x - s->slice.x;
3083 xgcv.clip_y_origin = y - s->slice.y;
3084 xgcv.function = GXcopy;
3085 XChangeGC (s->display, s->gc, mask, &xgcv);
3087 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3088 s->slice.x, s->slice.y,
3089 s->slice.width, s->slice.height, x, y);
3090 XSetClipMask (s->display, s->gc, None);
3092 else
3094 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3095 s->slice.x, s->slice.y,
3096 s->slice.width, s->slice.height, x, y);
3098 /* When the image has a mask, we can expect that at
3099 least part of a mouse highlight or a block cursor will
3100 be visible. If the image doesn't have a mask, make
3101 a block cursor visible by drawing a rectangle around
3102 the image. I believe it's looking better if we do
3103 nothing here for mouse-face. */
3104 if (s->hl == DRAW_CURSOR)
3106 int r = eabs (s->img->relief);
3107 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3108 s->slice.width + r*2 - 1,
3109 s->slice.height + r*2 - 1);
3113 else
3114 /* Draw a rectangle if image could not be loaded. */
3115 x_draw_rectangle (s->f, s->gc, x, y,
3116 s->slice.width - 1, s->slice.height - 1);
3120 /* Draw part of the background of glyph string S. X, Y, W, and H
3121 give the rectangle to draw. */
3123 static void
3124 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3126 if (s->stippled_p)
3128 /* Fill background with a stipple pattern. */
3129 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3130 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3131 XSetFillStyle (s->display, s->gc, FillSolid);
3133 else
3134 x_clear_glyph_string_rect (s, x, y, w, h);
3138 /* Draw image glyph string S.
3140 s->y
3141 s->x +-------------------------
3142 | s->face->box
3144 | +-------------------------
3145 | | s->img->margin
3147 | | +-------------------
3148 | | | the image
3152 static void
3153 x_draw_image_glyph_string (struct glyph_string *s)
3155 int box_line_hwidth = eabs (s->face->box_line_width);
3156 int box_line_vwidth = max (s->face->box_line_width, 0);
3157 int height;
3158 Pixmap pixmap = None;
3160 height = s->height;
3161 if (s->slice.y == 0)
3162 height -= box_line_vwidth;
3163 if (s->slice.y + s->slice.height >= s->img->height)
3164 height -= box_line_vwidth;
3166 /* Fill background with face under the image. Do it only if row is
3167 taller than image or if image has a clip mask to reduce
3168 flickering. */
3169 s->stippled_p = s->face->stipple != 0;
3170 if (height > s->slice.height
3171 || s->img->hmargin
3172 || s->img->vmargin
3173 || s->img->mask
3174 || s->img->pixmap == 0
3175 || s->width != s->background_width)
3177 if (s->img->mask)
3179 /* Create a pixmap as large as the glyph string. Fill it
3180 with the background color. Copy the image to it, using
3181 its mask. Copy the temporary pixmap to the display. */
3182 Screen *screen = FRAME_X_SCREEN (s->f);
3183 int depth = DefaultDepthOfScreen (screen);
3185 /* Create a pixmap as large as the glyph string. */
3186 pixmap = XCreatePixmap (s->display, s->window,
3187 s->background_width,
3188 s->height, depth);
3190 /* Don't clip in the following because we're working on the
3191 pixmap. */
3192 XSetClipMask (s->display, s->gc, None);
3194 /* Fill the pixmap with the background color/stipple. */
3195 if (s->stippled_p)
3197 /* Fill background with a stipple pattern. */
3198 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3199 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3200 XFillRectangle (s->display, pixmap, s->gc,
3201 0, 0, s->background_width, s->height);
3202 XSetFillStyle (s->display, s->gc, FillSolid);
3203 XSetTSOrigin (s->display, s->gc, 0, 0);
3205 else
3207 XGCValues xgcv;
3208 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3209 &xgcv);
3210 XSetForeground (s->display, s->gc, xgcv.background);
3211 XFillRectangle (s->display, pixmap, s->gc,
3212 0, 0, s->background_width, s->height);
3213 XSetForeground (s->display, s->gc, xgcv.foreground);
3216 else
3218 int x = s->x;
3219 int y = s->y;
3220 int width = s->background_width;
3222 if (s->first_glyph->left_box_line_p
3223 && s->slice.x == 0)
3225 x += box_line_hwidth;
3226 width -= box_line_hwidth;
3229 if (s->slice.y == 0)
3230 y += box_line_vwidth;
3232 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3235 s->background_filled_p = true;
3238 /* Draw the foreground. */
3239 #ifdef USE_CAIRO
3240 if (s->img->cr_data)
3242 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3244 int x = s->x + s->img->hmargin;
3245 int y = s->y + s->img->vmargin;
3246 int width = s->background_width;
3248 cairo_set_source_surface (cr, s->img->cr_data,
3249 x - s->slice.x,
3250 y - s->slice.y);
3251 cairo_rectangle (cr, x, y, width, height);
3252 cairo_fill (cr);
3253 x_end_cr_clip (s->f);
3255 else
3256 #endif
3257 if (pixmap != None)
3259 x_draw_image_foreground_1 (s, pixmap);
3260 x_set_glyph_string_clipping (s);
3261 XCopyArea (s->display, pixmap, s->window, s->gc,
3262 0, 0, s->background_width, s->height, s->x, s->y);
3263 XFreePixmap (s->display, pixmap);
3265 else
3266 x_draw_image_foreground (s);
3268 /* If we must draw a relief around the image, do it. */
3269 if (s->img->relief
3270 || s->hl == DRAW_IMAGE_RAISED
3271 || s->hl == DRAW_IMAGE_SUNKEN)
3272 x_draw_image_relief (s);
3276 /* Draw stretch glyph string S. */
3278 static void
3279 x_draw_stretch_glyph_string (struct glyph_string *s)
3281 eassert (s->first_glyph->type == STRETCH_GLYPH);
3283 if (s->hl == DRAW_CURSOR
3284 && !x_stretch_cursor_p)
3286 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3287 wide as the stretch glyph. */
3288 int width, background_width = s->background_width;
3289 int x = s->x;
3291 if (!s->row->reversed_p)
3293 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3295 if (x < left_x)
3297 background_width -= left_x - x;
3298 x = left_x;
3301 else
3303 /* In R2L rows, draw the cursor on the right edge of the
3304 stretch glyph. */
3305 int right_x = window_box_right (s->w, TEXT_AREA);
3307 if (x + background_width > right_x)
3308 background_width -= x - right_x;
3309 x += background_width;
3311 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3312 if (s->row->reversed_p)
3313 x -= width;
3315 /* Draw cursor. */
3316 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3318 /* Clear rest using the GC of the original non-cursor face. */
3319 if (width < background_width)
3321 int y = s->y;
3322 int w = background_width - width, h = s->height;
3323 XRectangle r;
3324 GC gc;
3326 if (!s->row->reversed_p)
3327 x += width;
3328 else
3329 x = s->x;
3330 if (s->row->mouse_face_p
3331 && cursor_in_mouse_face_p (s->w))
3333 x_set_mouse_face_gc (s);
3334 gc = s->gc;
3336 else
3337 gc = s->face->gc;
3339 get_glyph_string_clip_rect (s, &r);
3340 x_set_clip_rectangles (s->f, gc, &r, 1);
3342 if (s->face->stipple)
3344 /* Fill background with a stipple pattern. */
3345 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3346 x_fill_rectangle (s->f, gc, x, y, w, h);
3347 XSetFillStyle (s->display, gc, FillSolid);
3349 else
3351 XGCValues xgcv;
3352 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3353 XSetForeground (s->display, gc, xgcv.background);
3354 x_fill_rectangle (s->f, gc, x, y, w, h);
3355 XSetForeground (s->display, gc, xgcv.foreground);
3358 x_reset_clip_rectangles (s->f, gc);
3361 else if (!s->background_filled_p)
3363 int background_width = s->background_width;
3364 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3366 /* Don't draw into left margin, fringe or scrollbar area
3367 except for header line and mode line. */
3368 if (x < left_x && !s->row->mode_line_p)
3370 background_width -= left_x - x;
3371 x = left_x;
3373 if (background_width > 0)
3374 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3377 s->background_filled_p = true;
3381 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3383 x0 wave_length = 2
3385 y0 * * * * *
3386 |* * * * * * * * *
3387 wave_height = 3 | * * * *
3391 static void
3392 x_draw_underwave (struct glyph_string *s)
3394 int wave_height = 3, wave_length = 2;
3395 #ifdef USE_CAIRO
3396 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3397 s->width, wave_height, wave_length);
3398 #else /* not USE_CAIRO */
3399 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3400 bool odd;
3401 XRectangle wave_clip, string_clip, final_clip;
3403 dx = wave_length;
3404 dy = wave_height - 1;
3405 x0 = s->x;
3406 y0 = s->ybase - wave_height + 3;
3407 width = s->width;
3408 xmax = x0 + width;
3410 /* Find and set clipping rectangle */
3412 wave_clip.x = x0;
3413 wave_clip.y = y0;
3414 wave_clip.width = width;
3415 wave_clip.height = wave_height;
3416 get_glyph_string_clip_rect (s, &string_clip);
3418 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3419 return;
3421 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3423 /* Draw the waves */
3425 x1 = x0 - (x0 % dx);
3426 x2 = x1 + dx;
3427 odd = (x1 / dx) & 1;
3428 y1 = y2 = y0;
3430 if (odd)
3431 y1 += dy;
3432 else
3433 y2 += dy;
3435 if (INT_MAX - dx < xmax)
3436 emacs_abort ();
3438 while (x1 <= xmax)
3440 XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
3441 x1 = x2, y1 = y2;
3442 x2 += dx, y2 = y0 + odd*dy;
3443 odd = !odd;
3446 /* Restore previous clipping rectangle(s) */
3447 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3448 #endif /* not USE_CAIRO */
3452 /* Draw glyph string S. */
3454 static void
3455 x_draw_glyph_string (struct glyph_string *s)
3457 bool relief_drawn_p = false;
3459 /* If S draws into the background of its successors, draw the
3460 background of the successors first so that S can draw into it.
3461 This makes S->next use XDrawString instead of XDrawImageString. */
3462 if (s->next && s->right_overhang && !s->for_overlaps)
3464 int width;
3465 struct glyph_string *next;
3467 for (width = 0, next = s->next;
3468 next && width < s->right_overhang;
3469 width += next->width, next = next->next)
3470 if (next->first_glyph->type != IMAGE_GLYPH)
3472 x_set_glyph_string_gc (next);
3473 x_set_glyph_string_clipping (next);
3474 if (next->first_glyph->type == STRETCH_GLYPH)
3475 x_draw_stretch_glyph_string (next);
3476 else
3477 x_draw_glyph_string_background (next, true);
3478 next->num_clips = 0;
3482 /* Set up S->gc, set clipping and draw S. */
3483 x_set_glyph_string_gc (s);
3485 /* Draw relief (if any) in advance for char/composition so that the
3486 glyph string can be drawn over it. */
3487 if (!s->for_overlaps
3488 && s->face->box != FACE_NO_BOX
3489 && (s->first_glyph->type == CHAR_GLYPH
3490 || s->first_glyph->type == COMPOSITE_GLYPH))
3493 x_set_glyph_string_clipping (s);
3494 x_draw_glyph_string_background (s, true);
3495 x_draw_glyph_string_box (s);
3496 x_set_glyph_string_clipping (s);
3497 relief_drawn_p = true;
3499 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3500 && !s->clip_tail
3501 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3502 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3503 /* We must clip just this glyph. left_overhang part has already
3504 drawn when s->prev was drawn, and right_overhang part will be
3505 drawn later when s->next is drawn. */
3506 x_set_glyph_string_clipping_exactly (s, s);
3507 else
3508 x_set_glyph_string_clipping (s);
3510 switch (s->first_glyph->type)
3512 case IMAGE_GLYPH:
3513 x_draw_image_glyph_string (s);
3514 break;
3516 case XWIDGET_GLYPH:
3517 x_draw_xwidget_glyph_string (s);
3518 break;
3520 case STRETCH_GLYPH:
3521 x_draw_stretch_glyph_string (s);
3522 break;
3524 case CHAR_GLYPH:
3525 if (s->for_overlaps)
3526 s->background_filled_p = true;
3527 else
3528 x_draw_glyph_string_background (s, false);
3529 x_draw_glyph_string_foreground (s);
3530 break;
3532 case COMPOSITE_GLYPH:
3533 if (s->for_overlaps || (s->cmp_from > 0
3534 && ! s->first_glyph->u.cmp.automatic))
3535 s->background_filled_p = true;
3536 else
3537 x_draw_glyph_string_background (s, true);
3538 x_draw_composite_glyph_string_foreground (s);
3539 break;
3541 case GLYPHLESS_GLYPH:
3542 if (s->for_overlaps)
3543 s->background_filled_p = true;
3544 else
3545 x_draw_glyph_string_background (s, true);
3546 x_draw_glyphless_glyph_string_foreground (s);
3547 break;
3549 default:
3550 emacs_abort ();
3553 if (!s->for_overlaps)
3555 /* Draw underline. */
3556 if (s->face->underline_p)
3558 if (s->face->underline_type == FACE_UNDER_WAVE)
3560 if (s->face->underline_defaulted_p)
3561 x_draw_underwave (s);
3562 else
3564 XGCValues xgcv;
3565 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3566 XSetForeground (s->display, s->gc, s->face->underline_color);
3567 x_draw_underwave (s);
3568 XSetForeground (s->display, s->gc, xgcv.foreground);
3571 else if (s->face->underline_type == FACE_UNDER_LINE)
3573 unsigned long thickness, position;
3574 int y;
3576 if (s->prev && s->prev->face->underline_p
3577 && s->prev->face->underline_type == FACE_UNDER_LINE)
3579 /* We use the same underline style as the previous one. */
3580 thickness = s->prev->underline_thickness;
3581 position = s->prev->underline_position;
3583 else
3585 /* Get the underline thickness. Default is 1 pixel. */
3586 if (s->font && s->font->underline_thickness > 0)
3587 thickness = s->font->underline_thickness;
3588 else
3589 thickness = 1;
3590 if (x_underline_at_descent_line)
3591 position = (s->height - thickness) - (s->ybase - s->y);
3592 else
3594 /* Get the underline position. This is the recommended
3595 vertical offset in pixels from the baseline to the top of
3596 the underline. This is a signed value according to the
3597 specs, and its default is
3599 ROUND ((maximum descent) / 2), with
3600 ROUND(x) = floor (x + 0.5) */
3602 if (x_use_underline_position_properties
3603 && s->font && s->font->underline_position >= 0)
3604 position = s->font->underline_position;
3605 else if (s->font)
3606 position = (s->font->descent + 1) / 2;
3607 else
3608 position = underline_minimum_offset;
3610 position = max (position, underline_minimum_offset);
3612 /* Check the sanity of thickness and position. We should
3613 avoid drawing underline out of the current line area. */
3614 if (s->y + s->height <= s->ybase + position)
3615 position = (s->height - 1) - (s->ybase - s->y);
3616 if (s->y + s->height < s->ybase + position + thickness)
3617 thickness = (s->y + s->height) - (s->ybase + position);
3618 s->underline_thickness = thickness;
3619 s->underline_position = position;
3620 y = s->ybase + position;
3621 if (s->face->underline_defaulted_p)
3622 x_fill_rectangle (s->f, s->gc,
3623 s->x, y, s->width, thickness);
3624 else
3626 XGCValues xgcv;
3627 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3628 XSetForeground (s->display, s->gc, s->face->underline_color);
3629 x_fill_rectangle (s->f, s->gc,
3630 s->x, y, s->width, thickness);
3631 XSetForeground (s->display, s->gc, xgcv.foreground);
3635 /* Draw overline. */
3636 if (s->face->overline_p)
3638 unsigned long dy = 0, h = 1;
3640 if (s->face->overline_color_defaulted_p)
3641 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3642 s->width, h);
3643 else
3645 XGCValues xgcv;
3646 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3647 XSetForeground (s->display, s->gc, s->face->overline_color);
3648 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3649 s->width, h);
3650 XSetForeground (s->display, s->gc, xgcv.foreground);
3654 /* Draw strike-through. */
3655 if (s->face->strike_through_p)
3657 unsigned long h = 1;
3658 unsigned long dy = (s->height - h) / 2;
3660 if (s->face->strike_through_color_defaulted_p)
3661 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3662 s->width, h);
3663 else
3665 XGCValues xgcv;
3666 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3667 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3668 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3669 s->width, h);
3670 XSetForeground (s->display, s->gc, xgcv.foreground);
3674 /* Draw relief if not yet drawn. */
3675 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3676 x_draw_glyph_string_box (s);
3678 if (s->prev)
3680 struct glyph_string *prev;
3682 for (prev = s->prev; prev; prev = prev->prev)
3683 if (prev->hl != s->hl
3684 && prev->x + prev->width + prev->right_overhang > s->x)
3686 /* As prev was drawn while clipped to its own area, we
3687 must draw the right_overhang part using s->hl now. */
3688 enum draw_glyphs_face save = prev->hl;
3690 prev->hl = s->hl;
3691 x_set_glyph_string_gc (prev);
3692 x_set_glyph_string_clipping_exactly (s, prev);
3693 if (prev->first_glyph->type == CHAR_GLYPH)
3694 x_draw_glyph_string_foreground (prev);
3695 else
3696 x_draw_composite_glyph_string_foreground (prev);
3697 x_reset_clip_rectangles (prev->f, prev->gc);
3698 prev->hl = save;
3699 prev->num_clips = 0;
3703 if (s->next)
3705 struct glyph_string *next;
3707 for (next = s->next; next; next = next->next)
3708 if (next->hl != s->hl
3709 && next->x - next->left_overhang < s->x + s->width)
3711 /* As next will be drawn while clipped to its own area,
3712 we must draw the left_overhang part using s->hl now. */
3713 enum draw_glyphs_face save = next->hl;
3715 next->hl = s->hl;
3716 x_set_glyph_string_gc (next);
3717 x_set_glyph_string_clipping_exactly (s, next);
3718 if (next->first_glyph->type == CHAR_GLYPH)
3719 x_draw_glyph_string_foreground (next);
3720 else
3721 x_draw_composite_glyph_string_foreground (next);
3722 x_reset_clip_rectangles (next->f, next->gc);
3723 next->hl = save;
3724 next->num_clips = 0;
3725 next->clip_head = s->next;
3730 /* Reset clipping. */
3731 x_reset_clip_rectangles (s->f, s->gc);
3732 s->num_clips = 0;
3735 /* Shift display to make room for inserted glyphs. */
3737 static void
3738 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3740 /* Never called on a GUI frame, see
3741 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3743 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
3744 f->output_data.x->normal_gc,
3745 x, y, width, height,
3746 x + shift_by, y);
3749 /* Delete N glyphs at the nominal cursor position. Not implemented
3750 for X frames. */
3752 static void
3753 x_delete_glyphs (struct frame *f, register int n)
3755 emacs_abort ();
3759 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3760 If they are <= 0, this is probably an error. */
3762 static ATTRIBUTE_UNUSED void
3763 x_clear_area1 (Display *dpy, Window window,
3764 int x, int y, int width, int height, int exposures)
3766 eassert (width > 0 && height > 0);
3767 XClearArea (dpy, window, x, y, width, height, exposures);
3770 void
3771 x_clear_area (struct frame *f, int x, int y, int width, int height)
3773 #ifdef USE_CAIRO
3774 cairo_t *cr;
3776 eassert (width > 0 && height > 0);
3778 cr = x_begin_cr_clip (f, NULL);
3779 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3780 cairo_rectangle (cr, x, y, width, height);
3781 cairo_fill (cr);
3782 x_end_cr_clip (f);
3783 #else
3784 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3785 x, y, width, height, False);
3786 #endif
3790 /* Clear an entire frame. */
3792 static void
3793 x_clear_frame (struct frame *f)
3795 /* Clearing the frame will erase any cursor, so mark them all as no
3796 longer visible. */
3797 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3799 block_input ();
3801 x_clear_window (f);
3803 /* We have to clear the scroll bars. If we have changed colors or
3804 something like that, then they should be notified. */
3805 x_scroll_bar_clear (f);
3807 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3808 /* Make sure scroll bars are redrawn. As they aren't redrawn by
3809 redisplay, do it here. */
3810 if (FRAME_GTK_WIDGET (f))
3811 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
3812 #endif
3814 XFlush (FRAME_X_DISPLAY (f));
3816 unblock_input ();
3819 /* RIF: Show hourglass cursor on frame F. */
3821 static void
3822 x_show_hourglass (struct frame *f)
3824 Display *dpy = FRAME_X_DISPLAY (f);
3826 if (dpy)
3828 struct x_output *x = FRAME_X_OUTPUT (f);
3829 #ifdef USE_X_TOOLKIT
3830 if (x->widget)
3831 #else
3832 if (FRAME_OUTER_WINDOW (f))
3833 #endif
3835 x->hourglass_p = true;
3837 if (!x->hourglass_window)
3839 unsigned long mask = CWCursor;
3840 XSetWindowAttributes attrs;
3841 #ifdef USE_GTK
3842 Window parent = FRAME_X_WINDOW (f);
3843 #else
3844 Window parent = FRAME_OUTER_WINDOW (f);
3845 #endif
3846 attrs.cursor = x->hourglass_cursor;
3848 x->hourglass_window = XCreateWindow
3849 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3850 InputOnly, CopyFromParent, mask, &attrs);
3853 XMapRaised (dpy, x->hourglass_window);
3854 XFlush (dpy);
3859 /* RIF: Cancel hourglass cursor on frame F. */
3861 static void
3862 x_hide_hourglass (struct frame *f)
3864 struct x_output *x = FRAME_X_OUTPUT (f);
3866 /* Watch out for newly created frames. */
3867 if (x->hourglass_window)
3869 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3870 /* Sync here because XTread_socket looks at the
3871 hourglass_p flag that is reset to zero below. */
3872 XSync (FRAME_X_DISPLAY (f), False);
3873 x->hourglass_p = false;
3877 /* Invert the middle quarter of the frame for .15 sec. */
3879 static void
3880 XTflash (struct frame *f)
3882 block_input ();
3885 #ifdef USE_GTK
3886 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3887 when the scroll bars and the edit widget share the same X window. */
3888 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3889 #ifdef HAVE_GTK3
3890 cairo_t *cr = gdk_cairo_create (window);
3891 cairo_set_source_rgb (cr, 1, 1, 1);
3892 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
3893 #define XFillRectangle(d, win, gc, x, y, w, h) \
3894 do { \
3895 cairo_rectangle (cr, x, y, w, h); \
3896 cairo_fill (cr); \
3898 while (false)
3899 #else /* ! HAVE_GTK3 */
3900 GdkGCValues vals;
3901 GdkGC *gc;
3902 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
3903 ^ FRAME_BACKGROUND_PIXEL (f));
3904 vals.function = GDK_XOR;
3905 gc = gdk_gc_new_with_values (window,
3906 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
3907 #define XFillRectangle(d, win, gc, x, y, w, h) \
3908 gdk_draw_rectangle (window, gc, true, x, y, w, h)
3909 #endif /* ! HAVE_GTK3 */
3910 #else /* ! USE_GTK */
3911 GC gc;
3913 /* Create a GC that will use the GXxor function to flip foreground
3914 pixels into background pixels. */
3916 XGCValues values;
3918 values.function = GXxor;
3919 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
3920 ^ FRAME_BACKGROUND_PIXEL (f));
3922 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3923 GCFunction | GCForeground, &values);
3925 #endif
3927 /* Get the height not including a menu bar widget. */
3928 int height = FRAME_PIXEL_HEIGHT (f);
3929 /* Height of each line to flash. */
3930 int flash_height = FRAME_LINE_HEIGHT (f);
3931 /* These will be the left and right margins of the rectangles. */
3932 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3933 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3934 int width = flash_right - flash_left;
3936 /* If window is tall, flash top and bottom line. */
3937 if (height > 3 * FRAME_LINE_HEIGHT (f))
3939 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3940 flash_left,
3941 (FRAME_INTERNAL_BORDER_WIDTH (f)
3942 + FRAME_TOP_MARGIN_HEIGHT (f)),
3943 width, flash_height);
3944 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3945 flash_left,
3946 (height - flash_height
3947 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3948 width, flash_height);
3951 else
3952 /* If it is short, flash it all. */
3953 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3954 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3955 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3957 x_flush (f);
3960 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
3961 struct timespec wakeup = timespec_add (current_timespec (), delay);
3963 /* Keep waiting until past the time wakeup or any input gets
3964 available. */
3965 while (! detect_input_pending ())
3967 struct timespec current = current_timespec ();
3968 struct timespec timeout;
3970 /* Break if result would not be positive. */
3971 if (timespec_cmp (wakeup, current) <= 0)
3972 break;
3974 /* How long `select' should wait. */
3975 timeout = make_timespec (0, 10 * 1000 * 1000);
3977 /* Try to wait that long--but we might wake up sooner. */
3978 pselect (0, NULL, NULL, NULL, &timeout, NULL);
3982 /* If window is tall, flash top and bottom line. */
3983 if (height > 3 * FRAME_LINE_HEIGHT (f))
3985 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3986 flash_left,
3987 (FRAME_INTERNAL_BORDER_WIDTH (f)
3988 + FRAME_TOP_MARGIN_HEIGHT (f)),
3989 width, flash_height);
3990 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3991 flash_left,
3992 (height - flash_height
3993 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3994 width, flash_height);
3996 else
3997 /* If it is short, flash it all. */
3998 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3999 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4000 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4002 #ifdef USE_GTK
4003 #ifdef HAVE_GTK3
4004 cairo_destroy (cr);
4005 #else
4006 g_object_unref (G_OBJECT (gc));
4007 #endif
4008 #undef XFillRectangle
4009 #else
4010 XFreeGC (FRAME_X_DISPLAY (f), gc);
4011 #endif
4012 x_flush (f);
4016 unblock_input ();
4020 static void
4021 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4023 block_input ();
4024 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4025 unblock_input ();
4029 /* Make audible bell. */
4031 static void
4032 XTring_bell (struct frame *f)
4034 if (FRAME_X_DISPLAY (f))
4036 if (visible_bell)
4037 XTflash (f);
4038 else
4040 block_input ();
4041 #ifdef HAVE_XKB
4042 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4043 #else
4044 XBell (FRAME_X_DISPLAY (f), 0);
4045 #endif
4046 XFlush (FRAME_X_DISPLAY (f));
4047 unblock_input ();
4052 /***********************************************************************
4053 Line Dance
4054 ***********************************************************************/
4056 /* Perform an insert-lines or delete-lines operation, inserting N
4057 lines or deleting -N lines at vertical position VPOS. */
4059 static void
4060 x_ins_del_lines (struct frame *f, int vpos, int n)
4062 emacs_abort ();
4066 /* Scroll part of the display as described by RUN. */
4068 static void
4069 x_scroll_run (struct window *w, struct run *run)
4071 struct frame *f = XFRAME (w->frame);
4072 int x, y, width, height, from_y, to_y, bottom_y;
4074 /* Get frame-relative bounding box of the text display area of W,
4075 without mode lines. Include in this box the left and right
4076 fringe of W. */
4077 window_box (w, ANY_AREA, &x, &y, &width, &height);
4079 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4080 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4081 bottom_y = y + height;
4083 if (to_y < from_y)
4085 /* Scrolling up. Make sure we don't copy part of the mode
4086 line at the bottom. */
4087 if (from_y + run->height > bottom_y)
4088 height = bottom_y - from_y;
4089 else
4090 height = run->height;
4092 else
4094 /* Scrolling down. Make sure we don't copy over the mode line.
4095 at the bottom. */
4096 if (to_y + run->height > bottom_y)
4097 height = bottom_y - to_y;
4098 else
4099 height = run->height;
4102 block_input ();
4104 /* Cursor off. Will be switched on again in x_update_window_end. */
4105 x_clear_cursor (w);
4107 #ifdef USE_CAIRO
4108 SET_FRAME_GARBAGED (f);
4109 #else
4110 XCopyArea (FRAME_X_DISPLAY (f),
4111 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
4112 f->output_data.x->normal_gc,
4113 x, from_y,
4114 width, height,
4115 x, to_y);
4116 #endif
4118 unblock_input ();
4123 /***********************************************************************
4124 Exposure Events
4125 ***********************************************************************/
4128 static void
4129 frame_highlight (struct frame *f)
4131 /* We used to only do this if Vx_no_window_manager was non-nil, but
4132 the ICCCM (section 4.1.6) says that the window's border pixmap
4133 and border pixel are window attributes which are "private to the
4134 client", so we can always change it to whatever we want. */
4135 block_input ();
4136 /* I recently started to get errors in this XSetWindowBorder, depending on
4137 the window-manager in use, tho something more is at play since I've been
4138 using that same window-manager binary for ever. Let's not crash just
4139 because of this (bug#9310). */
4140 x_catch_errors (FRAME_X_DISPLAY (f));
4141 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4142 f->output_data.x->border_pixel);
4143 x_uncatch_errors ();
4144 unblock_input ();
4145 x_update_cursor (f, true);
4146 x_set_frame_alpha (f);
4149 static void
4150 frame_unhighlight (struct frame *f)
4152 /* We used to only do this if Vx_no_window_manager was non-nil, but
4153 the ICCCM (section 4.1.6) says that the window's border pixmap
4154 and border pixel are window attributes which are "private to the
4155 client", so we can always change it to whatever we want. */
4156 block_input ();
4157 /* Same as above for XSetWindowBorder (bug#9310). */
4158 x_catch_errors (FRAME_X_DISPLAY (f));
4159 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4160 f->output_data.x->border_tile);
4161 x_uncatch_errors ();
4162 unblock_input ();
4163 x_update_cursor (f, true);
4164 x_set_frame_alpha (f);
4167 /* The focus has changed. Update the frames as necessary to reflect
4168 the new situation. Note that we can't change the selected frame
4169 here, because the Lisp code we are interrupting might become confused.
4170 Each event gets marked with the frame in which it occurred, so the
4171 Lisp code can tell when the switch took place by examining the events. */
4173 static void
4174 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4176 struct frame *old_focus = dpyinfo->x_focus_frame;
4178 if (frame != dpyinfo->x_focus_frame)
4180 /* Set this before calling other routines, so that they see
4181 the correct value of x_focus_frame. */
4182 dpyinfo->x_focus_frame = frame;
4184 if (old_focus && old_focus->auto_lower)
4185 x_lower_frame (old_focus);
4187 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4188 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4189 else
4190 dpyinfo->x_pending_autoraise_frame = NULL;
4193 x_frame_rehighlight (dpyinfo);
4196 /* Handle FocusIn and FocusOut state changes for FRAME.
4197 If FRAME has focus and there exists more than one frame, puts
4198 a FOCUS_IN_EVENT into *BUFP. */
4200 static void
4201 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4203 if (type == FocusIn)
4205 if (dpyinfo->x_focus_event_frame != frame)
4207 x_new_focus_frame (dpyinfo, frame);
4208 dpyinfo->x_focus_event_frame = frame;
4210 /* Don't stop displaying the initial startup message
4211 for a switch-frame event we don't need. */
4212 /* When run as a daemon, Vterminal_frame is always NIL. */
4213 bufp->arg = (((NILP (Vterminal_frame)
4214 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4215 || EQ (Fdaemonp (), Qt))
4216 && CONSP (Vframe_list)
4217 && !NILP (XCDR (Vframe_list)))
4218 ? Qt : Qnil);
4219 bufp->kind = FOCUS_IN_EVENT;
4220 XSETFRAME (bufp->frame_or_window, frame);
4223 frame->output_data.x->focus_state |= state;
4225 #ifdef HAVE_X_I18N
4226 if (FRAME_XIC (frame))
4227 XSetICFocus (FRAME_XIC (frame));
4228 #endif
4230 else if (type == FocusOut)
4232 frame->output_data.x->focus_state &= ~state;
4234 if (dpyinfo->x_focus_event_frame == frame)
4236 dpyinfo->x_focus_event_frame = 0;
4237 x_new_focus_frame (dpyinfo, 0);
4239 bufp->kind = FOCUS_OUT_EVENT;
4240 XSETFRAME (bufp->frame_or_window, frame);
4243 #ifdef HAVE_X_I18N
4244 if (FRAME_XIC (frame))
4245 XUnsetICFocus (FRAME_XIC (frame));
4246 #endif
4247 if (frame->pointer_invisible)
4248 XTtoggle_invisible_pointer (frame, false);
4252 /* Return the Emacs frame-object corresponding to an X window.
4253 It could be the frame's main window or an icon window. */
4255 static struct frame *
4256 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4258 Lisp_Object tail, frame;
4259 struct frame *f;
4261 if (wdesc == None)
4262 return NULL;
4264 FOR_EACH_FRAME (tail, frame)
4266 f = XFRAME (frame);
4267 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4268 continue;
4269 if (f->output_data.x->hourglass_window == wdesc)
4270 return f;
4271 #ifdef USE_X_TOOLKIT
4272 if ((f->output_data.x->edit_widget
4273 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4274 /* A tooltip frame? */
4275 || (!f->output_data.x->edit_widget
4276 && FRAME_X_WINDOW (f) == wdesc)
4277 || f->output_data.x->icon_desc == wdesc)
4278 return f;
4279 #else /* not USE_X_TOOLKIT */
4280 #ifdef USE_GTK
4281 if (f->output_data.x->edit_widget)
4283 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4284 struct x_output *x = f->output_data.x;
4285 if (gwdesc != 0 && gwdesc == x->edit_widget)
4286 return f;
4288 #endif /* USE_GTK */
4289 if (FRAME_X_WINDOW (f) == wdesc
4290 || f->output_data.x->icon_desc == wdesc)
4291 return f;
4292 #endif /* not USE_X_TOOLKIT */
4294 return 0;
4297 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4299 /* Like x_window_to_frame but also compares the window with the widget's
4300 windows. */
4302 static struct frame *
4303 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4305 Lisp_Object tail, frame;
4306 struct frame *f, *found = NULL;
4307 struct x_output *x;
4309 if (wdesc == None)
4310 return NULL;
4312 FOR_EACH_FRAME (tail, frame)
4314 if (found)
4315 break;
4316 f = XFRAME (frame);
4317 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4319 /* This frame matches if the window is any of its widgets. */
4320 x = f->output_data.x;
4321 if (x->hourglass_window == wdesc)
4322 found = f;
4323 else if (x->widget)
4325 #ifdef USE_GTK
4326 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4327 if (gwdesc != 0
4328 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4329 found = f;
4330 #else
4331 if (wdesc == XtWindow (x->widget)
4332 || wdesc == XtWindow (x->column_widget)
4333 || wdesc == XtWindow (x->edit_widget))
4334 found = f;
4335 /* Match if the window is this frame's menubar. */
4336 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4337 found = f;
4338 #endif
4340 else if (FRAME_X_WINDOW (f) == wdesc)
4341 /* A tooltip frame. */
4342 found = f;
4346 return found;
4349 /* Likewise, but consider only the menu bar widget. */
4351 static struct frame *
4352 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4353 const XEvent *event)
4355 Window wdesc = event->xany.window;
4356 Lisp_Object tail, frame;
4357 struct frame *f;
4358 struct x_output *x;
4360 if (wdesc == None)
4361 return NULL;
4363 FOR_EACH_FRAME (tail, frame)
4365 f = XFRAME (frame);
4366 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4367 continue;
4368 x = f->output_data.x;
4369 #ifdef USE_GTK
4370 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4371 return f;
4372 #else
4373 /* Match if the window is this frame's menubar. */
4374 if (x->menubar_widget
4375 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4376 return f;
4377 #endif
4379 return 0;
4382 /* Return the frame whose principal (outermost) window is WDESC.
4383 If WDESC is some other (smaller) window, we return 0. */
4385 struct frame *
4386 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4388 Lisp_Object tail, frame;
4389 struct frame *f;
4390 struct x_output *x;
4392 if (wdesc == None)
4393 return NULL;
4395 FOR_EACH_FRAME (tail, frame)
4397 f = XFRAME (frame);
4398 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4399 continue;
4400 x = f->output_data.x;
4402 if (x->widget)
4404 /* This frame matches if the window is its topmost widget. */
4405 #ifdef USE_GTK
4406 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4407 if (gwdesc == x->widget)
4408 return f;
4409 #else
4410 if (wdesc == XtWindow (x->widget))
4411 return f;
4412 #endif
4414 else if (FRAME_X_WINDOW (f) == wdesc)
4415 /* Tooltip frame. */
4416 return f;
4418 return 0;
4421 #else /* !USE_X_TOOLKIT && !USE_GTK */
4423 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4424 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4426 #endif /* USE_X_TOOLKIT || USE_GTK */
4428 /* The focus may have changed. Figure out if it is a real focus change,
4429 by checking both FocusIn/Out and Enter/LeaveNotify events.
4431 Returns FOCUS_IN_EVENT event in *BUFP. */
4433 static void
4434 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4435 const XEvent *event, struct input_event *bufp)
4437 if (!frame)
4438 return;
4440 switch (event->type)
4442 case EnterNotify:
4443 case LeaveNotify:
4445 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4446 int focus_state
4447 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4449 if (event->xcrossing.detail != NotifyInferior
4450 && event->xcrossing.focus
4451 && ! (focus_state & FOCUS_EXPLICIT))
4452 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4453 FOCUS_IMPLICIT,
4454 dpyinfo, frame, bufp);
4456 break;
4458 case FocusIn:
4459 case FocusOut:
4460 x_focus_changed (event->type,
4461 (event->xfocus.detail == NotifyPointer ?
4462 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4463 dpyinfo, frame, bufp);
4464 break;
4466 case ClientMessage:
4467 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4469 enum xembed_message msg = event->xclient.data.l[1];
4470 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4471 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4473 break;
4478 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4479 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4481 void
4482 x_mouse_leave (struct x_display_info *dpyinfo)
4484 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4486 #endif
4488 /* The focus has changed, or we have redirected a frame's focus to
4489 another frame (this happens when a frame uses a surrogate
4490 mini-buffer frame). Shift the highlight as appropriate.
4492 The FRAME argument doesn't necessarily have anything to do with which
4493 frame is being highlighted or un-highlighted; we only use it to find
4494 the appropriate X display info. */
4496 static void
4497 XTframe_rehighlight (struct frame *frame)
4499 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4502 static void
4503 x_frame_rehighlight (struct x_display_info *dpyinfo)
4505 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4507 if (dpyinfo->x_focus_frame)
4509 dpyinfo->x_highlight_frame
4510 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4511 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4512 : dpyinfo->x_focus_frame);
4513 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4515 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4516 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4519 else
4520 dpyinfo->x_highlight_frame = 0;
4522 if (dpyinfo->x_highlight_frame != old_highlight)
4524 if (old_highlight)
4525 frame_unhighlight (old_highlight);
4526 if (dpyinfo->x_highlight_frame)
4527 frame_highlight (dpyinfo->x_highlight_frame);
4533 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4535 /* Initialize mode_switch_bit and modifier_meaning. */
4536 static void
4537 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4539 int min_code, max_code;
4540 KeySym *syms;
4541 int syms_per_code;
4542 XModifierKeymap *mods;
4544 dpyinfo->meta_mod_mask = 0;
4545 dpyinfo->shift_lock_mask = 0;
4546 dpyinfo->alt_mod_mask = 0;
4547 dpyinfo->super_mod_mask = 0;
4548 dpyinfo->hyper_mod_mask = 0;
4550 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4552 syms = XGetKeyboardMapping (dpyinfo->display,
4553 min_code, max_code - min_code + 1,
4554 &syms_per_code);
4555 mods = XGetModifierMapping (dpyinfo->display);
4557 /* Scan the modifier table to see which modifier bits the Meta and
4558 Alt keysyms are on. */
4560 int row, col; /* The row and column in the modifier table. */
4561 bool found_alt_or_meta;
4563 for (row = 3; row < 8; row++)
4565 found_alt_or_meta = false;
4566 for (col = 0; col < mods->max_keypermod; col++)
4568 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4570 /* Zeroes are used for filler. Skip them. */
4571 if (code == 0)
4572 continue;
4574 /* Are any of this keycode's keysyms a meta key? */
4576 int code_col;
4578 for (code_col = 0; code_col < syms_per_code; code_col++)
4580 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4582 switch (sym)
4584 case XK_Meta_L:
4585 case XK_Meta_R:
4586 found_alt_or_meta = true;
4587 dpyinfo->meta_mod_mask |= (1 << row);
4588 break;
4590 case XK_Alt_L:
4591 case XK_Alt_R:
4592 found_alt_or_meta = true;
4593 dpyinfo->alt_mod_mask |= (1 << row);
4594 break;
4596 case XK_Hyper_L:
4597 case XK_Hyper_R:
4598 if (!found_alt_or_meta)
4599 dpyinfo->hyper_mod_mask |= (1 << row);
4600 code_col = syms_per_code;
4601 col = mods->max_keypermod;
4602 break;
4604 case XK_Super_L:
4605 case XK_Super_R:
4606 if (!found_alt_or_meta)
4607 dpyinfo->super_mod_mask |= (1 << row);
4608 code_col = syms_per_code;
4609 col = mods->max_keypermod;
4610 break;
4612 case XK_Shift_Lock:
4613 /* Ignore this if it's not on the lock modifier. */
4614 if (!found_alt_or_meta && ((1 << row) == LockMask))
4615 dpyinfo->shift_lock_mask = LockMask;
4616 code_col = syms_per_code;
4617 col = mods->max_keypermod;
4618 break;
4626 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4627 if (! dpyinfo->meta_mod_mask)
4629 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4630 dpyinfo->alt_mod_mask = 0;
4633 /* If some keys are both alt and meta,
4634 make them just meta, not alt. */
4635 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4637 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4640 XFree (syms);
4641 XFreeModifiermap (mods);
4644 /* Convert between the modifier bits X uses and the modifier bits
4645 Emacs uses. */
4648 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4650 int mod_meta = meta_modifier;
4651 int mod_alt = alt_modifier;
4652 int mod_hyper = hyper_modifier;
4653 int mod_super = super_modifier;
4654 Lisp_Object tem;
4656 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4657 if (INTEGERP (tem)) mod_alt = XINT (tem) & INT_MAX;
4658 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4659 if (INTEGERP (tem)) mod_meta = XINT (tem) & INT_MAX;
4660 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4661 if (INTEGERP (tem)) mod_hyper = XINT (tem) & INT_MAX;
4662 tem = Fget (Vx_super_keysym, Qmodifier_value);
4663 if (INTEGERP (tem)) mod_super = XINT (tem) & INT_MAX;
4665 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
4666 | ((state & ControlMask) ? ctrl_modifier : 0)
4667 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
4668 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
4669 | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
4670 | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
4673 static int
4674 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
4676 EMACS_INT mod_meta = meta_modifier;
4677 EMACS_INT mod_alt = alt_modifier;
4678 EMACS_INT mod_hyper = hyper_modifier;
4679 EMACS_INT mod_super = super_modifier;
4681 Lisp_Object tem;
4683 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4684 if (INTEGERP (tem)) mod_alt = XINT (tem);
4685 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4686 if (INTEGERP (tem)) mod_meta = XINT (tem);
4687 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4688 if (INTEGERP (tem)) mod_hyper = XINT (tem);
4689 tem = Fget (Vx_super_keysym, Qmodifier_value);
4690 if (INTEGERP (tem)) mod_super = XINT (tem);
4693 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0)
4694 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0)
4695 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0)
4696 | ((state & shift_modifier) ? ShiftMask : 0)
4697 | ((state & ctrl_modifier) ? ControlMask : 0)
4698 | ((state & mod_meta) ? dpyinfo->meta_mod_mask : 0));
4701 /* Convert a keysym to its name. */
4703 char *
4704 x_get_keysym_name (int keysym)
4706 char *value;
4708 block_input ();
4709 value = XKeysymToString (keysym);
4710 unblock_input ();
4712 return value;
4715 /* Mouse clicks and mouse movement. Rah.
4717 Formerly, we used PointerMotionHintMask (in standard_event_mask)
4718 so that we would have to call XQueryPointer after each MotionNotify
4719 event to ask for another such event. However, this made mouse tracking
4720 slow, and there was a bug that made it eventually stop.
4722 Simply asking for MotionNotify all the time seems to work better.
4724 In order to avoid asking for motion events and then throwing most
4725 of them away or busy-polling the server for mouse positions, we ask
4726 the server for pointer motion hints. This means that we get only
4727 one event per group of mouse movements. "Groups" are delimited by
4728 other kinds of events (focus changes and button clicks, for
4729 example), or by XQueryPointer calls; when one of these happens, we
4730 get another MotionNotify event the next time the mouse moves. This
4731 is at least as efficient as getting motion events when mouse
4732 tracking is on, and I suspect only negligibly worse when tracking
4733 is off. */
4735 /* Prepare a mouse-event in *RESULT for placement in the input queue.
4737 If the event is a button press, then note that we have grabbed
4738 the mouse. */
4740 static Lisp_Object
4741 construct_mouse_click (struct input_event *result,
4742 const XButtonEvent *event,
4743 struct frame *f)
4745 /* Make the event type NO_EVENT; we'll change that when we decide
4746 otherwise. */
4747 result->kind = MOUSE_CLICK_EVENT;
4748 result->code = event->button - Button1;
4749 result->timestamp = event->time;
4750 result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
4751 event->state)
4752 | (event->type == ButtonRelease
4753 ? up_modifier
4754 : down_modifier));
4756 XSETINT (result->x, event->x);
4757 XSETINT (result->y, event->y);