Set :version of 'debugger-stack-frame-as-list'
[emacs.git] / src / xterm.c
blob747669446f57bb51dcd1642f94106cee33a6b0bc
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 #include <stdlib.h>
26 #ifdef USE_CAIRO
27 #include <math.h>
28 #endif
30 #include "lisp.h"
31 #include "blockinput.h"
33 /* This may include sys/types.h, and that somehow loses
34 if this is not done before the other system files. */
35 #include "xterm.h"
36 #include <X11/cursorfont.h>
38 /* If we have Xfixes extension, use it for pointer blanking. */
39 #ifdef HAVE_XFIXES
40 #include <X11/extensions/Xfixes.h>
41 #endif
43 /* Using Xft implies that XRender is available. */
44 #ifdef HAVE_XFT
45 #include <X11/extensions/Xrender.h>
46 #endif
48 /* Load sys/types.h if not already loaded.
49 In some systems loading it twice is suicidal. */
50 #ifndef makedev
51 #include <sys/types.h>
52 #endif /* makedev */
54 #include <sys/ioctl.h>
56 #include "systime.h"
58 #include <fcntl.h>
59 #include <errno.h>
60 #include <sys/stat.h>
61 #include "character.h"
62 #include "coding.h"
63 #include "composite.h"
64 #include "frame.h"
65 #include "dispextern.h"
66 #include "xwidget.h"
67 #include "fontset.h"
68 #include "termhooks.h"
69 #include "termopts.h"
70 #include "termchar.h"
71 #include "emacs-icon.h"
72 #include "buffer.h"
73 #include "window.h"
74 #include "keyboard.h"
75 #include "atimer.h"
76 #include "font.h"
77 #include "xsettings.h"
78 #include "sysselect.h"
79 #include "menu.h"
81 #ifdef USE_X_TOOLKIT
82 #include <X11/Shell.h>
83 #endif
85 #include <unistd.h>
87 #ifdef USE_GTK
88 #include "gtkutil.h"
89 #ifdef HAVE_GTK3
90 #include <X11/Xproto.h>
91 #endif
92 #endif
94 #if defined (USE_LUCID) || defined (USE_MOTIF)
95 #include "../lwlib/xlwmenu.h"
96 #endif
98 #ifdef USE_X_TOOLKIT
100 /* Include toolkit specific headers for the scroll bar widget. */
102 #ifdef USE_TOOLKIT_SCROLL_BARS
103 #if defined USE_MOTIF
104 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
105 #include <Xm/ScrollBar.h>
106 #else /* !USE_MOTIF i.e. use Xaw */
108 #ifdef HAVE_XAW3D
109 #include <X11/Xaw3d/Simple.h>
110 #include <X11/Xaw3d/Scrollbar.h>
111 #include <X11/Xaw3d/ThreeD.h>
112 #else /* !HAVE_XAW3D */
113 #include <X11/Xaw/Simple.h>
114 #include <X11/Xaw/Scrollbar.h>
115 #endif /* !HAVE_XAW3D */
116 #ifndef XtNpickTop
117 #define XtNpickTop "pickTop"
118 #endif /* !XtNpickTop */
119 #endif /* !USE_MOTIF */
120 #endif /* USE_TOOLKIT_SCROLL_BARS */
122 #endif /* USE_X_TOOLKIT */
124 #ifdef USE_X_TOOLKIT
125 #include "widget.h"
126 #ifndef XtNinitialState
127 #define XtNinitialState "initialState"
128 #endif
129 #endif
131 #include "bitmaps/gray.xbm"
133 #ifdef HAVE_XKB
134 #include <X11/XKBlib.h>
135 #endif
137 /* Default to using XIM if available. */
138 #ifdef USE_XIM
139 bool use_xim = true;
140 #else
141 bool use_xim = false; /* configure --without-xim */
142 #endif
144 /* Non-zero means that a HELP_EVENT has been generated since Emacs
145 start. */
147 static bool any_help_event_p;
149 /* This is a chain of structures for all the X displays currently in
150 use. */
152 struct x_display_info *x_display_list;
154 #ifdef USE_X_TOOLKIT
156 /* The application context for Xt use. */
157 XtAppContext Xt_app_con;
158 static String Xt_default_resources[] = {0};
160 /* Non-zero means user is interacting with a toolkit scroll bar. */
161 static bool toolkit_scroll_bar_interaction;
163 #endif /* USE_X_TOOLKIT */
165 /* Non-zero timeout value means ignore next mouse click if it arrives
166 before that timeout elapses (i.e. as part of the same sequence of
167 events resulting from clicking on a frame to select it). */
169 static Time ignore_next_mouse_click_timeout;
171 /* Used locally within XTread_socket. */
173 static int x_noop_count;
175 #ifdef USE_GTK
176 /* The name of the Emacs icon file. */
177 static Lisp_Object xg_default_icon_file;
178 #endif
180 /* Some functions take this as char *, not const char *. */
181 static char emacs_class[] = EMACS_CLASS;
183 enum xembed_info
185 XEMBED_MAPPED = 1 << 0
188 enum xembed_message
190 XEMBED_EMBEDDED_NOTIFY = 0,
191 XEMBED_WINDOW_ACTIVATE = 1,
192 XEMBED_WINDOW_DEACTIVATE = 2,
193 XEMBED_REQUEST_FOCUS = 3,
194 XEMBED_FOCUS_IN = 4,
195 XEMBED_FOCUS_OUT = 5,
196 XEMBED_FOCUS_NEXT = 6,
197 XEMBED_FOCUS_PREV = 7,
199 XEMBED_MODALITY_ON = 10,
200 XEMBED_MODALITY_OFF = 11,
201 XEMBED_REGISTER_ACCELERATOR = 12,
202 XEMBED_UNREGISTER_ACCELERATOR = 13,
203 XEMBED_ACTIVATE_ACCELERATOR = 14
206 static void x_free_cr_resources (struct frame *);
207 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
208 static void x_raise_frame (struct frame *);
209 static void x_lower_frame (struct frame *);
210 static int x_io_error_quitter (Display *);
211 static struct terminal *x_create_terminal (struct x_display_info *);
212 static void x_frame_rehighlight (struct x_display_info *);
214 static void x_clip_to_row (struct window *, struct glyph_row *,
215 enum glyph_row_area, GC);
216 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
217 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
218 enum scroll_bar_part *,
219 Lisp_Object *, Lisp_Object *,
220 Time *);
221 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
222 enum scroll_bar_part *,
223 Lisp_Object *, Lisp_Object *,
224 Time *);
225 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
226 static void x_check_fullscreen (struct frame *);
227 static void x_check_expected_move (struct frame *, int, int);
228 static void x_sync_with_move (struct frame *, int, int, bool);
229 static int handle_one_xevent (struct x_display_info *,
230 const XEvent *, int *,
231 struct input_event *);
232 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
233 static int x_dispatch_event (XEvent *, Display *);
234 #endif
235 static void x_wm_set_window_state (struct frame *, int);
236 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
237 static void x_initialize (void);
239 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
241 /* Flush display of frame F. */
243 static void
244 x_flush (struct frame *f)
246 eassert (f && FRAME_X_P (f));
247 /* Don't call XFlush when it is not safe to redisplay; the X
248 connection may be broken. */
249 if (!NILP (Vinhibit_redisplay))
250 return;
252 block_input ();
253 XFlush (FRAME_X_DISPLAY (f));
254 unblock_input ();
258 /* Remove calls to XFlush by defining XFlush to an empty replacement.
259 Calls to XFlush should be unnecessary because the X output buffer
260 is flushed automatically as needed by calls to XPending,
261 XNextEvent, or XWindowEvent according to the XFlush man page.
262 XTread_socket calls XPending. Removing XFlush improves
263 performance. */
265 #define XFlush(DISPLAY) (void) 0
268 /***********************************************************************
269 Debugging
270 ***********************************************************************/
272 #if false
274 /* This is a function useful for recording debugging information about
275 the sequence of occurrences in this file. */
277 struct record
279 char *locus;
280 int type;
283 struct record event_record[100];
285 int event_record_index;
287 void
288 record_event (char *locus, int type)
290 if (event_record_index == ARRAYELTS (event_record))
291 event_record_index = 0;
293 event_record[event_record_index].locus = locus;
294 event_record[event_record_index].type = type;
295 event_record_index++;
298 #endif
300 #ifdef USE_CAIRO
302 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
303 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
305 static struct x_gc_ext_data *
306 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
308 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
309 XEDataObject object;
310 XExtData **head, *ext_data;
312 object.gc = gc;
313 head = XEHeadOfExtensionList (object);
314 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
315 if (ext_data == NULL)
317 if (!create_if_not_found_p)
318 return NULL;
319 else
321 ext_data = xzalloc (sizeof (*ext_data));
322 ext_data->number = dpyinfo->ext_codes->extension;
323 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
324 XAddToExtensionList (head, ext_data);
327 return (struct x_gc_ext_data *) ext_data->private_data;
330 static void
331 x_extension_initialize (struct x_display_info *dpyinfo)
333 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
335 dpyinfo->ext_codes = ext_codes;
338 static void
339 x_cr_destroy_surface (struct frame *f)
341 if (FRAME_CR_SURFACE (f))
343 cairo_t *cr = FRAME_CR_CONTEXT (f);
344 cairo_surface_destroy (FRAME_CR_SURFACE (f));
345 FRAME_CR_SURFACE (f) = 0;
346 if (cr) cairo_destroy (cr);
347 FRAME_CR_CONTEXT (f) = NULL;
351 cairo_t *
352 x_begin_cr_clip (struct frame *f, GC gc)
354 cairo_t *cr = FRAME_CR_CONTEXT (f);
356 if (!cr)
359 if (! FRAME_CR_SURFACE (f))
361 cairo_surface_t *surface;
362 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
363 FRAME_X_WINDOW (f),
364 FRAME_DISPLAY_INFO (f)->visual,
365 FRAME_PIXEL_WIDTH (f),
366 FRAME_PIXEL_HEIGHT (f));
367 cr = cairo_create (surface);
368 cairo_surface_destroy (surface);
370 else
371 cr = cairo_create (FRAME_CR_SURFACE (f));
372 FRAME_CR_CONTEXT (f) = cr;
374 cairo_save (cr);
376 if (gc)
378 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
380 if (gc_ext && gc_ext->n_clip_rects)
382 int i;
384 for (i = 0; i < gc_ext->n_clip_rects; i++)
385 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
386 gc_ext->clip_rects[i].y,
387 gc_ext->clip_rects[i].width,
388 gc_ext->clip_rects[i].height);
389 cairo_clip (cr);
393 return cr;
396 void
397 x_end_cr_clip (struct frame *f)
399 cairo_restore (FRAME_CR_CONTEXT (f));
402 void
403 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
405 XGCValues xgcv;
406 XColor color;
408 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
409 color.pixel = xgcv.foreground;
410 x_query_color (f, &color);
411 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
412 color.green / 65535.0, color.blue / 65535.0);
415 void
416 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
418 XGCValues xgcv;
419 XColor color;
421 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
422 color.pixel = xgcv.background;
423 x_query_color (f, &color);
424 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
425 color.green / 65535.0, color.blue / 65535.0);
428 /* Fringe bitmaps. */
430 static int max_fringe_bmp = 0;
431 static cairo_pattern_t **fringe_bmp = 0;
433 static void
434 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
436 int i, stride;
437 cairo_surface_t *surface;
438 unsigned char *data;
439 cairo_pattern_t *pattern;
441 if (which >= max_fringe_bmp)
443 i = max_fringe_bmp;
444 max_fringe_bmp = which + 20;
445 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
446 while (i < max_fringe_bmp)
447 fringe_bmp[i++] = 0;
450 block_input ();
452 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
453 stride = cairo_image_surface_get_stride (surface);
454 data = cairo_image_surface_get_data (surface);
456 for (i = 0; i < h; i++)
458 *((unsigned short *) data) = bits[i];
459 data += stride;
462 cairo_surface_mark_dirty (surface);
463 pattern = cairo_pattern_create_for_surface (surface);
464 cairo_surface_destroy (surface);
466 unblock_input ();
468 fringe_bmp[which] = pattern;
471 static void
472 x_cr_destroy_fringe_bitmap (int which)
474 if (which >= max_fringe_bmp)
475 return;
477 if (fringe_bmp[which])
479 block_input ();
480 cairo_pattern_destroy (fringe_bmp[which]);
481 unblock_input ();
483 fringe_bmp[which] = 0;
486 static void
487 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
488 int src_x, int src_y, int width, int height,
489 int dest_x, int dest_y, bool overlay_p)
491 cairo_t *cr;
492 cairo_matrix_t matrix;
493 cairo_surface_t *surface;
494 cairo_format_t format;
496 cr = x_begin_cr_clip (f, gc);
497 if (overlay_p)
498 cairo_rectangle (cr, dest_x, dest_y, width, height);
499 else
501 x_set_cr_source_with_gc_background (f, gc);
502 cairo_rectangle (cr, dest_x, dest_y, width, height);
503 cairo_fill_preserve (cr);
505 cairo_clip (cr);
506 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
507 cairo_pattern_set_matrix (image, &matrix);
508 cairo_pattern_get_surface (image, &surface);
509 format = cairo_image_surface_get_format (surface);
510 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
512 cairo_set_source (cr, image);
513 cairo_fill (cr);
515 else
517 x_set_cr_source_with_gc_foreground (f, gc);
518 cairo_mask (cr, image);
520 x_end_cr_clip (f);
523 void
524 x_cr_draw_frame (cairo_t *cr, struct frame *f)
526 int width, height;
528 width = FRAME_PIXEL_WIDTH (f);
529 height = FRAME_PIXEL_HEIGHT (f);
531 x_free_cr_resources (f);
532 FRAME_CR_CONTEXT (f) = cr;
533 x_clear_area (f, 0, 0, width, height);
534 expose_frame (f, 0, 0, width, height);
535 FRAME_CR_CONTEXT (f) = NULL;
538 static cairo_status_t
539 x_cr_accumulate_data (void *closure, const unsigned char *data,
540 unsigned int length)
542 Lisp_Object *acc = (Lisp_Object *) closure;
544 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
546 return CAIRO_STATUS_SUCCESS;
549 static void
550 x_cr_destroy (Lisp_Object arg)
552 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
554 block_input ();
555 cairo_destroy (cr);
556 unblock_input ();
559 Lisp_Object
560 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
562 struct frame *f;
563 cairo_surface_t *surface;
564 cairo_t *cr;
565 int width, height;
566 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
567 Lisp_Object acc = Qnil;
568 int count = SPECPDL_INDEX ();
570 specbind (Qredisplay_dont_pause, Qt);
571 redisplay_preserve_echo_area (31);
573 f = XFRAME (XCAR (frames));
574 frames = XCDR (frames);
575 width = FRAME_PIXEL_WIDTH (f);
576 height = FRAME_PIXEL_HEIGHT (f);
578 block_input ();
579 #ifdef CAIRO_HAS_PDF_SURFACE
580 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
582 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
583 width, height);
584 surface_set_size_func = cairo_pdf_surface_set_size;
586 else
587 #endif
588 #ifdef CAIRO_HAS_PNG_FUNCTIONS
589 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
590 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
591 else
592 #endif
593 #ifdef CAIRO_HAS_PS_SURFACE
594 if (surface_type == CAIRO_SURFACE_TYPE_PS)
596 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
597 width, height);
598 surface_set_size_func = cairo_ps_surface_set_size;
600 else
601 #endif
602 #ifdef CAIRO_HAS_SVG_SURFACE
603 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
604 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
605 width, height);
606 else
607 #endif
608 abort ();
610 cr = cairo_create (surface);
611 cairo_surface_destroy (surface);
612 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
614 while (1)
616 x_free_cr_resources (f);
617 FRAME_CR_CONTEXT (f) = cr;
618 x_clear_area (f, 0, 0, width, height);
619 expose_frame (f, 0, 0, width, height);
620 FRAME_CR_CONTEXT (f) = NULL;
622 if (NILP (frames))
623 break;
625 cairo_surface_show_page (surface);
626 f = XFRAME (XCAR (frames));
627 frames = XCDR (frames);
628 width = FRAME_PIXEL_WIDTH (f);
629 height = FRAME_PIXEL_HEIGHT (f);
630 if (surface_set_size_func)
631 (*surface_set_size_func) (surface, width, height);
633 unblock_input ();
634 QUIT;
635 block_input ();
638 #ifdef CAIRO_HAS_PNG_FUNCTIONS
639 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
641 cairo_surface_flush (surface);
642 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
644 #endif
645 unblock_input ();
647 unbind_to (count, Qnil);
649 return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
652 #endif /* USE_CAIRO */
654 static void
655 x_free_cr_resources (struct frame *f)
657 #ifdef USE_CAIRO
658 if (f == NULL)
660 Lisp_Object rest, frame;
661 FOR_EACH_FRAME (rest, frame)
662 if (FRAME_X_P (XFRAME (frame)))
663 x_free_cr_resources (XFRAME (frame));
665 else
667 cairo_t *cr = FRAME_CR_CONTEXT (f);
669 if (cr)
671 cairo_surface_t *surface = cairo_get_target (cr);
673 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
675 cairo_destroy (cr);
676 FRAME_CR_CONTEXT (f) = NULL;
680 #endif
683 static void
684 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
686 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
687 #ifdef USE_CAIRO
688 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
691 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
693 gc_ext->n_clip_rects = n;
694 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
696 #endif
699 static void
700 x_reset_clip_rectangles (struct frame *f, GC gc)
702 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
703 #ifdef USE_CAIRO
705 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
707 if (gc_ext)
708 gc_ext->n_clip_rects = 0;
710 #endif
713 static void
714 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
716 #ifdef USE_CAIRO
717 cairo_t *cr;
719 cr = x_begin_cr_clip (f, gc);
720 x_set_cr_source_with_gc_foreground (f, gc);
721 cairo_rectangle (cr, x, y, width, height);
722 cairo_fill (cr);
723 x_end_cr_clip (f);
724 #else
725 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
726 gc, x, y, width, height);
727 #endif
730 static void
731 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
733 #ifdef USE_CAIRO
734 cairo_t *cr;
736 cr = x_begin_cr_clip (f, gc);
737 x_set_cr_source_with_gc_foreground (f, gc);
738 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
739 cairo_set_line_width (cr, 1);
740 cairo_stroke (cr);
741 x_end_cr_clip (f);
742 #else
743 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
744 gc, x, y, width, height);
745 #endif
748 static void
749 x_clear_window (struct frame *f)
751 #ifdef USE_CAIRO
752 cairo_t *cr;
754 cr = x_begin_cr_clip (f, NULL);
755 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
756 cairo_paint (cr);
757 x_end_cr_clip (f);
758 #else
759 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
760 #endif
763 #ifdef USE_CAIRO
764 static void
765 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
766 int width, int height, int top_p)
768 cairo_t *cr;
770 cr = x_begin_cr_clip (f, gc);
771 x_set_cr_source_with_gc_foreground (f, gc);
772 cairo_move_to (cr, top_p ? x : x + height, y);
773 cairo_line_to (cr, x, y + height);
774 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
775 cairo_line_to (cr, x + width, y);
776 cairo_fill (cr);
777 x_end_cr_clip (f);
780 enum corners
782 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
783 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
784 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
785 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
786 CORNER_LAST
789 static void
790 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
791 int width, int height,
792 double radius, double margin, int corners)
794 cairo_t *cr;
795 int i;
797 cr = x_begin_cr_clip (f, gc);
798 x_set_cr_source_with_gc_background (f, gc);
799 for (i = 0; i < CORNER_LAST; i++)
800 if (corners & (1 << i))
802 double xm, ym, xc, yc;
804 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
805 xm = x - margin, xc = xm + radius;
806 else
807 xm = x + width + margin, xc = xm - radius;
808 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
809 ym = y - margin, yc = ym + radius;
810 else
811 ym = y + height + margin, yc = ym - radius;
813 cairo_move_to (cr, xm, ym);
814 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
816 cairo_clip (cr);
817 cairo_rectangle (cr, x, y, width, height);
818 cairo_fill (cr);
819 x_end_cr_clip (f);
822 static void
823 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
824 int width, int height, int wave_length)
826 cairo_t *cr;
827 double dx = wave_length, dy = height - 1;
828 int xoffset, n;
830 cr = x_begin_cr_clip (f, gc);
831 x_set_cr_source_with_gc_foreground (f, gc);
832 cairo_rectangle (cr, x, y, width, height);
833 cairo_clip (cr);
835 if (x >= 0)
837 xoffset = x % (wave_length * 2);
838 if (xoffset == 0)
839 xoffset = wave_length * 2;
841 else
842 xoffset = x % (wave_length * 2) + wave_length * 2;
843 n = (width + xoffset) / wave_length + 1;
844 if (xoffset > wave_length)
846 xoffset -= wave_length;
847 --n;
848 y += height - 1;
849 dy = -dy;
852 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
853 while (--n >= 0)
855 cairo_rel_line_to (cr, dx, dy);
856 dy = -dy;
858 cairo_set_line_width (cr, 1);
859 cairo_stroke (cr);
860 x_end_cr_clip (f);
862 #endif
865 /* Return the struct x_display_info corresponding to DPY. */
867 struct x_display_info *
868 x_display_info_for_display (Display *dpy)
870 struct x_display_info *dpyinfo;
872 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
873 if (dpyinfo->display == dpy)
874 return dpyinfo;
876 return 0;
879 static Window
880 x_find_topmost_parent (struct frame *f)
882 struct x_output *x = f->output_data.x;
883 Window win = None, wi = x->parent_desc;
884 Display *dpy = FRAME_X_DISPLAY (f);
886 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
888 Window root;
889 Window *children;
890 unsigned int nchildren;
892 win = wi;
893 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
894 XFree (children);
895 else
896 break;
899 return win;
902 #define OPAQUE 0xffffffff
904 void
905 x_set_frame_alpha (struct frame *f)
907 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
908 Display *dpy = FRAME_X_DISPLAY (f);
909 Window win = FRAME_OUTER_WINDOW (f);
910 double alpha = 1.0;
911 double alpha_min = 1.0;
912 unsigned long opac;
913 Window parent;
915 if (dpyinfo->x_highlight_frame == f)
916 alpha = f->alpha[0];
917 else
918 alpha = f->alpha[1];
920 if (FLOATP (Vframe_alpha_lower_limit))
921 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
922 else if (INTEGERP (Vframe_alpha_lower_limit))
923 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
925 if (alpha < 0.0)
926 return;
927 else if (alpha > 1.0)
928 alpha = 1.0;
929 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
930 alpha = alpha_min;
932 opac = alpha * OPAQUE;
934 x_catch_errors (dpy);
936 /* If there is a parent from the window manager, put the property there
937 also, to work around broken window managers that fail to do that.
938 Do this unconditionally as this function is called on reparent when
939 alpha has not changed on the frame. */
941 parent = x_find_topmost_parent (f);
942 if (parent != None)
943 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
944 XA_CARDINAL, 32, PropModeReplace,
945 (unsigned char *) &opac, 1);
947 /* return unless necessary */
949 unsigned char *data;
950 Atom actual;
951 int rc, format;
952 unsigned long n, left;
954 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
955 0, 1, False, XA_CARDINAL,
956 &actual, &format, &n, &left,
957 &data);
959 if (rc == Success && actual != None)
961 unsigned long value = *(unsigned long *)data;
962 XFree (data);
963 if (value == opac)
965 x_uncatch_errors ();
966 return;
971 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
972 XA_CARDINAL, 32, PropModeReplace,
973 (unsigned char *) &opac, 1);
974 x_uncatch_errors ();
977 /***********************************************************************
978 Starting and ending an update
979 ***********************************************************************/
981 /* Start an update of frame F. This function is installed as a hook
982 for update_begin, i.e. it is called when update_begin is called.
983 This function is called prior to calls to x_update_window_begin for
984 each window being updated. Currently, there is nothing to do here
985 because all interesting stuff is done on a window basis. */
987 static void
988 x_update_begin (struct frame *f)
990 #ifdef USE_CAIRO
991 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
992 && ! FRAME_VISIBLE_P (f))
993 return;
995 if (! FRAME_CR_SURFACE (f))
997 int width, height;
998 #ifdef USE_GTK
999 if (FRAME_GTK_WIDGET (f))
1001 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1002 width = gdk_window_get_width (w);
1003 height = gdk_window_get_height (w);
1005 else
1006 #endif
1008 width = FRAME_PIXEL_WIDTH (f);
1009 height = FRAME_PIXEL_HEIGHT (f);
1010 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1011 height += FRAME_TOOL_BAR_HEIGHT (f);
1012 if (! FRAME_EXTERNAL_MENU_BAR (f))
1013 height += FRAME_MENU_BAR_HEIGHT (f);
1016 if (width > 0 && height > 0)
1018 block_input();
1019 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1020 (CAIRO_FORMAT_ARGB32, width, height);
1021 unblock_input();
1024 #endif /* USE_CAIRO */
1027 /* Start update of window W. */
1029 static void
1030 x_update_window_begin (struct window *w)
1032 struct frame *f = XFRAME (WINDOW_FRAME (w));
1033 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1035 w->output_cursor = w->cursor;
1037 block_input ();
1039 if (f == hlinfo->mouse_face_mouse_frame)
1041 /* Don't do highlighting for mouse motion during the update. */
1042 hlinfo->mouse_face_defer = true;
1044 /* If F needs to be redrawn, simply forget about any prior mouse
1045 highlighting. */
1046 if (FRAME_GARBAGED_P (f))
1047 hlinfo->mouse_face_window = Qnil;
1050 unblock_input ();
1054 /* Draw a vertical window border from (x,y0) to (x,y1) */
1056 static void
1057 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1059 struct frame *f = XFRAME (WINDOW_FRAME (w));
1060 struct face *face;
1062 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
1063 if (face)
1064 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1065 face->foreground);
1067 #ifdef USE_CAIRO
1068 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1069 #else
1070 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1071 f->output_data.x->normal_gc, x, y0, x, y1);
1072 #endif
1075 /* Draw a window divider from (x0,y0) to (x1,y1) */
1077 static void
1078 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1080 struct frame *f = XFRAME (WINDOW_FRAME (w));
1081 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
1082 struct face *face_first
1083 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1084 struct face *face_last
1085 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1086 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1087 unsigned long color_first = (face_first
1088 ? face_first->foreground
1089 : FRAME_FOREGROUND_PIXEL (f));
1090 unsigned long color_last = (face_last
1091 ? face_last->foreground
1092 : FRAME_FOREGROUND_PIXEL (f));
1093 Display *display = FRAME_X_DISPLAY (f);
1095 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1096 /* Vertical. */
1098 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1099 x_fill_rectangle (f, f->output_data.x->normal_gc,
1100 x0, y0, 1, y1 - y0);
1101 XSetForeground (display, f->output_data.x->normal_gc, color);
1102 x_fill_rectangle (f, f->output_data.x->normal_gc,
1103 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1104 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1105 x_fill_rectangle (f, f->output_data.x->normal_gc,
1106 x1 - 1, y0, 1, y1 - y0);
1108 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1109 /* Horizontal. */
1111 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1112 x_fill_rectangle (f, f->output_data.x->normal_gc,
1113 x0, y0, x1 - x0, 1);
1114 XSetForeground (display, f->output_data.x->normal_gc, color);
1115 x_fill_rectangle (f, f->output_data.x->normal_gc,
1116 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1117 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1118 x_fill_rectangle (f, f->output_data.x->normal_gc,
1119 x0, y1 - 1, x1 - x0, 1);
1121 else
1123 XSetForeground (display, f->output_data.x->normal_gc, color);
1124 x_fill_rectangle (f, f->output_data.x->normal_gc,
1125 x0, y0, x1 - x0, y1 - y0);
1129 /* End update of window W.
1131 Draw vertical borders between horizontally adjacent windows, and
1132 display W's cursor if CURSOR_ON_P is non-zero.
1134 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1135 glyphs in mouse-face were overwritten. In that case we have to
1136 make sure that the mouse-highlight is properly redrawn.
1138 W may be a menu bar pseudo-window in case we don't have X toolkit
1139 support. Such windows don't have a cursor, so don't display it
1140 here. */
1142 static void
1143 x_update_window_end (struct window *w, bool cursor_on_p,
1144 bool mouse_face_overwritten_p)
1146 if (!w->pseudo_window_p)
1148 block_input ();
1150 if (cursor_on_p)
1151 display_and_set_cursor (w, true,
1152 w->output_cursor.hpos, w->output_cursor.vpos,
1153 w->output_cursor.x, w->output_cursor.y);
1155 if (draw_window_fringes (w, true))
1157 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1158 x_draw_right_divider (w);
1159 else
1160 x_draw_vertical_border (w);
1163 unblock_input ();
1166 /* If a row with mouse-face was overwritten, arrange for
1167 XTframe_up_to_date to redisplay the mouse highlight. */
1168 if (mouse_face_overwritten_p)
1170 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1172 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1173 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1174 hlinfo->mouse_face_window = Qnil;
1179 /* End update of frame F. This function is installed as a hook in
1180 update_end. */
1182 static void
1183 x_update_end (struct frame *f)
1185 /* Mouse highlight may be displayed again. */
1186 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1188 #ifdef USE_CAIRO
1189 if (FRAME_CR_SURFACE (f))
1191 cairo_t *cr = 0;
1192 block_input();
1193 #if defined (USE_GTK) && defined (HAVE_GTK3)
1194 if (FRAME_GTK_WIDGET (f))
1196 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1197 cr = gdk_cairo_create (w);
1199 else
1200 #endif
1202 cairo_surface_t *surface;
1203 int width = FRAME_PIXEL_WIDTH (f);
1204 int height = FRAME_PIXEL_HEIGHT (f);
1205 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1206 height += FRAME_TOOL_BAR_HEIGHT (f);
1207 if (! FRAME_EXTERNAL_MENU_BAR (f))
1208 height += FRAME_MENU_BAR_HEIGHT (f);
1209 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1210 FRAME_X_WINDOW (f),
1211 FRAME_DISPLAY_INFO (f)->visual,
1212 width,
1213 height);
1214 cr = cairo_create (surface);
1215 cairo_surface_destroy (surface);
1218 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1219 cairo_paint (cr);
1220 cairo_destroy (cr);
1221 unblock_input ();
1223 #endif /* USE_CAIRO */
1225 #ifndef XFlush
1226 block_input ();
1227 XFlush (FRAME_X_DISPLAY (f));
1228 unblock_input ();
1229 #endif
1233 /* This function is called from various places in xdisp.c
1234 whenever a complete update has been performed. */
1236 static void
1237 XTframe_up_to_date (struct frame *f)
1239 if (FRAME_X_P (f))
1240 FRAME_MOUSE_UPDATE (f);
1244 /* Clear under internal border if any (GTK has its own version). */
1245 #ifndef USE_GTK
1246 void
1247 x_clear_under_internal_border (struct frame *f)
1249 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1251 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1252 int width = FRAME_PIXEL_WIDTH (f);
1253 int height = FRAME_PIXEL_HEIGHT (f);
1254 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1256 block_input ();
1257 x_clear_area (f, 0, 0, border, height);
1258 x_clear_area (f, 0, margin, width, border);
1259 x_clear_area (f, width - border, 0, border, height);
1260 x_clear_area (f, 0, height - border, width, border);
1261 unblock_input ();
1264 #endif
1266 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1267 arrow bitmaps, or clear the fringes if no bitmaps are required
1268 before DESIRED_ROW is made current. This function is called from
1269 update_window_line only if it is known that there are differences
1270 between bitmaps to be drawn between current row and DESIRED_ROW. */
1272 static void
1273 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1275 eassert (w);
1277 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1278 desired_row->redraw_fringe_bitmaps_p = true;
1280 #ifdef USE_X_TOOLKIT
1281 /* When a window has disappeared, make sure that no rest of
1282 full-width rows stays visible in the internal border. Could
1283 check here if updated window is the leftmost/rightmost window,
1284 but I guess it's not worth doing since vertically split windows
1285 are almost never used, internal border is rarely set, and the
1286 overhead is very small. */
1288 struct frame *f;
1289 int width, height;
1291 if (windows_or_buffers_changed
1292 && desired_row->full_width_p
1293 && (f = XFRAME (w->frame),
1294 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1295 width != 0)
1296 && (height = desired_row->visible_height,
1297 height > 0))
1299 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1301 block_input ();
1302 x_clear_area (f, 0, y, width, height);
1303 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1304 unblock_input ();
1307 #endif
1310 static void
1311 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1313 struct frame *f = XFRAME (WINDOW_FRAME (w));
1314 Display *display = FRAME_X_DISPLAY (f);
1315 GC gc = f->output_data.x->normal_gc;
1316 struct face *face = p->face;
1318 /* Must clip because of partially visible lines. */
1319 x_clip_to_row (w, row, ANY_AREA, gc);
1321 if (p->bx >= 0 && !p->overlay_p)
1323 /* In case the same realized face is used for fringes and
1324 for something displayed in the text (e.g. face `region' on
1325 mono-displays, the fill style may have been changed to
1326 FillSolid in x_draw_glyph_string_background. */
1327 if (face->stipple)
1328 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1329 else
1330 XSetForeground (display, face->gc, face->background);
1332 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1334 if (!face->stipple)
1335 XSetForeground (display, face->gc, face->foreground);
1338 #ifdef USE_CAIRO
1339 if (p->which && p->which < max_fringe_bmp)
1341 XGCValues gcv;
1343 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1344 XSetForeground (display, gc, (p->cursor_p
1345 ? (p->overlay_p ? face->background
1346 : f->output_data.x->cursor_pixel)
1347 : face->foreground));
1348 XSetBackground (display, gc, face->background);
1349 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1350 p->wd, p->h, p->x, p->y, p->overlay_p);
1351 XSetForeground (display, gc, gcv.foreground);
1352 XSetBackground (display, gc, gcv.background);
1354 #else /* not USE_CAIRO */
1355 if (p->which)
1357 Window window = FRAME_X_WINDOW (f);
1358 char *bits;
1359 Pixmap pixmap, clipmask = (Pixmap) 0;
1360 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1361 XGCValues gcv;
1363 if (p->wd > 8)
1364 bits = (char *) (p->bits + p->dh);
1365 else
1366 bits = (char *) p->bits + p->dh;
1368 /* Draw the bitmap. I believe these small pixmaps can be cached
1369 by the server. */
1370 pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h,
1371 (p->cursor_p
1372 ? (p->overlay_p ? face->background
1373 : f->output_data.x->cursor_pixel)
1374 : face->foreground),
1375 face->background, depth);
1377 if (p->overlay_p)
1379 clipmask = XCreatePixmapFromBitmapData (display,
1380 FRAME_DISPLAY_INFO (f)->root_window,
1381 bits, p->wd, p->h,
1382 1, 0, 1);
1383 gcv.clip_mask = clipmask;
1384 gcv.clip_x_origin = p->x;
1385 gcv.clip_y_origin = p->y;
1386 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1389 XCopyArea (display, pixmap, window, gc, 0, 0,
1390 p->wd, p->h, p->x, p->y);
1391 XFreePixmap (display, pixmap);
1393 if (p->overlay_p)
1395 gcv.clip_mask = (Pixmap) 0;
1396 XChangeGC (display, gc, GCClipMask, &gcv);
1397 XFreePixmap (display, clipmask);
1400 #endif /* not USE_CAIRO */
1402 x_reset_clip_rectangles (f, gc);
1405 /***********************************************************************
1406 Glyph display
1407 ***********************************************************************/
1411 static void x_set_glyph_string_clipping (struct glyph_string *);
1412 static void x_set_glyph_string_gc (struct glyph_string *);
1413 static void x_draw_glyph_string_foreground (struct glyph_string *);
1414 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1415 static void x_draw_glyph_string_box (struct glyph_string *);
1416 static void x_draw_glyph_string (struct glyph_string *);
1417 static _Noreturn void x_delete_glyphs (struct frame *, int);
1418 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1419 static void x_set_cursor_gc (struct glyph_string *);
1420 static void x_set_mode_line_face_gc (struct glyph_string *);
1421 static void x_set_mouse_face_gc (struct glyph_string *);
1422 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1423 unsigned long *, double, int);
1424 static void x_setup_relief_color (struct frame *, struct relief *,
1425 double, int, unsigned long);
1426 static void x_setup_relief_colors (struct glyph_string *);
1427 static void x_draw_image_glyph_string (struct glyph_string *);
1428 static void x_draw_image_relief (struct glyph_string *);
1429 static void x_draw_image_foreground (struct glyph_string *);
1430 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1431 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1432 int, int, int);
1433 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1434 int, bool, bool, bool, bool, bool,
1435 XRectangle *);
1436 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1437 int, bool, bool, XRectangle *);
1438 static void x_scroll_bar_clear (struct frame *);
1440 #ifdef GLYPH_DEBUG
1441 static void x_check_font (struct frame *, struct font *);
1442 #endif
1445 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1446 face. */
1448 static void
1449 x_set_cursor_gc (struct glyph_string *s)
1451 if (s->font == FRAME_FONT (s->f)
1452 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1453 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1454 && !s->cmp)
1455 s->gc = s->f->output_data.x->cursor_gc;
1456 else
1458 /* Cursor on non-default face: must merge. */
1459 XGCValues xgcv;
1460 unsigned long mask;
1462 xgcv.background = s->f->output_data.x->cursor_pixel;
1463 xgcv.foreground = s->face->background;
1465 /* If the glyph would be invisible, try a different foreground. */
1466 if (xgcv.foreground == xgcv.background)
1467 xgcv.foreground = s->face->foreground;
1468 if (xgcv.foreground == xgcv.background)
1469 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1470 if (xgcv.foreground == xgcv.background)
1471 xgcv.foreground = s->face->foreground;
1473 /* Make sure the cursor is distinct from text in this face. */
1474 if (xgcv.background == s->face->background
1475 && xgcv.foreground == s->face->foreground)
1477 xgcv.background = s->face->foreground;
1478 xgcv.foreground = s->face->background;
1481 IF_DEBUG (x_check_font (s->f, s->font));
1482 xgcv.graphics_exposures = False;
1483 mask = GCForeground | GCBackground | GCGraphicsExposures;
1485 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1486 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1487 mask, &xgcv);
1488 else
1489 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1490 = XCreateGC (s->display, s->window, mask, &xgcv);
1492 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1497 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1499 static void
1500 x_set_mouse_face_gc (struct glyph_string *s)
1502 int face_id;
1503 struct face *face;
1505 /* What face has to be used last for the mouse face? */
1506 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1507 face = FACE_FROM_ID_OR_NULL (s->f, face_id);
1508 if (face == NULL)
1509 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1511 if (s->first_glyph->type == CHAR_GLYPH)
1512 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1513 else
1514 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1515 s->face = FACE_FROM_ID (s->f, face_id);
1516 prepare_face_for_display (s->f, s->face);
1518 if (s->font == s->face->font)
1519 s->gc = s->face->gc;
1520 else
1522 /* Otherwise construct scratch_cursor_gc with values from FACE
1523 except for FONT. */
1524 XGCValues xgcv;
1525 unsigned long mask;
1527 xgcv.background = s->face->background;
1528 xgcv.foreground = s->face->foreground;
1529 xgcv.graphics_exposures = False;
1530 mask = GCForeground | GCBackground | GCGraphicsExposures;
1532 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1533 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1534 mask, &xgcv);
1535 else
1536 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1537 = XCreateGC (s->display, s->window, mask, &xgcv);
1539 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1542 eassert (s->gc != 0);
1546 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1547 Faces to use in the mode line have already been computed when the
1548 matrix was built, so there isn't much to do, here. */
1550 static void
1551 x_set_mode_line_face_gc (struct glyph_string *s)
1553 s->gc = s->face->gc;
1557 /* Set S->gc of glyph string S for drawing that glyph string. Set
1558 S->stippled_p to a non-zero value if the face of S has a stipple
1559 pattern. */
1561 static void
1562 x_set_glyph_string_gc (struct glyph_string *s)
1564 prepare_face_for_display (s->f, s->face);
1566 if (s->hl == DRAW_NORMAL_TEXT)
1568 s->gc = s->face->gc;
1569 s->stippled_p = s->face->stipple != 0;
1571 else if (s->hl == DRAW_INVERSE_VIDEO)
1573 x_set_mode_line_face_gc (s);
1574 s->stippled_p = s->face->stipple != 0;
1576 else if (s->hl == DRAW_CURSOR)
1578 x_set_cursor_gc (s);
1579 s->stippled_p = false;
1581 else if (s->hl == DRAW_MOUSE_FACE)
1583 x_set_mouse_face_gc (s);
1584 s->stippled_p = s->face->stipple != 0;
1586 else if (s->hl == DRAW_IMAGE_RAISED
1587 || s->hl == DRAW_IMAGE_SUNKEN)
1589 s->gc = s->face->gc;
1590 s->stippled_p = s->face->stipple != 0;
1592 else
1593 emacs_abort ();
1595 /* GC must have been set. */
1596 eassert (s->gc != 0);
1600 /* Set clipping for output of glyph string S. S may be part of a mode
1601 line or menu if we don't have X toolkit support. */
1603 static void
1604 x_set_glyph_string_clipping (struct glyph_string *s)
1606 XRectangle *r = s->clip;
1607 int n = get_glyph_string_clip_rects (s, r, 2);
1609 if (n > 0)
1610 x_set_clip_rectangles (s->f, s->gc, r, n);
1611 s->num_clips = n;
1615 /* Set SRC's clipping for output of glyph string DST. This is called
1616 when we are drawing DST's left_overhang or right_overhang only in
1617 the area of SRC. */
1619 static void
1620 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1622 XRectangle r;
1624 r.x = src->x;
1625 r.width = src->width;
1626 r.y = src->y;
1627 r.height = src->height;
1628 dst->clip[0] = r;
1629 dst->num_clips = 1;
1630 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1634 /* RIF:
1635 Compute left and right overhang of glyph string S. */
1637 static void
1638 x_compute_glyph_string_overhangs (struct glyph_string *s)
1640 if (s->cmp == NULL
1641 && (s->first_glyph->type == CHAR_GLYPH
1642 || s->first_glyph->type == COMPOSITE_GLYPH))
1644 struct font_metrics metrics;
1646 if (s->first_glyph->type == CHAR_GLYPH)
1648 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1649 struct font *font = s->font;
1650 int i;
1652 for (i = 0; i < s->nchars; i++)
1653 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1654 font->driver->text_extents (font, code, s->nchars, &metrics);
1656 else
1658 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1660 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1662 s->right_overhang = (metrics.rbearing > metrics.width
1663 ? metrics.rbearing - metrics.width : 0);
1664 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1666 else if (s->cmp)
1668 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1669 s->left_overhang = - s->cmp->lbearing;
1674 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1676 static void
1677 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1679 XGCValues xgcv;
1680 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1681 XSetForeground (s->display, s->gc, xgcv.background);
1682 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1683 XSetForeground (s->display, s->gc, xgcv.foreground);
1687 /* Draw the background of glyph_string S. If S->background_filled_p
1688 is non-zero don't draw it. FORCE_P non-zero means draw the
1689 background even if it wouldn't be drawn normally. This is used
1690 when a string preceding S draws into the background of S, or S
1691 contains the first component of a composition. */
1693 static void
1694 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1696 /* Nothing to do if background has already been drawn or if it
1697 shouldn't be drawn in the first place. */
1698 if (!s->background_filled_p)
1700 int box_line_width = max (s->face->box_line_width, 0);
1702 if (s->stippled_p)
1704 /* Fill background with a stipple pattern. */
1705 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1706 x_fill_rectangle (s->f, s->gc, s->x,
1707 s->y + box_line_width,
1708 s->background_width,
1709 s->height - 2 * box_line_width);
1710 XSetFillStyle (s->display, s->gc, FillSolid);
1711 s->background_filled_p = true;
1713 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1714 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1715 font dimensions, since the actual glyphs might be
1716 much smaller. So in that case we always clear the
1717 rectangle with background color. */
1718 || FONT_TOO_HIGH (s->font)
1719 || s->font_not_found_p
1720 || s->extends_to_end_of_line_p
1721 || force_p)
1723 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1724 s->background_width,
1725 s->height - 2 * box_line_width);
1726 s->background_filled_p = true;
1732 /* Draw the foreground of glyph string S. */
1734 static void
1735 x_draw_glyph_string_foreground (struct glyph_string *s)
1737 int i, x;
1739 /* If first glyph of S has a left box line, start drawing the text
1740 of S to the right of that box line. */
1741 if (s->face->box != FACE_NO_BOX
1742 && s->first_glyph->left_box_line_p)
1743 x = s->x + eabs (s->face->box_line_width);
1744 else
1745 x = s->x;
1747 /* Draw characters of S as rectangles if S's font could not be
1748 loaded. */
1749 if (s->font_not_found_p)
1751 for (i = 0; i < s->nchars; ++i)
1753 struct glyph *g = s->first_glyph + i;
1754 x_draw_rectangle (s->f,
1755 s->gc, x, s->y, g->pixel_width - 1,
1756 s->height - 1);
1757 x += g->pixel_width;
1760 else
1762 struct font *font = s->font;
1763 int boff = font->baseline_offset;
1764 int y;
1766 if (font->vertical_centering)
1767 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1769 y = s->ybase - boff;
1770 if (s->for_overlaps
1771 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1772 font->driver->draw (s, 0, s->nchars, x, y, false);
1773 else
1774 font->driver->draw (s, 0, s->nchars, x, y, true);
1775 if (s->face->overstrike)
1776 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1780 /* Draw the foreground of composite glyph string S. */
1782 static void
1783 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1785 int i, j, x;
1786 struct font *font = s->font;
1788 /* If first glyph of S has a left box line, start drawing the text
1789 of S to the right of that box line. */
1790 if (s->face && s->face->box != FACE_NO_BOX
1791 && s->first_glyph->left_box_line_p)
1792 x = s->x + eabs (s->face->box_line_width);
1793 else
1794 x = s->x;
1796 /* S is a glyph string for a composition. S->cmp_from is the index
1797 of the first character drawn for glyphs of this composition.
1798 S->cmp_from == 0 means we are drawing the very first character of
1799 this composition. */
1801 /* Draw a rectangle for the composition if the font for the very
1802 first character of the composition could not be loaded. */
1803 if (s->font_not_found_p)
1805 if (s->cmp_from == 0)
1806 x_draw_rectangle (s->f, s->gc, x, s->y,
1807 s->width - 1, s->height - 1);
1809 else if (! s->first_glyph->u.cmp.automatic)
1811 int y = s->ybase;
1813 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1814 /* TAB in a composition means display glyphs with padding
1815 space on the left or right. */
1816 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1818 int xx = x + s->cmp->offsets[j * 2];
1819 int yy = y - s->cmp->offsets[j * 2 + 1];
1821 font->driver->draw (s, j, j + 1, xx, yy, false);
1822 if (s->face->overstrike)
1823 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1826 else
1828 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1829 Lisp_Object glyph;
1830 int y = s->ybase;
1831 int width = 0;
1833 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1835 glyph = LGSTRING_GLYPH (gstring, i);
1836 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1837 width += LGLYPH_WIDTH (glyph);
1838 else
1840 int xoff, yoff, wadjust;
1842 if (j < i)
1844 font->driver->draw (s, j, i, x, y, false);
1845 if (s->face->overstrike)
1846 font->driver->draw (s, j, i, x + 1, y, false);
1847 x += width;
1849 xoff = LGLYPH_XOFF (glyph);
1850 yoff = LGLYPH_YOFF (glyph);
1851 wadjust = LGLYPH_WADJUST (glyph);
1852 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1853 if (s->face->overstrike)
1854 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1855 false);
1856 x += wadjust;
1857 j = i + 1;
1858 width = 0;
1861 if (j < i)
1863 font->driver->draw (s, j, i, x, y, false);
1864 if (s->face->overstrike)
1865 font->driver->draw (s, j, i, x + 1, y, false);
1871 /* Draw the foreground of glyph string S for glyphless characters. */
1873 static void
1874 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1876 struct glyph *glyph = s->first_glyph;
1877 XChar2b char2b[8];
1878 int x, i, j;
1880 /* If first glyph of S has a left box line, start drawing the text
1881 of S to the right of that box line. */
1882 if (s->face && s->face->box != FACE_NO_BOX
1883 && s->first_glyph->left_box_line_p)
1884 x = s->x + eabs (s->face->box_line_width);
1885 else
1886 x = s->x;
1888 s->char2b = char2b;
1890 for (i = 0; i < s->nchars; i++, glyph++)
1892 char buf[7], *str = NULL;
1893 int len = glyph->u.glyphless.len;
1895 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1897 if (len > 0
1898 && CHAR_TABLE_P (Vglyphless_char_display)
1899 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1900 >= 1))
1902 Lisp_Object acronym
1903 = (! glyph->u.glyphless.for_no_font
1904 ? CHAR_TABLE_REF (Vglyphless_char_display,
1905 glyph->u.glyphless.ch)
1906 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1907 if (STRINGP (acronym))
1908 str = SSDATA (acronym);
1911 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1913 sprintf (buf, "%0*X",
1914 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1915 glyph->u.glyphless.ch + 0u);
1916 str = buf;
1919 if (str)
1921 int upper_len = (len + 1) / 2;
1922 unsigned code;
1924 /* It is assured that all LEN characters in STR is ASCII. */
1925 for (j = 0; j < len; j++)
1927 code = s->font->driver->encode_char (s->font, str[j]);
1928 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
1930 s->font->driver->draw (s, 0, upper_len,
1931 x + glyph->slice.glyphless.upper_xoff,
1932 s->ybase + glyph->slice.glyphless.upper_yoff,
1933 false);
1934 s->font->driver->draw (s, upper_len, len,
1935 x + glyph->slice.glyphless.lower_xoff,
1936 s->ybase + glyph->slice.glyphless.lower_yoff,
1937 false);
1939 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1940 x_draw_rectangle (s->f, s->gc,
1941 x, s->ybase - glyph->ascent,
1942 glyph->pixel_width - 1,
1943 glyph->ascent + glyph->descent - 1);
1944 x += glyph->pixel_width;
1948 #ifdef USE_X_TOOLKIT
1950 #ifdef USE_LUCID
1952 /* Return the frame on which widget WIDGET is used.. Abort if frame
1953 cannot be determined. */
1955 static struct frame *
1956 x_frame_of_widget (Widget widget)
1958 struct x_display_info *dpyinfo;
1959 Lisp_Object tail, frame;
1960 struct frame *f;
1962 dpyinfo = x_display_info_for_display (XtDisplay (widget));
1964 /* Find the top-level shell of the widget. Note that this function
1965 can be called when the widget is not yet realized, so XtWindow
1966 (widget) == 0. That's the reason we can't simply use
1967 x_any_window_to_frame. */
1968 while (!XtIsTopLevelShell (widget))
1969 widget = XtParent (widget);
1971 /* Look for a frame with that top-level widget. Allocate the color
1972 on that frame to get the right gamma correction value. */
1973 FOR_EACH_FRAME (tail, frame)
1975 f = XFRAME (frame);
1976 if (FRAME_X_P (f)
1977 && f->output_data.nothing != 1
1978 && FRAME_DISPLAY_INFO (f) == dpyinfo
1979 && f->output_data.x->widget == widget)
1980 return f;
1982 emacs_abort ();
1985 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
1986 or DELTA. Try a color with RGB values multiplied by FACTOR first.
1987 If this produces the same color as PIXEL, try a color where all RGB
1988 values have DELTA added. Return the allocated color in *PIXEL.
1989 DISPLAY is the X display, CMAP is the colormap to operate on.
1990 Value is true if successful. */
1992 bool
1993 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
1994 unsigned long *pixel, double factor, int delta)
1996 struct frame *f = x_frame_of_widget (widget);
1997 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2000 #endif /* USE_LUCID */
2003 /* Structure specifying which arguments should be passed by Xt to
2004 cvt_string_to_pixel. We want the widget's screen and colormap. */
2006 static XtConvertArgRec cvt_string_to_pixel_args[] =
2008 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2009 sizeof (Screen *)},
2010 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2011 sizeof (Colormap)}
2015 /* The address of this variable is returned by
2016 cvt_string_to_pixel. */
2018 static Pixel cvt_string_to_pixel_value;
2021 /* Convert a color name to a pixel color.
2023 DPY is the display we are working on.
2025 ARGS is an array of *NARGS XrmValue structures holding additional
2026 information about the widget for which the conversion takes place.
2027 The contents of this array are determined by the specification
2028 in cvt_string_to_pixel_args.
2030 FROM is a pointer to an XrmValue which points to the color name to
2031 convert. TO is an XrmValue in which to return the pixel color.
2033 CLOSURE_RET is a pointer to user-data, in which we record if
2034 we allocated the color or not.
2036 Value is True if successful, False otherwise. */
2038 static Boolean
2039 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2040 XrmValue *from, XrmValue *to,
2041 XtPointer *closure_ret)
2043 Screen *screen;
2044 Colormap cmap;
2045 Pixel pixel;
2046 String color_name;
2047 XColor color;
2049 if (*nargs != 2)
2051 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2052 "wrongParameters", "cvt_string_to_pixel",
2053 "XtToolkitError",
2054 "Screen and colormap args required", NULL, NULL);
2055 return False;
2058 screen = *(Screen **) args[0].addr;
2059 cmap = *(Colormap *) args[1].addr;
2060 color_name = (String) from->addr;
2062 if (strcmp (color_name, XtDefaultBackground) == 0)
2064 *closure_ret = (XtPointer) False;
2065 pixel = WhitePixelOfScreen (screen);
2067 else if (strcmp (color_name, XtDefaultForeground) == 0)
2069 *closure_ret = (XtPointer) False;
2070 pixel = BlackPixelOfScreen (screen);
2072 else if (XParseColor (dpy, cmap, color_name, &color)
2073 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2075 pixel = color.pixel;
2076 *closure_ret = (XtPointer) True;
2078 else
2080 String params[1];
2081 Cardinal nparams = 1;
2083 params[0] = color_name;
2084 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2085 "badValue", "cvt_string_to_pixel",
2086 "XtToolkitError", "Invalid color '%s'",
2087 params, &nparams);
2088 return False;
2091 if (to->addr != NULL)
2093 if (to->size < sizeof (Pixel))
2095 to->size = sizeof (Pixel);
2096 return False;
2099 *(Pixel *) to->addr = pixel;
2101 else
2103 cvt_string_to_pixel_value = pixel;
2104 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2107 to->size = sizeof (Pixel);
2108 return True;
2112 /* Free a pixel color which was previously allocated via
2113 cvt_string_to_pixel. This is registered as the destructor
2114 for this type of resource via XtSetTypeConverter.
2116 APP is the application context in which we work.
2118 TO is a pointer to an XrmValue holding the color to free.
2119 CLOSURE is the value we stored in CLOSURE_RET for this color
2120 in cvt_string_to_pixel.
2122 ARGS and NARGS are like for cvt_string_to_pixel. */
2124 static void
2125 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2126 Cardinal *nargs)
2128 if (*nargs != 2)
2130 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2131 "XtToolkitError",
2132 "Screen and colormap arguments required",
2133 NULL, NULL);
2135 else if (closure != NULL)
2137 /* We did allocate the pixel, so free it. */
2138 Screen *screen = *(Screen **) args[0].addr;
2139 Colormap cmap = *(Colormap *) args[1].addr;
2140 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2141 (Pixel *) to->addr, 1);
2146 #endif /* USE_X_TOOLKIT */
2149 /* Value is an array of XColor structures for the contents of the
2150 color map of display DPY. Set *NCELLS to the size of the array.
2151 Note that this probably shouldn't be called for large color maps,
2152 say a 24-bit TrueColor map. */
2154 static const XColor *
2155 x_color_cells (Display *dpy, int *ncells)
2157 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2158 eassume (dpyinfo);
2160 if (dpyinfo->color_cells == NULL)
2162 Screen *screen = dpyinfo->screen;
2163 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2164 int i;
2166 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2167 sizeof *dpyinfo->color_cells);
2168 dpyinfo->ncolor_cells = ncolor_cells;
2170 for (i = 0; i < ncolor_cells; ++i)
2171 dpyinfo->color_cells[i].pixel = i;
2173 XQueryColors (dpy, dpyinfo->cmap,
2174 dpyinfo->color_cells, ncolor_cells);
2177 *ncells = dpyinfo->ncolor_cells;
2178 return dpyinfo->color_cells;
2182 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2183 colors in COLORS. Use cached information, if available. */
2185 void
2186 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2188 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2190 if (dpyinfo->red_bits > 0)
2192 /* For TrueColor displays, we can decompose the RGB value
2193 directly. */
2194 int i;
2195 unsigned int rmult, gmult, bmult;
2196 unsigned int rmask, gmask, bmask;
2198 rmask = (1 << dpyinfo->red_bits) - 1;
2199 gmask = (1 << dpyinfo->green_bits) - 1;
2200 bmask = (1 << dpyinfo->blue_bits) - 1;
2201 /* If we're widening, for example, 8 bits in the pixel value to
2202 16 bits for the separate-color representation, we want to
2203 extrapolate the lower bits based on those bits available --
2204 in other words, we'd like 0xff to become 0xffff instead of
2205 the 0xff00 we'd get by just zero-filling the lower bits.
2207 We generate a 32-bit scaled-up value and shift it, in case
2208 the bit count doesn't divide 16 evenly (e.g., when dealing
2209 with a 3-3-2 bit RGB display), to get more of the lower bits
2210 correct.
2212 Should we cache the multipliers in dpyinfo? Maybe
2213 special-case the 8-8-8 common case? */
2214 rmult = 0xffffffff / rmask;
2215 gmult = 0xffffffff / gmask;
2216 bmult = 0xffffffff / bmask;
2218 for (i = 0; i < ncolors; ++i)
2220 unsigned int r, g, b;
2221 unsigned long pixel = colors[i].pixel;
2223 r = (pixel >> dpyinfo->red_offset) & rmask;
2224 g = (pixel >> dpyinfo->green_offset) & gmask;
2225 b = (pixel >> dpyinfo->blue_offset) & bmask;
2227 colors[i].red = (r * rmult) >> 16;
2228 colors[i].green = (g * gmult) >> 16;
2229 colors[i].blue = (b * bmult) >> 16;
2231 return;
2234 if (dpyinfo->color_cells)
2236 int i;
2237 for (i = 0; i < ncolors; ++i)
2239 unsigned long pixel = colors[i].pixel;
2240 eassert (pixel < dpyinfo->ncolor_cells);
2241 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2242 colors[i] = dpyinfo->color_cells[pixel];
2244 return;
2247 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2251 /* On frame F, translate pixel color to RGB values for the color in
2252 COLOR. Use cached information, if available. */
2254 void
2255 x_query_color (struct frame *f, XColor *color)
2257 x_query_colors (f, color, 1);
2261 /* On frame F, translate the color name to RGB values. Use cached
2262 information, if possible.
2264 Note that there is currently no way to clean old entries out of the
2265 cache. However, it is limited to names in the server's database,
2266 and names we've actually looked up; list-colors-display is probably
2267 the most color-intensive case we're likely to hit. */
2269 Status x_parse_color (struct frame *f, const char *color_name,
2270 XColor *color)
2272 Display *dpy = FRAME_X_DISPLAY (f);
2273 Colormap cmap = FRAME_X_COLORMAP (f);
2274 struct color_name_cache_entry *cache_entry;
2276 if (color_name[0] == '#')
2278 /* The hex form is parsed directly by XParseColor without
2279 talking to the X server. No need for caching. */
2280 return XParseColor (dpy, cmap, color_name, color);
2283 for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
2284 cache_entry = cache_entry->next)
2286 if (!xstrcasecmp(cache_entry->name, color_name))
2288 *color = cache_entry->rgb;
2289 return 1;
2293 if (XParseColor (dpy, cmap, color_name, color) == 0)
2294 /* No caching of negative results, currently. */
2295 return 0;
2297 cache_entry = xzalloc (sizeof *cache_entry);
2298 cache_entry->rgb = *color;
2299 cache_entry->name = xstrdup (color_name);
2300 cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names;
2301 FRAME_DISPLAY_INFO (f)->color_names = cache_entry;
2302 return 1;
2306 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2307 exact match can't be allocated, try the nearest color available.
2308 Value is true if successful. Set *COLOR to the color
2309 allocated. */
2311 static bool
2312 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2314 bool rc;
2316 rc = XAllocColor (dpy, cmap, color) != 0;
2317 if (rc == 0)
2319 /* If we got to this point, the colormap is full, so we're going
2320 to try to get the next closest color. The algorithm used is
2321 a least-squares matching, which is what X uses for closest
2322 color matching with StaticColor visuals. */
2323 int nearest, i;
2324 int max_color_delta = 255;
2325 int max_delta = 3 * max_color_delta;
2326 int nearest_delta = max_delta + 1;
2327 int ncells;
2328 const XColor *cells = x_color_cells (dpy, &ncells);
2330 for (nearest = i = 0; i < ncells; ++i)
2332 int dred = (color->red >> 8) - (cells[i].red >> 8);
2333 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2334 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2335 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2337 if (delta < nearest_delta)
2339 nearest = i;
2340 nearest_delta = delta;
2344 color->red = cells[nearest].red;
2345 color->green = cells[nearest].green;
2346 color->blue = cells[nearest].blue;
2347 rc = XAllocColor (dpy, cmap, color) != 0;
2349 else
2351 /* If allocation succeeded, and the allocated pixel color is not
2352 equal to a cached pixel color recorded earlier, there was a
2353 change in the colormap, so clear the color cache. */
2354 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2355 eassume (dpyinfo);
2357 if (dpyinfo->color_cells)
2359 XColor *cached_color = &dpyinfo->color_cells[color->pixel];
2360 if (cached_color->red != color->red
2361 || cached_color->blue != color->blue
2362 || cached_color->green != color->green)
2364 xfree (dpyinfo->color_cells);
2365 dpyinfo->color_cells = NULL;
2366 dpyinfo->ncolor_cells = 0;
2371 #ifdef DEBUG_X_COLORS
2372 if (rc)
2373 register_color (color->pixel);
2374 #endif /* DEBUG_X_COLORS */
2376 return rc;
2380 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
2381 gamma correction. If an exact match can't be allocated, try the
2382 nearest color available. Value is true if successful. Set *COLOR
2383 to the color allocated. */
2385 bool
2386 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2388 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2390 gamma_correct (f, color);
2392 if (dpyinfo->red_bits > 0)
2394 color->pixel = x_make_truecolor_pixel (dpyinfo,
2395 color->red,
2396 color->green,
2397 color->blue);
2398 return true;
2401 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2405 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2406 It's necessary to do this instead of just using PIXEL directly to
2407 get color reference counts right. */
2409 unsigned long
2410 x_copy_color (struct frame *f, unsigned long pixel)
2412 XColor color;
2414 /* If display has an immutable color map, freeing colors is not
2415 necessary and some servers don't allow it. Since we won't free a
2416 color once we've allocated it, we don't need to re-allocate it to
2417 maintain the server's reference count. */
2418 if (!x_mutable_colormap (FRAME_X_VISUAL (f)))
2419 return pixel;
2421 color.pixel = pixel;
2422 block_input ();
2423 /* The color could still be found in the color_cells array. */
2424 x_query_color (f, &color);
2425 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2426 unblock_input ();
2427 #ifdef DEBUG_X_COLORS
2428 register_color (pixel);
2429 #endif
2430 return color.pixel;
2434 /* Brightness beyond which a color won't have its highlight brightness
2435 boosted.
2437 Nominally, highlight colors for `3d' faces are calculated by
2438 brightening an object's color by a constant scale factor, but this
2439 doesn't yield good results for dark colors, so for colors who's
2440 brightness is less than this value (on a scale of 0-65535) have an
2441 use an additional additive factor.
2443 The value here is set so that the default menu-bar/mode-line color
2444 (grey75) will not have its highlights changed at all. */
2445 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2448 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2449 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2450 If this produces the same color as PIXEL, try a color where all RGB
2451 values have DELTA added. Return the allocated color in *PIXEL.
2452 DISPLAY is the X display, CMAP is the colormap to operate on.
2453 Value is non-zero if successful. */
2455 static bool
2456 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2457 unsigned long *pixel, double factor, int delta)
2459 XColor color, new;
2460 long bright;
2461 bool success_p;
2463 /* Get RGB color values. */
2464 color.pixel = *pixel;
2465 x_query_color (f, &color);
2467 /* Change RGB values by specified FACTOR. Avoid overflow! */
2468 eassert (factor >= 0);
2469 new.red = min (0xffff, factor * color.red);
2470 new.green = min (0xffff, factor * color.green);
2471 new.blue = min (0xffff, factor * color.blue);
2473 /* Calculate brightness of COLOR. */
2474 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2476 /* We only boost colors that are darker than
2477 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2478 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2479 /* Make an additive adjustment to NEW, because it's dark enough so
2480 that scaling by FACTOR alone isn't enough. */
2482 /* How far below the limit this color is (0 - 1, 1 being darker). */
2483 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2484 /* The additive adjustment. */
2485 int min_delta = delta * dimness * factor / 2;
2487 if (factor < 1)
2489 new.red = max (0, new.red - min_delta);
2490 new.green = max (0, new.green - min_delta);
2491 new.blue = max (0, new.blue - min_delta);
2493 else
2495 new.red = min (0xffff, min_delta + new.red);
2496 new.green = min (0xffff, min_delta + new.green);
2497 new.blue = min (0xffff, min_delta + new.blue);
2501 /* Try to allocate the color. */
2502 success_p = x_alloc_nearest_color (f, cmap, &new);
2503 if (success_p)
2505 if (new.pixel == *pixel)
2507 /* If we end up with the same color as before, try adding
2508 delta to the RGB values. */
2509 x_free_colors (f, &new.pixel, 1);
2511 new.red = min (0xffff, delta + color.red);
2512 new.green = min (0xffff, delta + color.green);
2513 new.blue = min (0xffff, delta + color.blue);
2514 success_p = x_alloc_nearest_color (f, cmap, &new);
2516 else
2517 success_p = true;
2518 *pixel = new.pixel;
2521 return success_p;
2525 /* Set up the foreground color for drawing relief lines of glyph
2526 string S. RELIEF is a pointer to a struct relief containing the GC
2527 with which lines will be drawn. Use a color that is FACTOR or
2528 DELTA lighter or darker than the relief's background which is found
2529 in S->f->output_data.x->relief_background. If such a color cannot
2530 be allocated, use DEFAULT_PIXEL, instead. */
2532 static void
2533 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2534 int delta, unsigned long default_pixel)
2536 XGCValues xgcv;
2537 struct x_output *di = f->output_data.x;
2538 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2539 unsigned long pixel;
2540 unsigned long background = di->relief_background;
2541 Colormap cmap = FRAME_X_COLORMAP (f);
2542 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2543 Display *dpy = FRAME_X_DISPLAY (f);
2545 xgcv.graphics_exposures = False;
2546 xgcv.line_width = 1;
2548 /* Free previously allocated color. The color cell will be reused
2549 when it has been freed as many times as it was allocated, so this
2550 doesn't affect faces using the same colors. */
2551 if (relief->gc && relief->pixel != -1)
2553 x_free_colors (f, &relief->pixel, 1);
2554 relief->pixel = -1;
2557 /* Allocate new color. */
2558 xgcv.foreground = default_pixel;
2559 pixel = background;
2560 if (dpyinfo->n_planes != 1
2561 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2562 xgcv.foreground = relief->pixel = pixel;
2564 if (relief->gc == 0)
2566 xgcv.stipple = dpyinfo->gray;
2567 mask |= GCStipple;
2568 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
2570 else
2571 XChangeGC (dpy, relief->gc, mask, &xgcv);
2575 /* Set up colors for the relief lines around glyph string S. */
2577 static void
2578 x_setup_relief_colors (struct glyph_string *s)
2580 struct x_output *di = s->f->output_data.x;
2581 unsigned long color;
2583 if (s->face->use_box_color_for_shadows_p)
2584 color = s->face->box_color;
2585 else if (s->first_glyph->type == IMAGE_GLYPH
2586 && s->img->pixmap
2587 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2588 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2589 else
2591 XGCValues xgcv;
2593 /* Get the background color of the face. */
2594 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2595 color = xgcv.background;
2598 if (di->white_relief.gc == 0
2599 || color != di->relief_background)
2601 di->relief_background = color;
2602 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2603 WHITE_PIX_DEFAULT (s->f));
2604 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2605 BLACK_PIX_DEFAULT (s->f));
2610 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2611 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2612 to draw, it must be >= 0. RAISED_P means draw a raised
2613 relief. LEFT_P means draw a relief on the left side of
2614 the rectangle. RIGHT_P means draw a relief on the right
2615 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2616 when drawing. */
2618 static void
2619 x_draw_relief_rect (struct frame *f,
2620 int left_x, int top_y, int right_x, int bottom_y,
2621 int width, bool raised_p, bool top_p, bool bot_p,
2622 bool left_p, bool right_p,
2623 XRectangle *clip_rect)
2625 #ifdef USE_CAIRO
2626 GC top_left_gc, bottom_right_gc;
2627 int corners = 0;
2629 if (raised_p)
2631 top_left_gc = f->output_data.x->white_relief.gc;
2632 bottom_right_gc = f->output_data.x->black_relief.gc;
2634 else
2636 top_left_gc = f->output_data.x->black_relief.gc;
2637 bottom_right_gc = f->output_data.x->white_relief.gc;
2640 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2641 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2643 if (left_p)
2645 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2646 width, bottom_y + 1 - top_y);
2647 if (top_p)
2648 corners |= 1 << CORNER_TOP_LEFT;
2649 if (bot_p)
2650 corners |= 1 << CORNER_BOTTOM_LEFT;
2652 if (right_p)
2654 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2655 width, bottom_y + 1 - top_y);
2656 if (top_p)
2657 corners |= 1 << CORNER_TOP_RIGHT;
2658 if (bot_p)
2659 corners |= 1 << CORNER_BOTTOM_RIGHT;
2661 if (top_p)
2663 if (!right_p)
2664 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2665 right_x + 1 - left_x, width);
2666 else
2667 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2668 right_x + 1 - left_x, width, 1);
2670 if (bot_p)
2672 if (!left_p)
2673 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2674 right_x + 1 - left_x, width);
2675 else
2676 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2677 left_x, bottom_y + 1 - width,
2678 right_x + 1 - left_x, width, 0);
2680 if (left_p && width != 1)
2681 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2682 1, bottom_y + 1 - top_y);
2683 if (top_p && width != 1)
2684 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2685 right_x + 1 - left_x, 1);
2686 if (corners)
2688 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2689 FRAME_BACKGROUND_PIXEL (f));
2690 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2691 right_x - left_x + 1, bottom_y - top_y + 1,
2692 6, 1, corners);
2695 x_reset_clip_rectangles (f, top_left_gc);
2696 x_reset_clip_rectangles (f, bottom_right_gc);
2697 #else
2698 Display *dpy = FRAME_X_DISPLAY (f);
2699 Window window = FRAME_X_WINDOW (f);
2700 int i;
2701 GC gc;
2703 if (raised_p)
2704 gc = f->output_data.x->white_relief.gc;
2705 else
2706 gc = f->output_data.x->black_relief.gc;
2707 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2709 /* This code is more complicated than it has to be, because of two
2710 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2711 the outermost line using the black relief. (ii) Omit the four
2712 corner pixels. */
2714 /* Top. */
2715 if (top_p)
2717 if (width == 1)
2718 XDrawLine (dpy, window, gc,
2719 left_x + left_p, top_y,
2720 right_x + !right_p, top_y);
2722 for (i = 1; i < width; ++i)
2723 XDrawLine (dpy, window, gc,
2724 left_x + i * left_p, top_y + i,
2725 right_x + 1 - i * right_p, top_y + i);
2728 /* Left. */
2729 if (left_p)
2731 if (width == 1)
2732 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2734 XClearArea (dpy, window, left_x, top_y, 1, 1, False);
2735 XClearArea (dpy, window, left_x, bottom_y, 1, 1, False);
2737 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2738 XDrawLine (dpy, window, gc,
2739 left_x + i, top_y + (i + 1) * top_p,
2740 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2743 XSetClipMask (dpy, gc, None);
2744 if (raised_p)
2745 gc = f->output_data.x->black_relief.gc;
2746 else
2747 gc = f->output_data.x->white_relief.gc;
2748 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2750 if (width > 1)
2752 /* Outermost top line. */
2753 if (top_p)
2754 XDrawLine (dpy, window, gc,
2755 left_x + left_p, top_y,
2756 right_x + !right_p, top_y);
2758 /* Outermost left line. */
2759 if (left_p)
2760 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2763 /* Bottom. */
2764 if (bot_p)
2766 XDrawLine (dpy, window, gc,
2767 left_x + left_p, bottom_y,
2768 right_x + !right_p, bottom_y);
2769 for (i = 1; i < width; ++i)
2770 XDrawLine (dpy, window, gc,
2771 left_x + i * left_p, bottom_y - i,
2772 right_x + 1 - i * right_p, bottom_y - i);
2775 /* Right. */
2776 if (right_p)
2778 XClearArea (dpy, window, right_x, top_y, 1, 1, False);
2779 XClearArea (dpy, window, right_x, bottom_y, 1, 1, False);
2780 for (i = 0; i < width; ++i)
2781 XDrawLine (dpy, window, gc,
2782 right_x - i, top_y + (i + 1) * top_p,
2783 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2786 x_reset_clip_rectangles (f, gc);
2788 #endif
2792 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2793 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2794 draw, it must be >= 0. LEFT_P means draw a line on the
2795 left side of the rectangle. RIGHT_P means draw a line
2796 on the right side of the rectangle. CLIP_RECT is the clipping
2797 rectangle to use when drawing. */
2799 static void
2800 x_draw_box_rect (struct glyph_string *s,
2801 int left_x, int top_y, int right_x, int bottom_y, int width,
2802 bool left_p, bool right_p, XRectangle *clip_rect)
2804 XGCValues xgcv;
2806 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2807 XSetForeground (s->display, s->gc, s->face->box_color);
2808 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2810 /* Top. */
2811 x_fill_rectangle (s->f, s->gc,
2812 left_x, top_y, right_x - left_x + 1, width);
2814 /* Left. */
2815 if (left_p)
2816 x_fill_rectangle (s->f, s->gc,
2817 left_x, top_y, width, bottom_y - top_y + 1);
2819 /* Bottom. */
2820 x_fill_rectangle (s->f, s->gc,
2821 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2823 /* Right. */
2824 if (right_p)
2825 x_fill_rectangle (s->f, s->gc,
2826 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2828 XSetForeground (s->display, s->gc, xgcv.foreground);
2829 x_reset_clip_rectangles (s->f, s->gc);
2833 /* Draw a box around glyph string S. */
2835 static void
2836 x_draw_glyph_string_box (struct glyph_string *s)
2838 int width, left_x, right_x, top_y, bottom_y, last_x;
2839 bool raised_p, left_p, right_p;
2840 struct glyph *last_glyph;
2841 XRectangle clip_rect;
2843 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2844 ? WINDOW_RIGHT_EDGE_X (s->w)
2845 : window_box_right (s->w, s->area));
2847 /* The glyph that may have a right box line. */
2848 last_glyph = (s->cmp || s->img
2849 ? s->first_glyph
2850 : s->first_glyph + s->nchars - 1);
2852 width = eabs (s->face->box_line_width);
2853 raised_p = s->face->box == FACE_RAISED_BOX;
2854 left_x = s->x;
2855 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2856 ? last_x - 1
2857 : min (last_x, s->x + s->background_width) - 1);
2858 top_y = s->y;
2859 bottom_y = top_y + s->height - 1;
2861 left_p = (s->first_glyph->left_box_line_p
2862 || (s->hl == DRAW_MOUSE_FACE
2863 && (s->prev == NULL
2864 || s->prev->hl != s->hl)));
2865 right_p = (last_glyph->right_box_line_p
2866 || (s->hl == DRAW_MOUSE_FACE
2867 && (s->next == NULL
2868 || s->next->hl != s->hl)));
2870 get_glyph_string_clip_rect (s, &clip_rect);
2872 if (s->face->box == FACE_SIMPLE_BOX)
2873 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2874 left_p, right_p, &clip_rect);
2875 else
2877 x_setup_relief_colors (s);
2878 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2879 width, raised_p, true, true, left_p, right_p,
2880 &clip_rect);
2885 /* Draw foreground of image glyph string S. */
2887 static void
2888 x_draw_image_foreground (struct glyph_string *s)
2890 int x = s->x;
2891 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2893 /* If first glyph of S has a left box line, start drawing it to the
2894 right of that line. */
2895 if (s->face->box != FACE_NO_BOX
2896 && s->first_glyph->left_box_line_p
2897 && s->slice.x == 0)
2898 x += eabs (s->face->box_line_width);
2900 /* If there is a margin around the image, adjust x- and y-position
2901 by that margin. */
2902 if (s->slice.x == 0)
2903 x += s->img->hmargin;
2904 if (s->slice.y == 0)
2905 y += s->img->vmargin;
2907 if (s->img->pixmap)
2909 if (s->img->mask)
2911 /* We can't set both a clip mask and use XSetClipRectangles
2912 because the latter also sets a clip mask. We also can't
2913 trust on the shape extension to be available
2914 (XShapeCombineRegion). So, compute the rectangle to draw
2915 manually. */
2916 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2917 | GCFunction);
2918 XGCValues xgcv;
2919 XRectangle clip_rect, image_rect, r;
2921 xgcv.clip_mask = s->img->mask;
2922 xgcv.clip_x_origin = x;
2923 xgcv.clip_y_origin = y;
2924 xgcv.function = GXcopy;
2925 XChangeGC (s->display, s->gc, mask, &xgcv);
2927 get_glyph_string_clip_rect (s, &clip_rect);
2928 image_rect.x = x;
2929 image_rect.y = y;
2930 image_rect.width = s->slice.width;
2931 image_rect.height = s->slice.height;
2932 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2933 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2934 s->slice.x + r.x - x, s->slice.y + r.y - y,
2935 r.width, r.height, r.x, r.y);
2937 else
2939 XRectangle clip_rect, image_rect, r;
2941 get_glyph_string_clip_rect (s, &clip_rect);
2942 image_rect.x = x;
2943 image_rect.y = y;
2944 image_rect.width = s->slice.width;
2945 image_rect.height = s->slice.height;
2946 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2947 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2948 s->slice.x + r.x - x, s->slice.y + r.y - y,
2949 r.width, r.height, r.x, r.y);
2951 /* When the image has a mask, we can expect that at
2952 least part of a mouse highlight or a block cursor will
2953 be visible. If the image doesn't have a mask, make
2954 a block cursor visible by drawing a rectangle around
2955 the image. I believe it's looking better if we do
2956 nothing here for mouse-face. */
2957 if (s->hl == DRAW_CURSOR)
2959 int relief = eabs (s->img->relief);
2960 x_draw_rectangle (s->f, s->gc,
2961 x - relief, y - relief,
2962 s->slice.width + relief*2 - 1,
2963 s->slice.height + relief*2 - 1);
2967 else
2968 /* Draw a rectangle if image could not be loaded. */
2969 x_draw_rectangle (s->f, s->gc, x, y,
2970 s->slice.width - 1, s->slice.height - 1);
2974 /* Draw a relief around the image glyph string S. */
2976 static void
2977 x_draw_image_relief (struct glyph_string *s)
2979 int x1, y1, thick;
2980 bool raised_p, top_p, bot_p, left_p, right_p;
2981 int extra_x, extra_y;
2982 XRectangle r;
2983 int x = s->x;
2984 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2986 /* If first glyph of S has a left box line, start drawing it to the
2987 right of that line. */
2988 if (s->face->box != FACE_NO_BOX
2989 && s->first_glyph->left_box_line_p
2990 && s->slice.x == 0)
2991 x += eabs (s->face->box_line_width);
2993 /* If there is a margin around the image, adjust x- and y-position
2994 by that margin. */
2995 if (s->slice.x == 0)
2996 x += s->img->hmargin;
2997 if (s->slice.y == 0)
2998 y += s->img->vmargin;
3000 if (s->hl == DRAW_IMAGE_SUNKEN
3001 || s->hl == DRAW_IMAGE_RAISED)
3003 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3004 raised_p = s->hl == DRAW_IMAGE_RAISED;
3006 else
3008 thick = eabs (s->img->relief);
3009 raised_p = s->img->relief > 0;
3012 x1 = x + s->slice.width - 1;
3013 y1 = y + s->slice.height - 1;
3015 extra_x = extra_y = 0;
3016 if (s->face->id == TOOL_BAR_FACE_ID)
3018 if (CONSP (Vtool_bar_button_margin)
3019 && INTEGERP (XCAR (Vtool_bar_button_margin))
3020 && INTEGERP (XCDR (Vtool_bar_button_margin)))
3022 extra_x = XINT (XCAR (Vtool_bar_button_margin));
3023 extra_y = XINT (XCDR (Vtool_bar_button_margin));
3025 else if (INTEGERP (Vtool_bar_button_margin))
3026 extra_x = extra_y = XINT (Vtool_bar_button_margin);
3029 top_p = bot_p = left_p = right_p = false;
3031 if (s->slice.x == 0)
3032 x -= thick + extra_x, left_p = true;
3033 if (s->slice.y == 0)
3034 y -= thick + extra_y, top_p = true;
3035 if (s->slice.x + s->slice.width == s->img->width)
3036 x1 += thick + extra_x, right_p = true;
3037 if (s->slice.y + s->slice.height == s->img->height)
3038 y1 += thick + extra_y, bot_p = true;
3040 x_setup_relief_colors (s);
3041 get_glyph_string_clip_rect (s, &r);
3042 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
3043 top_p, bot_p, left_p, right_p, &r);
3047 /* Draw the foreground of image glyph string S to PIXMAP. */
3049 static void
3050 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3052 int x = 0;
3053 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
3055 /* If first glyph of S has a left box line, start drawing it to the
3056 right of that line. */
3057 if (s->face->box != FACE_NO_BOX
3058 && s->first_glyph->left_box_line_p
3059 && s->slice.x == 0)
3060 x += eabs (s->face->box_line_width);
3062 /* If there is a margin around the image, adjust x- and y-position
3063 by that margin. */
3064 if (s->slice.x == 0)
3065 x += s->img->hmargin;
3066 if (s->slice.y == 0)
3067 y += s->img->vmargin;
3069 if (s->img->pixmap)
3071 if (s->img->mask)
3073 /* We can't set both a clip mask and use XSetClipRectangles
3074 because the latter also sets a clip mask. We also can't
3075 trust on the shape extension to be available
3076 (XShapeCombineRegion). So, compute the rectangle to draw
3077 manually. */
3078 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3079 | GCFunction);
3080 XGCValues xgcv;
3082 xgcv.clip_mask = s->img->mask;
3083 xgcv.clip_x_origin = x - s->slice.x;
3084 xgcv.clip_y_origin = y - s->slice.y;
3085 xgcv.function = GXcopy;
3086 XChangeGC (s->display, s->gc, mask, &xgcv);
3088 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3089 s->slice.x, s->slice.y,
3090 s->slice.width, s->slice.height, x, y);
3091 XSetClipMask (s->display, s->gc, None);
3093 else
3095 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3096 s->slice.x, s->slice.y,
3097 s->slice.width, s->slice.height, x, y);
3099 /* When the image has a mask, we can expect that at
3100 least part of a mouse highlight or a block cursor will
3101 be visible. If the image doesn't have a mask, make
3102 a block cursor visible by drawing a rectangle around
3103 the image. I believe it's looking better if we do
3104 nothing here for mouse-face. */
3105 if (s->hl == DRAW_CURSOR)
3107 int r = eabs (s->img->relief);
3108 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3109 s->slice.width + r*2 - 1,
3110 s->slice.height + r*2 - 1);
3114 else
3115 /* Draw a rectangle if image could not be loaded. */
3116 x_draw_rectangle (s->f, s->gc, x, y,
3117 s->slice.width - 1, s->slice.height - 1);
3121 /* Draw part of the background of glyph string S. X, Y, W, and H
3122 give the rectangle to draw. */
3124 static void
3125 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3127 if (s->stippled_p)
3129 /* Fill background with a stipple pattern. */
3130 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3131 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3132 XSetFillStyle (s->display, s->gc, FillSolid);
3134 else
3135 x_clear_glyph_string_rect (s, x, y, w, h);
3139 /* Draw image glyph string S.
3141 s->y
3142 s->x +-------------------------
3143 | s->face->box
3145 | +-------------------------
3146 | | s->img->margin
3148 | | +-------------------
3149 | | | the image
3153 static void
3154 x_draw_image_glyph_string (struct glyph_string *s)
3156 int box_line_hwidth = eabs (s->face->box_line_width);
3157 int box_line_vwidth = max (s->face->box_line_width, 0);
3158 int height;
3159 Pixmap pixmap = None;
3161 height = s->height;
3162 if (s->slice.y == 0)
3163 height -= box_line_vwidth;
3164 if (s->slice.y + s->slice.height >= s->img->height)
3165 height -= box_line_vwidth;
3167 /* Fill background with face under the image. Do it only if row is
3168 taller than image or if image has a clip mask to reduce
3169 flickering. */
3170 s->stippled_p = s->face->stipple != 0;
3171 if (height > s->slice.height
3172 || s->img->hmargin
3173 || s->img->vmargin
3174 || s->img->mask
3175 || s->img->pixmap == 0
3176 || s->width != s->background_width)
3178 if (s->img->mask)
3180 /* Create a pixmap as large as the glyph string. Fill it
3181 with the background color. Copy the image to it, using
3182 its mask. Copy the temporary pixmap to the display. */
3183 Screen *screen = FRAME_X_SCREEN (s->f);
3184 int depth = DefaultDepthOfScreen (screen);
3186 /* Create a pixmap as large as the glyph string. */
3187 pixmap = XCreatePixmap (s->display, s->window,
3188 s->background_width,
3189 s->height, depth);
3191 /* Don't clip in the following because we're working on the
3192 pixmap. */
3193 XSetClipMask (s->display, s->gc, None);
3195 /* Fill the pixmap with the background color/stipple. */
3196 if (s->stippled_p)
3198 /* Fill background with a stipple pattern. */
3199 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3200 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3201 XFillRectangle (s->display, pixmap, s->gc,
3202 0, 0, s->background_width, s->height);
3203 XSetFillStyle (s->display, s->gc, FillSolid);
3204 XSetTSOrigin (s->display, s->gc, 0, 0);
3206 else
3208 XGCValues xgcv;
3209 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3210 &xgcv);
3211 XSetForeground (s->display, s->gc, xgcv.background);
3212 XFillRectangle (s->display, pixmap, s->gc,
3213 0, 0, s->background_width, s->height);
3214 XSetForeground (s->display, s->gc, xgcv.foreground);
3217 else
3219 int x = s->x;
3220 int y = s->y;
3221 int width = s->background_width;
3223 if (s->first_glyph->left_box_line_p
3224 && s->slice.x == 0)
3226 x += box_line_hwidth;
3227 width -= box_line_hwidth;
3230 if (s->slice.y == 0)
3231 y += box_line_vwidth;
3233 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3236 s->background_filled_p = true;
3239 /* Draw the foreground. */
3240 #ifdef USE_CAIRO
3241 if (s->img->cr_data)
3243 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3245 int x = s->x + s->img->hmargin;
3246 int y = s->y + s->img->vmargin;
3247 int width = s->background_width;
3249 cairo_set_source_surface (cr, s->img->cr_data,
3250 x - s->slice.x,
3251 y - s->slice.y);
3252 cairo_rectangle (cr, x, y, width, height);
3253 cairo_fill (cr);
3254 x_end_cr_clip (s->f);
3256 else
3257 #endif
3258 if (pixmap != None)
3260 x_draw_image_foreground_1 (s, pixmap);
3261 x_set_glyph_string_clipping (s);
3262 XCopyArea (s->display, pixmap, s->window, s->gc,
3263 0, 0, s->background_width, s->height, s->x, s->y);
3264 XFreePixmap (s->display, pixmap);
3266 else
3267 x_draw_image_foreground (s);
3269 /* If we must draw a relief around the image, do it. */
3270 if (s->img->relief
3271 || s->hl == DRAW_IMAGE_RAISED
3272 || s->hl == DRAW_IMAGE_SUNKEN)
3273 x_draw_image_relief (s);
3277 /* Draw stretch glyph string S. */
3279 static void
3280 x_draw_stretch_glyph_string (struct glyph_string *s)
3282 eassert (s->first_glyph->type == STRETCH_GLYPH);
3284 if (s->hl == DRAW_CURSOR
3285 && !x_stretch_cursor_p)
3287 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3288 wide as the stretch glyph. */
3289 int width, background_width = s->background_width;
3290 int x = s->x;
3292 if (!s->row->reversed_p)
3294 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3296 if (x < left_x)
3298 background_width -= left_x - x;
3299 x = left_x;
3302 else
3304 /* In R2L rows, draw the cursor on the right edge of the
3305 stretch glyph. */
3306 int right_x = window_box_right (s->w, TEXT_AREA);
3308 if (x + background_width > right_x)
3309 background_width -= x - right_x;
3310 x += background_width;
3312 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3313 if (s->row->reversed_p)
3314 x -= width;
3316 /* Draw cursor. */
3317 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3319 /* Clear rest using the GC of the original non-cursor face. */
3320 if (width < background_width)
3322 int y = s->y;
3323 int w = background_width - width, h = s->height;
3324 XRectangle r;
3325 GC gc;
3327 if (!s->row->reversed_p)
3328 x += width;
3329 else
3330 x = s->x;
3331 if (s->row->mouse_face_p
3332 && cursor_in_mouse_face_p (s->w))
3334 x_set_mouse_face_gc (s);
3335 gc = s->gc;
3337 else
3338 gc = s->face->gc;
3340 get_glyph_string_clip_rect (s, &r);
3341 x_set_clip_rectangles (s->f, gc, &r, 1);
3343 if (s->face->stipple)
3345 /* Fill background with a stipple pattern. */
3346 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3347 x_fill_rectangle (s->f, gc, x, y, w, h);
3348 XSetFillStyle (s->display, gc, FillSolid);
3350 else
3352 XGCValues xgcv;
3353 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3354 XSetForeground (s->display, gc, xgcv.background);
3355 x_fill_rectangle (s->f, gc, x, y, w, h);
3356 XSetForeground (s->display, gc, xgcv.foreground);
3359 x_reset_clip_rectangles (s->f, gc);
3362 else if (!s->background_filled_p)
3364 int background_width = s->background_width;
3365 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3367 /* Don't draw into left margin, fringe or scrollbar area
3368 except for header line and mode line. */
3369 if (x < left_x && !s->row->mode_line_p)
3371 background_width -= left_x - x;
3372 x = left_x;
3374 if (background_width > 0)
3375 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3378 s->background_filled_p = true;
3382 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3384 x0 wave_length = 2
3386 y0 * * * * *
3387 |* * * * * * * * *
3388 wave_height = 3 | * * * *
3392 static void
3393 x_draw_underwave (struct glyph_string *s)
3395 int wave_height = 3, wave_length = 2;
3396 #ifdef USE_CAIRO
3397 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3398 s->width, wave_height, wave_length);
3399 #else /* not USE_CAIRO */
3400 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3401 bool odd;
3402 XRectangle wave_clip, string_clip, final_clip;
3404 dx = wave_length;
3405 dy = wave_height - 1;
3406 x0 = s->x;
3407 y0 = s->ybase - wave_height + 3;
3408 width = s->width;
3409 xmax = x0 + width;
3411 /* Find and set clipping rectangle */
3413 wave_clip.x = x0;
3414 wave_clip.y = y0;
3415 wave_clip.width = width;
3416 wave_clip.height = wave_height;
3417 get_glyph_string_clip_rect (s, &string_clip);
3419 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3420 return;
3422 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3424 /* Draw the waves */
3426 x1 = x0 - (x0 % dx);
3427 x2 = x1 + dx;
3428 odd = (x1 / dx) & 1;
3429 y1 = y2 = y0;
3431 if (odd)
3432 y1 += dy;
3433 else
3434 y2 += dy;
3436 if (INT_MAX - dx < xmax)
3437 emacs_abort ();
3439 while (x1 <= xmax)
3441 XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
3442 x1 = x2, y1 = y2;
3443 x2 += dx, y2 = y0 + odd*dy;
3444 odd = !odd;
3447 /* Restore previous clipping rectangle(s) */
3448 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3449 #endif /* not USE_CAIRO */
3453 /* Draw glyph string S. */
3455 static void
3456 x_draw_glyph_string (struct glyph_string *s)
3458 bool relief_drawn_p = false;
3460 /* If S draws into the background of its successors, draw the
3461 background of the successors first so that S can draw into it.
3462 This makes S->next use XDrawString instead of XDrawImageString. */
3463 if (s->next && s->right_overhang && !s->for_overlaps)
3465 int width;
3466 struct glyph_string *next;
3468 for (width = 0, next = s->next;
3469 next && width < s->right_overhang;
3470 width += next->width, next = next->next)
3471 if (next->first_glyph->type != IMAGE_GLYPH)
3473 x_set_glyph_string_gc (next);
3474 x_set_glyph_string_clipping (next);
3475 if (next->first_glyph->type == STRETCH_GLYPH)
3476 x_draw_stretch_glyph_string (next);
3477 else
3478 x_draw_glyph_string_background (next, true);
3479 next->num_clips = 0;
3483 /* Set up S->gc, set clipping and draw S. */
3484 x_set_glyph_string_gc (s);
3486 /* Draw relief (if any) in advance for char/composition so that the
3487 glyph string can be drawn over it. */
3488 if (!s->for_overlaps
3489 && s->face->box != FACE_NO_BOX
3490 && (s->first_glyph->type == CHAR_GLYPH
3491 || s->first_glyph->type == COMPOSITE_GLYPH))
3494 x_set_glyph_string_clipping (s);
3495 x_draw_glyph_string_background (s, true);
3496 x_draw_glyph_string_box (s);
3497 x_set_glyph_string_clipping (s);
3498 relief_drawn_p = true;
3500 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3501 && !s->clip_tail
3502 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3503 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3504 /* We must clip just this glyph. left_overhang part has already
3505 drawn when s->prev was drawn, and right_overhang part will be
3506 drawn later when s->next is drawn. */
3507 x_set_glyph_string_clipping_exactly (s, s);
3508 else
3509 x_set_glyph_string_clipping (s);
3511 switch (s->first_glyph->type)
3513 case IMAGE_GLYPH:
3514 x_draw_image_glyph_string (s);
3515 break;
3517 case XWIDGET_GLYPH:
3518 x_draw_xwidget_glyph_string (s);
3519 break;
3521 case STRETCH_GLYPH:
3522 x_draw_stretch_glyph_string (s);
3523 break;
3525 case CHAR_GLYPH:
3526 if (s->for_overlaps)
3527 s->background_filled_p = true;
3528 else
3529 x_draw_glyph_string_background (s, false);
3530 x_draw_glyph_string_foreground (s);
3531 break;
3533 case COMPOSITE_GLYPH:
3534 if (s->for_overlaps || (s->cmp_from > 0
3535 && ! s->first_glyph->u.cmp.automatic))
3536 s->background_filled_p = true;
3537 else
3538 x_draw_glyph_string_background (s, true);
3539 x_draw_composite_glyph_string_foreground (s);
3540 break;
3542 case GLYPHLESS_GLYPH:
3543 if (s->for_overlaps)
3544 s->background_filled_p = true;
3545 else
3546 x_draw_glyph_string_background (s, true);
3547 x_draw_glyphless_glyph_string_foreground (s);
3548 break;
3550 default:
3551 emacs_abort ();
3554 if (!s->for_overlaps)
3556 /* Draw underline. */
3557 if (s->face->underline_p)
3559 if (s->face->underline_type == FACE_UNDER_WAVE)
3561 if (s->face->underline_defaulted_p)
3562 x_draw_underwave (s);
3563 else
3565 XGCValues xgcv;
3566 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3567 XSetForeground (s->display, s->gc, s->face->underline_color);
3568 x_draw_underwave (s);
3569 XSetForeground (s->display, s->gc, xgcv.foreground);
3572 else if (s->face->underline_type == FACE_UNDER_LINE)
3574 unsigned long thickness, position;
3575 int y;
3577 if (s->prev && s->prev->face->underline_p
3578 && s->prev->face->underline_type == FACE_UNDER_LINE)
3580 /* We use the same underline style as the previous one. */
3581 thickness = s->prev->underline_thickness;
3582 position = s->prev->underline_position;
3584 else
3586 /* Get the underline thickness. Default is 1 pixel. */
3587 if (s->font && s->font->underline_thickness > 0)
3588 thickness = s->font->underline_thickness;
3589 else
3590 thickness = 1;
3591 if (x_underline_at_descent_line)
3592 position = (s->height - thickness) - (s->ybase - s->y);
3593 else
3595 /* Get the underline position. This is the recommended
3596 vertical offset in pixels from the baseline to the top of
3597 the underline. This is a signed value according to the
3598 specs, and its default is
3600 ROUND ((maximum descent) / 2), with
3601 ROUND(x) = floor (x + 0.5) */
3603 if (x_use_underline_position_properties
3604 && s->font && s->font->underline_position >= 0)
3605 position = s->font->underline_position;
3606 else if (s->font)
3607 position = (s->font->descent + 1) / 2;
3608 else
3609 position = underline_minimum_offset;
3611 position = max (position, underline_minimum_offset);
3613 /* Check the sanity of thickness and position. We should
3614 avoid drawing underline out of the current line area. */
3615 if (s->y + s->height <= s->ybase + position)
3616 position = (s->height - 1) - (s->ybase - s->y);
3617 if (s->y + s->height < s->ybase + position + thickness)
3618 thickness = (s->y + s->height) - (s->ybase + position);
3619 s->underline_thickness = thickness;
3620 s->underline_position = position;
3621 y = s->ybase + position;
3622 if (s->face->underline_defaulted_p)
3623 x_fill_rectangle (s->f, s->gc,
3624 s->x, y, s->width, thickness);
3625 else
3627 XGCValues xgcv;
3628 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3629 XSetForeground (s->display, s->gc, s->face->underline_color);
3630 x_fill_rectangle (s->f, s->gc,
3631 s->x, y, s->width, thickness);
3632 XSetForeground (s->display, s->gc, xgcv.foreground);
3636 /* Draw overline. */
3637 if (s->face->overline_p)
3639 unsigned long dy = 0, h = 1;
3641 if (s->face->overline_color_defaulted_p)
3642 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3643 s->width, h);
3644 else
3646 XGCValues xgcv;
3647 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3648 XSetForeground (s->display, s->gc, s->face->overline_color);
3649 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3650 s->width, h);
3651 XSetForeground (s->display, s->gc, xgcv.foreground);
3655 /* Draw strike-through. */
3656 if (s->face->strike_through_p)
3658 unsigned long h = 1;
3659 unsigned long dy = (s->height - h) / 2;
3661 if (s->face->strike_through_color_defaulted_p)
3662 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3663 s->width, h);
3664 else
3666 XGCValues xgcv;
3667 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3668 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3669 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3670 s->width, h);
3671 XSetForeground (s->display, s->gc, xgcv.foreground);
3675 /* Draw relief if not yet drawn. */
3676 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3677 x_draw_glyph_string_box (s);
3679 if (s->prev)
3681 struct glyph_string *prev;
3683 for (prev = s->prev; prev; prev = prev->prev)
3684 if (prev->hl != s->hl
3685 && prev->x + prev->width + prev->right_overhang > s->x)
3687 /* As prev was drawn while clipped to its own area, we
3688 must draw the right_overhang part using s->hl now. */
3689 enum draw_glyphs_face save = prev->hl;
3691 prev->hl = s->hl;
3692 x_set_glyph_string_gc (prev);
3693 x_set_glyph_string_clipping_exactly (s, prev);
3694 if (prev->first_glyph->type == CHAR_GLYPH)
3695 x_draw_glyph_string_foreground (prev);
3696 else
3697 x_draw_composite_glyph_string_foreground (prev);
3698 x_reset_clip_rectangles (prev->f, prev->gc);
3699 prev->hl = save;
3700 prev->num_clips = 0;
3704 if (s->next)
3706 struct glyph_string *next;
3708 for (next = s->next; next; next = next->next)
3709 if (next->hl != s->hl
3710 && next->x - next->left_overhang < s->x + s->width)
3712 /* As next will be drawn while clipped to its own area,
3713 we must draw the left_overhang part using s->hl now. */
3714 enum draw_glyphs_face save = next->hl;
3716 next->hl = s->hl;
3717 x_set_glyph_string_gc (next);
3718 x_set_glyph_string_clipping_exactly (s, next);
3719 if (next->first_glyph->type == CHAR_GLYPH)
3720 x_draw_glyph_string_foreground (next);
3721 else
3722 x_draw_composite_glyph_string_foreground (next);
3723 x_reset_clip_rectangles (next->f, next->gc);
3724 next->hl = save;
3725 next->num_clips = 0;
3726 next->clip_head = s->next;
3731 /* Reset clipping. */
3732 x_reset_clip_rectangles (s->f, s->gc);
3733 s->num_clips = 0;
3736 /* Shift display to make room for inserted glyphs. */
3738 static void
3739 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3741 /* Never called on a GUI frame, see
3742 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3744 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
3745 f->output_data.x->normal_gc,
3746 x, y, width, height,
3747 x + shift_by, y);
3750 /* Delete N glyphs at the nominal cursor position. Not implemented
3751 for X frames. */
3753 static void
3754 x_delete_glyphs (struct frame *f, register int n)
3756 emacs_abort ();
3760 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3761 If they are <= 0, this is probably an error. */
3763 static ATTRIBUTE_UNUSED void
3764 x_clear_area1 (Display *dpy, Window window,
3765 int x, int y, int width, int height, int exposures)
3767 eassert (width > 0 && height > 0);
3768 XClearArea (dpy, window, x, y, width, height, exposures);
3771 void
3772 x_clear_area (struct frame *f, int x, int y, int width, int height)
3774 #ifdef USE_CAIRO
3775 cairo_t *cr;
3777 eassert (width > 0 && height > 0);
3779 cr = x_begin_cr_clip (f, NULL);
3780 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3781 cairo_rectangle (cr, x, y, width, height);
3782 cairo_fill (cr);
3783 x_end_cr_clip (f);
3784 #else
3785 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3786 x, y, width, height, False);
3787 #endif
3791 /* Clear an entire frame. */
3793 static void
3794 x_clear_frame (struct frame *f)
3796 /* Clearing the frame will erase any cursor, so mark them all as no
3797 longer visible. */
3798 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3800 block_input ();
3802 x_clear_window (f);
3804 /* We have to clear the scroll bars. If we have changed colors or
3805 something like that, then they should be notified. */
3806 x_scroll_bar_clear (f);
3808 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3809 /* Make sure scroll bars are redrawn. As they aren't redrawn by
3810 redisplay, do it here. */
3811 if (FRAME_GTK_WIDGET (f))
3812 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
3813 #endif
3815 XFlush (FRAME_X_DISPLAY (f));
3817 unblock_input ();
3820 /* RIF: Show hourglass cursor on frame F. */
3822 static void
3823 x_show_hourglass (struct frame *f)
3825 Display *dpy = FRAME_X_DISPLAY (f);
3827 if (dpy)
3829 struct x_output *x = FRAME_X_OUTPUT (f);
3830 #ifdef USE_X_TOOLKIT
3831 if (x->widget)
3832 #else
3833 if (FRAME_OUTER_WINDOW (f))
3834 #endif
3836 x->hourglass_p = true;
3838 if (!x->hourglass_window)
3840 unsigned long mask = CWCursor;
3841 XSetWindowAttributes attrs;
3842 #ifdef USE_GTK
3843 Window parent = FRAME_X_WINDOW (f);
3844 #else
3845 Window parent = FRAME_OUTER_WINDOW (f);
3846 #endif
3847 attrs.cursor = x->hourglass_cursor;
3849 x->hourglass_window = XCreateWindow
3850 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3851 InputOnly, CopyFromParent, mask, &attrs);
3854 XMapRaised (dpy, x->hourglass_window);
3855 XFlush (dpy);
3860 /* RIF: Cancel hourglass cursor on frame F. */
3862 static void
3863 x_hide_hourglass (struct frame *f)
3865 struct x_output *x = FRAME_X_OUTPUT (f);
3867 /* Watch out for newly created frames. */
3868 if (x->hourglass_window)
3870 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3871 /* Sync here because XTread_socket looks at the
3872 hourglass_p flag that is reset to zero below. */
3873 XSync (FRAME_X_DISPLAY (f), False);
3874 x->hourglass_p = false;
3878 /* Invert the middle quarter of the frame for .15 sec. */
3880 static void
3881 XTflash (struct frame *f)
3883 block_input ();
3886 #ifdef USE_GTK
3887 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3888 when the scroll bars and the edit widget share the same X window. */
3889 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3890 #ifdef HAVE_GTK3
3891 cairo_t *cr = gdk_cairo_create (window);
3892 cairo_set_source_rgb (cr, 1, 1, 1);
3893 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
3894 #define XFillRectangle(d, win, gc, x, y, w, h) \
3895 do { \
3896 cairo_rectangle (cr, x, y, w, h); \
3897 cairo_fill (cr); \
3899 while (false)
3900 #else /* ! HAVE_GTK3 */
3901 GdkGCValues vals;
3902 GdkGC *gc;
3903 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
3904 ^ FRAME_BACKGROUND_PIXEL (f));
3905 vals.function = GDK_XOR;
3906 gc = gdk_gc_new_with_values (window,
3907 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
3908 #define XFillRectangle(d, win, gc, x, y, w, h) \
3909 gdk_draw_rectangle (window, gc, true, x, y, w, h)
3910 #endif /* ! HAVE_GTK3 */
3911 #else /* ! USE_GTK */
3912 GC gc;
3914 /* Create a GC that will use the GXxor function to flip foreground
3915 pixels into background pixels. */
3917 XGCValues values;
3919 values.function = GXxor;
3920 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
3921 ^ FRAME_BACKGROUND_PIXEL (f));
3923 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3924 GCFunction | GCForeground, &values);
3926 #endif
3928 /* Get the height not including a menu bar widget. */
3929 int height = FRAME_PIXEL_HEIGHT (f);
3930 /* Height of each line to flash. */
3931 int flash_height = FRAME_LINE_HEIGHT (f);
3932 /* These will be the left and right margins of the rectangles. */
3933 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3934 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3935 int width = flash_right - flash_left;
3937 /* If window is tall, flash top and bottom line. */
3938 if (height > 3 * FRAME_LINE_HEIGHT (f))
3940 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3941 flash_left,
3942 (FRAME_INTERNAL_BORDER_WIDTH (f)
3943 + FRAME_TOP_MARGIN_HEIGHT (f)),
3944 width, flash_height);
3945 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3946 flash_left,
3947 (height - flash_height
3948 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3949 width, flash_height);
3952 else
3953 /* If it is short, flash it all. */
3954 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3955 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3956 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3958 x_flush (f);
3961 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
3962 struct timespec wakeup = timespec_add (current_timespec (), delay);
3964 /* Keep waiting until past the time wakeup or any input gets
3965 available. */
3966 while (! detect_input_pending ())
3968 struct timespec current = current_timespec ();
3969 struct timespec timeout;
3971 /* Break if result would not be positive. */
3972 if (timespec_cmp (wakeup, current) <= 0)
3973 break;
3975 /* How long `select' should wait. */
3976 timeout = make_timespec (0, 10 * 1000 * 1000);
3978 /* Try to wait that long--but we might wake up sooner. */
3979 pselect (0, NULL, NULL, NULL, &timeout, NULL);
3983 /* If window is tall, flash top and bottom line. */
3984 if (height > 3 * FRAME_LINE_HEIGHT (f))
3986 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3987 flash_left,
3988 (FRAME_INTERNAL_BORDER_WIDTH (f)
3989 + FRAME_TOP_MARGIN_HEIGHT (f)),
3990 width, flash_height);
3991 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3992 flash_left,
3993 (height - flash_height
3994 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3995 width, flash_height);
3997 else
3998 /* If it is short, flash it all. */
3999 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
4000 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
4001 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
4003 #ifdef USE_GTK
4004 #ifdef HAVE_GTK3
4005 cairo_destroy (cr);
4006 #else
4007 g_object_unref (G_OBJECT (gc));
4008 #endif
4009 #undef XFillRectangle
4010 #else
4011 XFreeGC (FRAME_X_DISPLAY (f), gc);
4012 #endif
4013 x_flush (f);
4017 unblock_input ();
4021 static void
4022 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
4024 block_input ();
4025 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
4026 unblock_input ();
4030 /* Make audible bell. */
4032 static void
4033 XTring_bell (struct frame *f)
4035 if (FRAME_X_DISPLAY (f))
4037 if (visible_bell)
4038 XTflash (f);
4039 else
4041 block_input ();
4042 #ifdef HAVE_XKB
4043 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
4044 #else
4045 XBell (FRAME_X_DISPLAY (f), 0);
4046 #endif
4047 XFlush (FRAME_X_DISPLAY (f));
4048 unblock_input ();
4053 /***********************************************************************
4054 Line Dance
4055 ***********************************************************************/
4057 /* Perform an insert-lines or delete-lines operation, inserting N
4058 lines or deleting -N lines at vertical position VPOS. */
4060 static void
4061 x_ins_del_lines (struct frame *f, int vpos, int n)
4063 emacs_abort ();
4067 /* Scroll part of the display as described by RUN. */
4069 static void
4070 x_scroll_run (struct window *w, struct run *run)
4072 struct frame *f = XFRAME (w->frame);
4073 int x, y, width, height, from_y, to_y, bottom_y;
4075 /* Get frame-relative bounding box of the text display area of W,
4076 without mode lines. Include in this box the left and right
4077 fringe of W. */
4078 window_box (w, ANY_AREA, &x, &y, &width, &height);
4080 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
4081 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
4082 bottom_y = y + height;
4084 if (to_y < from_y)
4086 /* Scrolling up. Make sure we don't copy part of the mode
4087 line at the bottom. */
4088 if (from_y + run->height > bottom_y)
4089 height = bottom_y - from_y;
4090 else
4091 height = run->height;
4093 else
4095 /* Scrolling down. Make sure we don't copy over the mode line.
4096 at the bottom. */
4097 if (to_y + run->height > bottom_y)
4098 height = bottom_y - to_y;
4099 else
4100 height = run->height;
4103 block_input ();
4105 /* Cursor off. Will be switched on again in x_update_window_end. */
4106 x_clear_cursor (w);
4108 #ifdef USE_CAIRO
4109 SET_FRAME_GARBAGED (f);
4110 #else
4111 XCopyArea (FRAME_X_DISPLAY (f),
4112 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
4113 f->output_data.x->normal_gc,
4114 x, from_y,
4115 width, height,
4116 x, to_y);
4117 #endif
4119 unblock_input ();
4124 /***********************************************************************
4125 Exposure Events
4126 ***********************************************************************/
4129 static void
4130 frame_highlight (struct frame *f)
4132 /* We used to only do this if Vx_no_window_manager was non-nil, but
4133 the ICCCM (section 4.1.6) says that the window's border pixmap
4134 and border pixel are window attributes which are "private to the
4135 client", so we can always change it to whatever we want. */
4136 block_input ();
4137 /* I recently started to get errors in this XSetWindowBorder, depending on
4138 the window-manager in use, tho something more is at play since I've been
4139 using that same window-manager binary for ever. Let's not crash just
4140 because of this (bug#9310). */
4141 x_catch_errors (FRAME_X_DISPLAY (f));
4142 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4143 f->output_data.x->border_pixel);
4144 x_uncatch_errors ();
4145 unblock_input ();
4146 x_update_cursor (f, true);
4147 x_set_frame_alpha (f);
4150 static void
4151 frame_unhighlight (struct frame *f)
4153 /* We used to only do this if Vx_no_window_manager was non-nil, but
4154 the ICCCM (section 4.1.6) says that the window's border pixmap
4155 and border pixel are window attributes which are "private to the
4156 client", so we can always change it to whatever we want. */
4157 block_input ();
4158 /* Same as above for XSetWindowBorder (bug#9310). */
4159 x_catch_errors (FRAME_X_DISPLAY (f));
4160 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4161 f->output_data.x->border_tile);
4162 x_uncatch_errors ();
4163 unblock_input ();
4164 x_update_cursor (f, true);
4165 x_set_frame_alpha (f);
4168 /* The focus has changed. Update the frames as necessary to reflect
4169 the new situation. Note that we can't change the selected frame
4170 here, because the Lisp code we are interrupting might become confused.
4171 Each event gets marked with the frame in which it occurred, so the
4172 Lisp code can tell when the switch took place by examining the events. */
4174 static void
4175 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4177 struct frame *old_focus = dpyinfo->x_focus_frame;
4179 if (frame != dpyinfo->x_focus_frame)
4181 /* Set this before calling other routines, so that they see
4182 the correct value of x_focus_frame. */
4183 dpyinfo->x_focus_frame = frame;
4185 if (old_focus && old_focus->auto_lower)
4186 x_lower_frame (old_focus);
4188 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4189 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4190 else
4191 dpyinfo->x_pending_autoraise_frame = NULL;
4194 x_frame_rehighlight (dpyinfo);
4197 /* Handle FocusIn and FocusOut state changes for FRAME.
4198 If FRAME has focus and there exists more than one frame, puts
4199 a FOCUS_IN_EVENT into *BUFP. */
4201 static void
4202 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4204 if (type == FocusIn)
4206 if (dpyinfo->x_focus_event_frame != frame)
4208 x_new_focus_frame (dpyinfo, frame);
4209 dpyinfo->x_focus_event_frame = frame;
4211 /* Don't stop displaying the initial startup message
4212 for a switch-frame event we don't need. */
4213 /* When run as a daemon, Vterminal_frame is always NIL. */
4214 bufp->arg = (((NILP (Vterminal_frame)
4215 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4216 || EQ (Fdaemonp (), Qt))
4217 && CONSP (Vframe_list)
4218 && !NILP (XCDR (Vframe_list)))
4219 ? Qt : Qnil);
4220 bufp->kind = FOCUS_IN_EVENT;
4221 XSETFRAME (bufp->frame_or_window, frame);
4224 frame->output_data.x->focus_state |= state;
4226 #ifdef HAVE_X_I18N
4227 if (FRAME_XIC (frame))
4228 XSetICFocus (FRAME_XIC (frame));
4229 #endif
4231 else if (type == FocusOut)
4233 frame->output_data.x->focus_state &= ~state;
4235 if (dpyinfo->x_focus_event_frame == frame)
4237 dpyinfo->x_focus_event_frame = 0;
4238 x_new_focus_frame (dpyinfo, 0);
4240 bufp->kind = FOCUS_OUT_EVENT;
4241 XSETFRAME (bufp->frame_or_window, frame);
4244 #ifdef HAVE_X_I18N
4245 if (FRAME_XIC (frame))
4246 XUnsetICFocus (FRAME_XIC (frame));
4247 #endif
4248 if (frame->pointer_invisible)
4249 XTtoggle_invisible_pointer (frame, false);
4253 /* Return the Emacs frame-object corresponding to an X window.
4254 It could be the frame's main window or an icon window. */
4256 static struct frame *
4257 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4259 Lisp_Object tail, frame;
4260 struct frame *f;
4262 if (wdesc == None)
4263 return NULL;
4265 FOR_EACH_FRAME (tail, frame)
4267 f = XFRAME (frame);
4268 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4269 continue;
4270 if (f->output_data.x->hourglass_window == wdesc)
4271 return f;
4272 #ifdef USE_X_TOOLKIT
4273 if ((f->output_data.x->edit_widget
4274 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4275 /* A tooltip frame? */
4276 || (!f->output_data.x->edit_widget
4277 && FRAME_X_WINDOW (f) == wdesc)
4278 || f->output_data.x->icon_desc == wdesc)
4279 return f;
4280 #else /* not USE_X_TOOLKIT */
4281 #ifdef USE_GTK
4282 if (f->output_data.x->edit_widget)
4284 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4285 struct x_output *x = f->output_data.x;
4286 if (gwdesc != 0 && gwdesc == x->edit_widget)
4287 return f;
4289 #endif /* USE_GTK */
4290 if (FRAME_X_WINDOW (f) == wdesc
4291 || f->output_data.x->icon_desc == wdesc)
4292 return f;
4293 #endif /* not USE_X_TOOLKIT */
4295 return 0;
4298 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4300 /* Like x_window_to_frame but also compares the window with the widget's
4301 windows. */
4303 static struct frame *
4304 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4306 Lisp_Object tail, frame;
4307 struct frame *f, *found = NULL;
4308 struct x_output *x;
4310 if (wdesc == None)
4311 return NULL;
4313 FOR_EACH_FRAME (tail, frame)
4315 if (found)
4316 break;
4317 f = XFRAME (frame);
4318 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4320 /* This frame matches if the window is any of its widgets. */
4321 x = f->output_data.x;
4322 if (x->hourglass_window == wdesc)
4323 found = f;
4324 else if (x->widget)
4326 #ifdef USE_GTK
4327 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4328 if (gwdesc != 0
4329 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4330 found = f;
4331 #else
4332 if (wdesc == XtWindow (x->widget)
4333 || wdesc == XtWindow (x->column_widget)
4334 || wdesc == XtWindow (x->edit_widget))
4335 found = f;
4336 /* Match if the window is this frame's menubar. */
4337 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4338 found = f;
4339 #endif
4341 else if (FRAME_X_WINDOW (f) == wdesc)
4342 /* A tooltip frame. */
4343 found = f;
4347 return found;
4350 /* Likewise, but consider only the menu bar widget. */
4352 static struct frame *
4353 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4354 const XEvent *event)
4356 Window wdesc = event->xany.window;
4357 Lisp_Object tail, frame;
4358 struct frame *f;
4359 struct x_output *x;
4361 if (wdesc == None)
4362 return NULL;
4364 FOR_EACH_FRAME (tail, frame)
4366 f = XFRAME (frame);
4367 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4368 continue;
4369 x = f->output_data.x;
4370 #ifdef USE_GTK
4371 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4372 return f;
4373 #else
4374 /* Match if the window is this frame's menubar. */
4375 if (x->menubar_widget
4376 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4377 return f;
4378 #endif
4380 return 0;
4383 /* Return the frame whose principal (outermost) window is WDESC.
4384 If WDESC is some other (smaller) window, we return 0. */
4386 struct frame *
4387 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4389 Lisp_Object tail, frame;
4390 struct frame *f;
4391 struct x_output *x;
4393 if (wdesc == None)
4394 return NULL;
4396 FOR_EACH_FRAME (tail, frame)
4398 f = XFRAME (frame);
4399 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4400 continue;
4401 x = f->output_data.x;
4403 if (x->widget)
4405 /* This frame matches if the window is its topmost widget. */
4406 #ifdef USE_GTK
4407 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4408 if (gwdesc == x->widget)
4409 return f;
4410 #else
4411 if (wdesc == XtWindow (x->widget))
4412 return f;
4413 #endif
4415 else if (FRAME_X_WINDOW (f) == wdesc)
4416 /* Tooltip frame. */
4417 return f;
4419 return 0;
4422 #else /* !USE_X_TOOLKIT && !USE_GTK */
4424 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4425 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4427 #endif /* USE_X_TOOLKIT || USE_GTK */
4429 /* The focus may have changed. Figure out if it is a real focus change,
4430 by checking both FocusIn/Out and Enter/LeaveNotify events.
4432 Returns FOCUS_IN_EVENT event in *BUFP. */
4434 static void
4435 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4436 const XEvent *event, struct input_event *bufp)
4438 if (!frame)
4439 return;
4441 switch (event->type)
4443 case EnterNotify:
4444 case LeaveNotify:
4446 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4447 int focus_state
4448 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4450 if (event->xcrossing.detail != NotifyInferior
4451 && event->xcrossing.focus
4452 && ! (focus_state & FOCUS_EXPLICIT))
4453 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4454 FOCUS_IMPLICIT,
4455 dpyinfo, frame, bufp);
4457 break;
4459 case FocusIn:
4460 case FocusOut:
4461 x_focus_changed (event->type,
4462 (event->xfocus.detail == NotifyPointer ?
4463 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4464 dpyinfo, frame, bufp);
4465 break;
4467 case ClientMessage:
4468 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4470 enum xembed_message msg = event->xclient.data.l[1];
4471 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4472 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4474 break;
4479 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4480 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4482 void
4483 x_mouse_leave (struct x_display_info *dpyinfo)
4485 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4487 #endif
4489 /* The focus has changed, or we have redirected a frame's focus to
4490 another frame (this happens when a frame uses a surrogate
4491 mini-buffer frame). Shift the highlight as appropriate.
4493 The FRAME argument doesn't necessarily have anything to do with which
4494 frame is being highlighted or un-highlighted; we only use it to find
4495 the appropriate X display info. */
4497 static void
4498 XTframe_rehighlight (struct frame *frame)
4500 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4503 static void
4504 x_frame_rehighlight (struct x_display_info *dpyinfo)
4506 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4508 if (dpyinfo->x_focus_frame)
4510 dpyinfo->x_highlight_frame
4511 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4512 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4513 : dpyinfo->x_focus_frame);
4514 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4516 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4517 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4520 else
4521 dpyinfo->x_highlight_frame = 0;
4523 if (dpyinfo->x_highlight_frame != old_highlight)
4525 if (old_highlight)
4526 frame_unhighlight (old_highlight);
4527 if (dpyinfo->x_highlight_frame)
4528 frame_highlight (dpyinfo->x_highlight_frame);
4534 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4536 /* Initialize mode_switch_bit and modifier_meaning. */
4537 static void
4538 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4540 int min_code, max_code;
4541 KeySym *syms;
4542 int syms_per_code;
4543 XModifierKeymap *mods;
4545 dpyinfo->meta_mod_mask = 0;
4546 dpyinfo->shift_lock_mask = 0;
4547 dpyinfo->alt_mod_mask = 0;
4548 dpyinfo->super_mod_mask = 0;
4549 dpyinfo->hyper_mod_mask = 0;
4551 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4553 syms = XGetKeyboardMapping (dpyinfo->display,
4554 min_code, max_code - min_code + 1,
4555 &syms_per_code);
4556 mods = XGetModifierMapping (dpyinfo->display);
4558 /* Scan the modifier table to see which modifier bits the Meta and
4559 Alt keysyms are on. */
4561 int row, col; /* The row and column in the modifier table. */
4562 bool found_alt_or_meta;
4564 for (row = 3; row < 8; row++)
4566 found_alt_or_meta = false;
4567 for (col = 0; col < mods->max_keypermod; col++)
4569 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4571 /* Zeroes are used for filler. Skip them. */
4572 if (code == 0)
4573 continue;
4575 /* Are any of this keycode's keysyms a meta key? */
4577 int code_col;
4579 for (code_col = 0; code_col < syms_per_code; code_col++)
4581 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4583 switch (sym)
4585 case XK_Meta_L:
4586 case XK_Meta_R:
4587 found_alt_or_meta = true;
4588 dpyinfo->meta_mod_mask |= (1 << row);
4589 break;
4591 case XK_Alt_L:
4592 case XK_Alt_R:
4593 found_alt_or_meta = true;
4594 dpyinfo->alt_mod_mask |= (1 << row);
4595 break;
4597 case XK_Hyper_L:
4598 case XK_Hyper_R:
4599 if (!found_alt_or_meta)
4600 dpyinfo->hyper_mod_mask |= (1 << row);
4601 code_col = syms_per_code;
4602 col = mods->max_keypermod;
4603 break;
4605 case XK_Super_L:
4606 case XK_Super_R:
4607 if (!found_alt_or_meta)
4608 dpyinfo->super_mod_mask |= (1 << row);
4609 code_col = syms_per_code;
4610 col = mods->max_keypermod;
4611 break;
4613 case XK_Shift_Lock:
4614 /* Ignore this if it's not on the lock modifier. */
4615 if (!found_alt_or_meta && ((1 << row) == LockMask))
4616 dpyinfo->shift_lock_mask = LockMask;
4617 code_col = syms_per_code;
4618 col = mods->max_keypermod;
4619 break;
4627 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4628 if (! dpyinfo->meta_mod_mask)
4630 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4631 dpyinfo->alt_mod_mask = 0;
4634 /* If some keys are both alt and meta,
4635 make them just meta, not alt. */
4636 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4638 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4641 XFree (syms);
4642 XFreeModifiermap (mods);
4645 /* Convert between the modifier bits X uses and the modifier bits
4646 Emacs uses. */
4649 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4651 int mod_meta = meta_modifier;
4652 int mod_alt = alt_modifier;
4653 int mod_hyper = hyper_modifier;
4654 int mod_super = super_modifier;
4655 Lisp_Object tem;
4657 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4658 if (INTEGERP (tem)) mod_alt = XINT (tem) & INT_MAX;
4659 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4660 if (INTEGERP (tem)) mod_meta = XINT (tem) & INT_MAX;
4661 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4662 if (INTEGERP (tem)) mod_hyper = XINT (tem) & INT_MAX;
4663 tem = Fget (Vx_super_keysym, Qmodifier_value);
4664 if (INTEGERP (tem)) mod_super = XINT (tem) & INT_MAX;
4666 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
4667 | ((state & ControlMask) ? ctrl_modifier : 0)
4668 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
4669 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
4670 | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
4671 | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
4674 static int
4675 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
4677 EMACS_INT mod_meta = meta_modifier;
4678 EMACS_INT mod_alt = alt_modifier;
4679 EMACS_INT mod_hyper = hyper_modifier;
4680 EMACS_INT mod_super = super_modifier;
4682 Lisp_Object tem;
4684 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4685 if (INTEGERP (tem)) mod_alt = XINT (tem);
4686 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4687 if (INTEGERP (tem)) mod_meta = XINT (tem);
4688 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4689 if (INTEGERP (tem)) mod_hyper = XINT (tem);
4690 tem = Fget (Vx_super_keysym, Qmodifier_value);
4691 if (INTEGERP (tem)) mod_super = XINT (tem);
4694 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0)
4695 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0)
4696 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0)
4697 | ((state & shift_modifier) ? ShiftMask : 0)
4698 | ((state & ctrl_modifier) ? ControlMask : 0)
4699 | ((state & mod_meta) ? dpyinfo->meta_mod_mask : 0));
4702 /* Convert a keysym to its name. */
4704 char *
4705 x_get_keysym_name (int keysym)
4707 char *value;
4709 block_input ();
4710 value = XKeysymToString (keysym);
4711 unblock_input ();
4713 return value;
4716 /* Mouse clicks and mouse movement. Rah.
4718 Formerly, we used PointerMotionHintMask (in standard_event_mask)
4719 so that we would have to call XQueryPointer after each MotionNotify
4720 event to ask for another such event. However, this made mouse tracking
4721 slow, and there was a bug that made it eventually stop.
4723 Simply asking for MotionNotify all the time seems to work better.
4725 In order to avoid asking for motion events and then throwing most
4726 of them away or busy-polling the server for mouse positions, we ask
4727 the server for pointer motion hints. This means that we get only
4728 one event per group of mouse movements. "Groups" are delimited by
4729 other kinds of events (focus changes and button clicks, for
4730 example), or by XQueryPointer calls; when one of these happens, we
4731 get another MotionNotify event the next time the mouse moves. This
4732 is at least as efficient as getting motion events when mouse
4733 tracking is on, and I suspect only negligibly worse when tracking
4734 is off. */
4736 /* Prepare a mouse-event in *RESULT for placement in the input queue.
4738 If the event is a button press, then note that we have grabbed
4739 the mouse. */
4741 static Lisp_Object
4742 construct_mouse_click (struct input_event *result,
4743 const XButtonEvent *event,
4744 struct frame *f)
4746 /* Make the event type NO_EVENT; we'll change that when we decide
4747 otherwise. */
4748 result->kind = MOUSE_CLICK_EVENT;
4749 result->code = event->button - Button1;
4750 result->timestamp = event->time;
4751 result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
4752 event->state)
4753 | (event->type == ButtonRelease
4754 ? up_modifier
4755 : down_modifier));
4757 XSETINT (result->x, event->x);
4758 XSETINT (result->y