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