Follow text-quoting-style in display table init
[emacs.git] / src / xterm.c
blob9ee76e967e124734688892b576076178169658d7
1 /* X Communication module for terminals which understand the X protocol.
3 Copyright (C) 1989, 1993-2015 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
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
21 /* Xt features made by Fred Pierresteguy. */
23 #include <config.h>
24 #include <stdio.h>
25 #ifdef USE_CAIRO
26 #include <math.h>
27 #endif
29 #include "lisp.h"
30 #include "blockinput.h"
31 #include "syssignal.h"
33 /* This may include sys/types.h, and that somehow loses
34 if this is not done before the other system files. */
35 #include "xterm.h"
36 #include <X11/cursorfont.h>
38 /* If we have Xfixes extension, use it for pointer blanking. */
39 #ifdef HAVE_XFIXES
40 #include <X11/extensions/Xfixes.h>
41 #endif
43 /* Using Xft implies that XRender is available. */
44 #ifdef HAVE_XFT
45 #include <X11/extensions/Xrender.h>
46 #endif
48 /* Load sys/types.h if not already loaded.
49 In some systems loading it twice is suicidal. */
50 #ifndef makedev
51 #include <sys/types.h>
52 #endif /* makedev */
54 #include <sys/ioctl.h>
56 #include "systime.h"
58 #include <fcntl.h>
59 #include <errno.h>
60 #include <sys/stat.h>
61 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
62 /* #include <sys/param.h> */
64 #include "charset.h"
65 #include "character.h"
66 #include "coding.h"
67 #include "frame.h"
68 #include "dispextern.h"
69 #include "fontset.h"
70 #include "termhooks.h"
71 #include "termopts.h"
72 #include "termchar.h"
73 #include "emacs-icon.h"
74 #include "disptab.h"
75 #include "buffer.h"
76 #include "window.h"
77 #include "keyboard.h"
78 #include "intervals.h"
79 #include "process.h"
80 #include "atimer.h"
81 #include "keymap.h"
82 #include "font.h"
83 #include "xsettings.h"
84 #include "xgselect.h"
85 #include "sysselect.h"
86 #include "menu.h"
88 #ifdef USE_X_TOOLKIT
89 #include <X11/Shell.h>
90 #endif
92 #include <unistd.h>
94 #ifdef USE_GTK
95 #include "gtkutil.h"
96 #ifdef HAVE_GTK3
97 #include <X11/Xproto.h>
98 #endif
99 #endif
101 #if defined (USE_LUCID) || defined (USE_MOTIF)
102 #include "../lwlib/xlwmenu.h"
103 #endif
105 #ifdef USE_X_TOOLKIT
106 #if !defined (NO_EDITRES)
107 #define HACK_EDITRES
108 extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
109 #endif /* not NO_EDITRES */
111 /* Include toolkit specific headers for the scroll bar widget. */
113 #ifdef USE_TOOLKIT_SCROLL_BARS
114 #if defined USE_MOTIF
115 #include <Xm/Xm.h> /* For LESSTIF_VERSION */
116 #include <Xm/ScrollBar.h>
117 #else /* !USE_MOTIF i.e. use Xaw */
119 #ifdef HAVE_XAW3D
120 #include <X11/Xaw3d/Simple.h>
121 #include <X11/Xaw3d/Scrollbar.h>
122 #include <X11/Xaw3d/ThreeD.h>
123 #else /* !HAVE_XAW3D */
124 #include <X11/Xaw/Simple.h>
125 #include <X11/Xaw/Scrollbar.h>
126 #endif /* !HAVE_XAW3D */
127 #ifndef XtNpickTop
128 #define XtNpickTop "pickTop"
129 #endif /* !XtNpickTop */
130 #endif /* !USE_MOTIF */
131 #endif /* USE_TOOLKIT_SCROLL_BARS */
133 #endif /* USE_X_TOOLKIT */
135 #ifdef USE_X_TOOLKIT
136 #include "widget.h"
137 #ifndef XtNinitialState
138 #define XtNinitialState "initialState"
139 #endif
140 #endif
142 #include "bitmaps/gray.xbm"
144 #ifdef HAVE_XKB
145 #include <X11/XKBlib.h>
146 #endif
148 /* Default to using XIM if available. */
149 #ifdef USE_XIM
150 bool use_xim = true;
151 #else
152 bool use_xim = false; /* configure --without-xim */
153 #endif
155 /* Non-zero means that a HELP_EVENT has been generated since Emacs
156 start. */
158 static bool any_help_event_p;
160 /* This is a chain of structures for all the X displays currently in
161 use. */
163 struct x_display_info *x_display_list;
165 #ifdef USE_X_TOOLKIT
167 /* The application context for Xt use. */
168 XtAppContext Xt_app_con;
169 static String Xt_default_resources[] = {0};
171 /* Non-zero means user is interacting with a toolkit scroll bar. */
172 static bool toolkit_scroll_bar_interaction;
174 #endif /* USE_X_TOOLKIT */
176 /* Non-zero timeout value means ignore next mouse click if it arrives
177 before that timeout elapses (i.e. as part of the same sequence of
178 events resulting from clicking on a frame to select it). */
180 static Time ignore_next_mouse_click_timeout;
182 /* Used locally within XTread_socket. */
184 static int x_noop_count;
186 #ifdef USE_GTK
187 /* The name of the Emacs icon file. */
188 static Lisp_Object xg_default_icon_file;
189 #endif
191 /* Some functions take this as char *, not const char *. */
192 static char emacs_class[] = EMACS_CLASS;
194 enum xembed_info
196 XEMBED_MAPPED = 1 << 0
197 };
199 enum xembed_message
201 XEMBED_EMBEDDED_NOTIFY = 0,
202 XEMBED_WINDOW_ACTIVATE = 1,
203 XEMBED_WINDOW_DEACTIVATE = 2,
204 XEMBED_REQUEST_FOCUS = 3,
205 XEMBED_FOCUS_IN = 4,
206 XEMBED_FOCUS_OUT = 5,
207 XEMBED_FOCUS_NEXT = 6,
208 XEMBED_FOCUS_PREV = 7,
210 XEMBED_MODALITY_ON = 10,
211 XEMBED_MODALITY_OFF = 11,
212 XEMBED_REGISTER_ACCELERATOR = 12,
213 XEMBED_UNREGISTER_ACCELERATOR = 13,
214 XEMBED_ACTIVATE_ACCELERATOR = 14
215 };
217 static void x_free_cr_resources (struct frame *);
218 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
219 static void x_raise_frame (struct frame *);
220 static void x_lower_frame (struct frame *);
221 static int x_io_error_quitter (Display *);
222 static struct terminal *x_create_terminal (struct x_display_info *);
223 static void x_frame_rehighlight (struct x_display_info *);
225 static void x_clip_to_row (struct window *, struct glyph_row *,
226 enum glyph_row_area, GC);
227 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
228 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
229 enum scroll_bar_part *,
230 Lisp_Object *, Lisp_Object *,
231 Time *);
232 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
233 enum scroll_bar_part *,
234 Lisp_Object *, Lisp_Object *,
235 Time *);
236 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
237 static void x_check_fullscreen (struct frame *);
238 static void x_check_expected_move (struct frame *, int, int);
239 static void x_sync_with_move (struct frame *, int, int, bool);
240 static int handle_one_xevent (struct x_display_info *,
241 const XEvent *, int *,
242 struct input_event *);
243 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF)
244 static int x_dispatch_event (XEvent *, Display *);
245 #endif
246 static void x_wm_set_window_state (struct frame *, int);
247 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
248 static void x_initialize (void);
250 static bool get_current_wm_state (struct frame *, Window, int *, bool *);
252 /* Flush display of frame F. */
254 static void
255 x_flush (struct frame *f)
257 eassert (f && FRAME_X_P (f));
258 /* Don't call XFlush when it is not safe to redisplay; the X
259 connection may be broken. */
260 if (!NILP (Vinhibit_redisplay))
261 return;
263 block_input ();
264 XFlush (FRAME_X_DISPLAY (f));
265 unblock_input ();
269 /* Remove calls to XFlush by defining XFlush to an empty replacement.
270 Calls to XFlush should be unnecessary because the X output buffer
271 is flushed automatically as needed by calls to XPending,
272 XNextEvent, or XWindowEvent according to the XFlush man page.
273 XTread_socket calls XPending. Removing XFlush improves
274 performance. */
276 #define XFlush(DISPLAY) (void) 0
278 \f
279 /***********************************************************************
280 Debugging
281 ***********************************************************************/
283 #if false
285 /* This is a function useful for recording debugging information about
286 the sequence of occurrences in this file. */
288 struct record
290 char *locus;
291 int type;
292 };
294 struct record event_record[100];
296 int event_record_index;
298 void
299 record_event (char *locus, int type)
301 if (event_record_index == ARRAYELTS (event_record))
302 event_record_index = 0;
304 event_record[event_record_index].locus = locus;
305 event_record[event_record_index].type = type;
306 event_record_index++;
309 #endif
311 #ifdef USE_CAIRO
313 #define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
314 #define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
316 static struct x_gc_ext_data *
317 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
319 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
320 XEDataObject object;
321 XExtData **head, *ext_data;
323 object.gc = gc;
324 head = XEHeadOfExtensionList (object);
325 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
326 if (ext_data == NULL)
328 if (!create_if_not_found_p)
329 return NULL;
330 else
332 ext_data = xzalloc (sizeof (*ext_data));
333 ext_data->number = dpyinfo->ext_codes->extension;
334 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
335 XAddToExtensionList (head, ext_data);
338 return (struct x_gc_ext_data *) ext_data->private_data;
341 static void
342 x_extension_initialize (struct x_display_info *dpyinfo)
344 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
346 dpyinfo->ext_codes = ext_codes;
349 static void
350 x_cr_destroy_surface (struct frame *f)
352 if (FRAME_CR_SURFACE (f))
354 cairo_t *cr = FRAME_CR_CONTEXT (f);
355 cairo_surface_destroy (FRAME_CR_SURFACE (f));
356 FRAME_CR_SURFACE (f) = 0;
357 if (cr) cairo_destroy (cr);
358 FRAME_CR_CONTEXT (f) = NULL;
362 cairo_t *
363 x_begin_cr_clip (struct frame *f, GC gc)
365 cairo_t *cr = FRAME_CR_CONTEXT (f);
367 if (!cr)
370 if (! FRAME_CR_SURFACE (f))
372 cairo_surface_t *surface;
373 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
374 FRAME_X_WINDOW (f),
375 FRAME_DISPLAY_INFO (f)->visual,
376 FRAME_PIXEL_WIDTH (f),
377 FRAME_PIXEL_HEIGHT (f));
378 cr = cairo_create (surface);
379 cairo_surface_destroy (surface);
381 else
382 cr = cairo_create (FRAME_CR_SURFACE (f));
383 FRAME_CR_CONTEXT (f) = cr;
385 cairo_save (cr);
387 if (gc)
389 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
391 if (gc_ext && gc_ext->n_clip_rects)
393 int i;
395 for (i = 0; i < gc_ext->n_clip_rects; i++)
396 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
397 gc_ext->clip_rects[i].y,
398 gc_ext->clip_rects[i].width,
399 gc_ext->clip_rects[i].height);
400 cairo_clip (cr);
404 return cr;
407 void
408 x_end_cr_clip (struct frame *f)
410 cairo_restore (FRAME_CR_CONTEXT (f));
413 void
414 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
416 XGCValues xgcv;
417 XColor color;
419 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
420 color.pixel = xgcv.foreground;
421 x_query_color (f, &color);
422 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
423 color.green / 65535.0, color.blue / 65535.0);
426 void
427 x_set_cr_source_with_gc_background (struct frame *f, GC gc)
429 XGCValues xgcv;
430 XColor color;
432 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
433 color.pixel = xgcv.background;
434 x_query_color (f, &color);
435 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
436 color.green / 65535.0, color.blue / 65535.0);
439 /* Fringe bitmaps. */
441 static int max_fringe_bmp = 0;
442 static cairo_pattern_t **fringe_bmp = 0;
444 static void
445 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
447 int i, stride;
448 cairo_surface_t *surface;
449 unsigned char *data;
450 cairo_pattern_t *pattern;
452 if (which >= max_fringe_bmp)
454 i = max_fringe_bmp;
455 max_fringe_bmp = which + 20;
456 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
457 while (i < max_fringe_bmp)
458 fringe_bmp[i++] = 0;
461 block_input ();
463 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
464 stride = cairo_image_surface_get_stride (surface);
465 data = cairo_image_surface_get_data (surface);
467 for (i = 0; i < h; i++)
469 *((unsigned short *) data) = bits[i];
470 data += stride;
473 cairo_surface_mark_dirty (surface);
474 pattern = cairo_pattern_create_for_surface (surface);
475 cairo_surface_destroy (surface);
477 unblock_input ();
479 fringe_bmp[which] = pattern;
482 static void
483 x_cr_destroy_fringe_bitmap (int which)
485 if (which >= max_fringe_bmp)
486 return;
488 if (fringe_bmp[which])
490 block_input ();
491 cairo_pattern_destroy (fringe_bmp[which]);
492 unblock_input ();
494 fringe_bmp[which] = 0;
497 static void
498 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
499 int src_x, int src_y, int width, int height,
500 int dest_x, int dest_y, bool overlay_p)
502 cairo_t *cr;
503 cairo_matrix_t matrix;
504 cairo_surface_t *surface;
505 cairo_format_t format;
507 cr = x_begin_cr_clip (f, gc);
508 if (overlay_p)
509 cairo_rectangle (cr, dest_x, dest_y, width, height);
510 else
512 x_set_cr_source_with_gc_background (f, gc);
513 cairo_rectangle (cr, dest_x, dest_y, width, height);
514 cairo_fill_preserve (cr);
516 cairo_clip (cr);
517 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
518 cairo_pattern_set_matrix (image, &matrix);
519 cairo_pattern_get_surface (image, &surface);
520 format = cairo_image_surface_get_format (surface);
521 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
523 cairo_set_source (cr, image);
524 cairo_fill (cr);
526 else
528 x_set_cr_source_with_gc_foreground (f, gc);
529 cairo_mask (cr, image);
531 x_end_cr_clip (f);
534 void
535 x_cr_draw_frame (cairo_t *cr, struct frame *f)
537 int width, height;
539 width = FRAME_PIXEL_WIDTH (f);
540 height = FRAME_PIXEL_HEIGHT (f);
542 x_free_cr_resources (f);
543 FRAME_CR_CONTEXT (f) = cr;
544 x_clear_area (f, 0, 0, width, height);
545 expose_frame (f, 0, 0, width, height);
546 FRAME_CR_CONTEXT (f) = NULL;
549 static cairo_status_t
550 x_cr_accumulate_data (void *closure, const unsigned char *data,
551 unsigned int length)
553 Lisp_Object *acc = (Lisp_Object *) closure;
555 *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
557 return CAIRO_STATUS_SUCCESS;
560 static void
561 x_cr_destroy (Lisp_Object arg)
563 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
565 block_input ();
566 cairo_destroy (cr);
567 unblock_input ();
570 Lisp_Object
571 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
573 struct frame *f;
574 cairo_surface_t *surface;
575 cairo_t *cr;
576 int width, height;
577 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
578 Lisp_Object acc = Qnil, args[2];
579 int count = SPECPDL_INDEX ();
581 Fredisplay (Qt);
583 f = XFRAME (XCAR (frames));
584 frames = XCDR (frames);
585 width = FRAME_PIXEL_WIDTH (f);
586 height = FRAME_PIXEL_HEIGHT (f);
588 block_input ();
589 #ifdef CAIRO_HAS_PDF_SURFACE
590 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
592 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
593 width, height);
594 surface_set_size_func = cairo_pdf_surface_set_size;
596 else
597 #endif
598 #ifdef CAIRO_HAS_PNG_FUNCTIONS
599 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
600 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
601 else
602 #endif
603 #ifdef CAIRO_HAS_PS_SURFACE
604 if (surface_type == CAIRO_SURFACE_TYPE_PS)
606 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
607 width, height);
608 surface_set_size_func = cairo_ps_surface_set_size;
610 else
611 #endif
612 #ifdef CAIRO_HAS_SVG_SURFACE
613 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
614 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
615 width, height);
616 else
617 #endif
618 abort ();
620 cr = cairo_create (surface);
621 cairo_surface_destroy (surface);
622 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
623 unblock_input ();
625 while (1)
627 QUIT;
629 block_input ();
630 x_free_cr_resources (f);
631 FRAME_CR_CONTEXT (f) = cr;
632 x_clear_area (f, 0, 0, width, height);
633 expose_frame (f, 0, 0, width, height);
634 FRAME_CR_CONTEXT (f) = NULL;
635 unblock_input ();
637 if (NILP (frames))
638 break;
640 block_input ();
641 cairo_surface_show_page (surface);
642 f = XFRAME (XCAR (frames));
643 frames = XCDR (frames);
644 width = FRAME_PIXEL_WIDTH (f);
645 height = FRAME_PIXEL_HEIGHT (f);
646 if (surface_set_size_func)
647 (*surface_set_size_func) (surface, width, height);
648 unblock_input ();
651 #ifdef CAIRO_HAS_PNG_FUNCTIONS
652 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
654 block_input ();
655 cairo_surface_flush (surface);
656 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
657 unblock_input ();
659 #endif
660 unbind_to (count, Qnil);
662 args[0] = intern ("concat");
663 args[1] = Fnreverse (acc);
664 return Fapply (2, args);
667 #endif /* USE_CAIRO */
669 static void
670 x_free_cr_resources (struct frame *f)
672 #ifdef USE_CAIRO
673 if (f == NULL)
675 Lisp_Object rest, frame;
676 FOR_EACH_FRAME (rest, frame)
677 if (FRAME_X_P (XFRAME (frame)))
678 x_free_cr_resources (XFRAME (frame));
680 else
682 cairo_t *cr = FRAME_CR_CONTEXT (f);
684 if (cr)
686 cairo_surface_t *surface = cairo_get_target (cr);
688 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
690 cairo_destroy (cr);
691 FRAME_CR_CONTEXT (f) = NULL;
695 #endif
698 static void
699 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
701 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
702 #ifdef USE_CAIRO
703 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
706 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
708 gc_ext->n_clip_rects = n;
709 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
711 #endif
714 static void
715 x_reset_clip_rectangles (struct frame *f, GC gc)
717 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
718 #ifdef USE_CAIRO
720 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
722 if (gc_ext)
723 gc_ext->n_clip_rects = 0;
725 #endif
728 static void
729 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
731 #ifdef USE_CAIRO
732 cairo_t *cr;
734 cr = x_begin_cr_clip (f, gc);
735 x_set_cr_source_with_gc_foreground (f, gc);
736 cairo_rectangle (cr, x, y, width, height);
737 cairo_fill (cr);
738 x_end_cr_clip (f);
739 #else
740 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
741 gc, x, y, width, height);
742 #endif
745 static void
746 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
748 #ifdef USE_CAIRO
749 cairo_t *cr;
751 cr = x_begin_cr_clip (f, gc);
752 x_set_cr_source_with_gc_foreground (f, gc);
753 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
754 cairo_set_line_width (cr, 1);
755 cairo_stroke (cr);
756 x_end_cr_clip (f);
757 #else
758 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
759 gc, x, y, width, height);
760 #endif
763 static void
764 x_clear_window (struct frame *f)
766 #ifdef USE_CAIRO
767 cairo_t *cr;
769 cr = x_begin_cr_clip (f, NULL);
770 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
771 cairo_paint (cr);
772 x_end_cr_clip (f);
773 #else
774 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
775 #endif
778 #ifdef USE_CAIRO
779 static void
780 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
781 int width, int height, int top_p)
783 cairo_t *cr;
785 cr = x_begin_cr_clip (f, gc);
786 x_set_cr_source_with_gc_foreground (f, gc);
787 cairo_move_to (cr, top_p ? x : x + height, y);
788 cairo_line_to (cr, x, y + height);
789 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
790 cairo_line_to (cr, x + width, y);
791 cairo_fill (cr);
792 x_end_cr_clip (f);
795 enum corners
797 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
798 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
799 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
800 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
801 CORNER_LAST
802 };
804 static void
805 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
806 int width, int height,
807 double radius, double margin, int corners)
809 cairo_t *cr;
810 int i;
812 cr = x_begin_cr_clip (f, gc);
813 x_set_cr_source_with_gc_background (f, gc);
814 for (i = 0; i < CORNER_LAST; i++)
815 if (corners & (1 << i))
817 double xm, ym, xc, yc;
819 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
820 xm = x - margin, xc = xm + radius;
821 else
822 xm = x + width + margin, xc = xm - radius;
823 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
824 ym = y - margin, yc = ym + radius;
825 else
826 ym = y + height + margin, yc = ym - radius;
828 cairo_move_to (cr, xm, ym);
829 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
831 cairo_clip (cr);
832 cairo_rectangle (cr, x, y, width, height);
833 cairo_fill (cr);
834 x_end_cr_clip (f);
837 static void
838 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
839 int width, int height, int wave_length)
841 cairo_t *cr;
842 double dx = wave_length, dy = height - 1;
843 int xoffset, n;
845 cr = x_begin_cr_clip (f, gc);
846 x_set_cr_source_with_gc_foreground (f, gc);
847 cairo_rectangle (cr, x, y, width, height);
848 cairo_clip (cr);
850 if (x >= 0)
852 xoffset = x % (wave_length * 2);
853 if (xoffset == 0)
854 xoffset = wave_length * 2;
856 else
857 xoffset = x % (wave_length * 2) + wave_length * 2;
858 n = (width + xoffset) / wave_length + 1;
859 if (xoffset > wave_length)
861 xoffset -= wave_length;
862 --n;
863 y += height - 1;
864 dy = -dy;
867 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
868 while (--n >= 0)
870 cairo_rel_line_to (cr, dx, dy);
871 dy = -dy;
873 cairo_set_line_width (cr, 1);
874 cairo_stroke (cr);
875 x_end_cr_clip (f);
877 #endif
879 \f
880 /* Return the struct x_display_info corresponding to DPY. */
882 struct x_display_info *
883 x_display_info_for_display (Display *dpy)
885 struct x_display_info *dpyinfo;
887 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
888 if (dpyinfo->display == dpy)
889 return dpyinfo;
891 return 0;
894 static Window
895 x_find_topmost_parent (struct frame *f)
897 struct x_output *x = f->output_data.x;
898 Window win = None, wi = x->parent_desc;
899 Display *dpy = FRAME_X_DISPLAY (f);
901 while (wi != FRAME_DISPLAY_INFO (f)->root_window)
903 Window root;
904 Window *children;
905 unsigned int nchildren;
907 win = wi;
908 if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
909 XFree (children);
910 else
911 break;
914 return win;
917 #define OPAQUE 0xffffffff
919 void
920 x_set_frame_alpha (struct frame *f)
922 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
923 Display *dpy = FRAME_X_DISPLAY (f);
924 Window win = FRAME_OUTER_WINDOW (f);
925 double alpha = 1.0;
926 double alpha_min = 1.0;
927 unsigned long opac;
928 Window parent;
930 if (dpyinfo->x_highlight_frame == f)
931 alpha = f->alpha[0];
932 else
933 alpha = f->alpha[1];
935 if (FLOATP (Vframe_alpha_lower_limit))
936 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
937 else if (INTEGERP (Vframe_alpha_lower_limit))
938 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
940 if (alpha < 0.0)
941 return;
942 else if (alpha > 1.0)
943 alpha = 1.0;
944 else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
945 alpha = alpha_min;
947 opac = alpha * OPAQUE;
949 x_catch_errors (dpy);
951 /* If there is a parent from the window manager, put the property there
952 also, to work around broken window managers that fail to do that.
953 Do this unconditionally as this function is called on reparent when
954 alpha has not changed on the frame. */
956 parent = x_find_topmost_parent (f);
957 if (parent != None)
958 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
959 XA_CARDINAL, 32, PropModeReplace,
960 (unsigned char *) &opac, 1);
962 /* return unless necessary */
964 unsigned char *data;
965 Atom actual;
966 int rc, format;
967 unsigned long n, left;
969 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
970 0, 1, False, XA_CARDINAL,
971 &actual, &format, &n, &left,
972 &data);
974 if (rc == Success && actual != None)
976 unsigned long value = *(unsigned long *)data;
977 XFree (data);
978 if (value == opac)
980 x_uncatch_errors ();
981 return;
986 XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
987 XA_CARDINAL, 32, PropModeReplace,
988 (unsigned char *) &opac, 1);
989 x_uncatch_errors ();
992 /***********************************************************************
993 Starting and ending an update
994 ***********************************************************************/
996 /* Start an update of frame F. This function is installed as a hook
997 for update_begin, i.e. it is called when update_begin is called.
998 This function is called prior to calls to x_update_window_begin for
999 each window being updated. Currently, there is nothing to do here
1000 because all interesting stuff is done on a window basis. */
1002 static void
1003 x_update_begin (struct frame *f)
1005 #ifdef USE_CAIRO
1006 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
1007 && ! FRAME_VISIBLE_P (f))
1008 return;
1010 if (! FRAME_CR_SURFACE (f))
1012 int width, height;
1013 #ifdef USE_GTK
1014 if (FRAME_GTK_WIDGET (f))
1016 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1017 width = gdk_window_get_width (w);
1018 height = gdk_window_get_height (w);
1020 else
1021 #endif
1023 width = FRAME_PIXEL_WIDTH (f);
1024 height = FRAME_PIXEL_HEIGHT (f);
1025 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1026 height += FRAME_TOOL_BAR_HEIGHT (f);
1027 if (! FRAME_EXTERNAL_MENU_BAR (f))
1028 height += FRAME_MENU_BAR_HEIGHT (f);
1031 if (width > 0 && height > 0)
1033 block_input();
1034 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1035 (CAIRO_FORMAT_ARGB32, width, height);
1036 unblock_input();
1039 #endif /* USE_CAIRO */
1042 /* Start update of window W. */
1044 static void
1045 x_update_window_begin (struct window *w)
1047 struct frame *f = XFRAME (WINDOW_FRAME (w));
1048 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1050 w->output_cursor = w->cursor;
1052 block_input ();
1054 if (f == hlinfo->mouse_face_mouse_frame)
1056 /* Don't do highlighting for mouse motion during the update. */
1057 hlinfo->mouse_face_defer = true;
1059 /* If F needs to be redrawn, simply forget about any prior mouse
1060 highlighting. */
1061 if (FRAME_GARBAGED_P (f))
1062 hlinfo->mouse_face_window = Qnil;
1065 unblock_input ();
1069 /* Draw a vertical window border from (x,y0) to (x,y1) */
1071 static void
1072 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
1074 struct frame *f = XFRAME (WINDOW_FRAME (w));
1075 struct face *face;
1077 face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
1078 if (face)
1079 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
1080 face->foreground);
1082 #ifdef USE_CAIRO
1083 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1084 #else
1085 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1086 f->output_data.x->normal_gc, x, y0, x, y1);
1087 #endif
1090 /* Draw a window divider from (x0,y0) to (x1,y1) */
1092 static void
1093 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
1095 struct frame *f = XFRAME (WINDOW_FRAME (w));
1096 struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
1097 struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
1098 struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
1099 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
1100 unsigned long color_first = (face_first
1101 ? face_first->foreground
1102 : FRAME_FOREGROUND_PIXEL (f));
1103 unsigned long color_last = (face_last
1104 ? face_last->foreground
1105 : FRAME_FOREGROUND_PIXEL (f));
1106 Display *display = FRAME_X_DISPLAY (f);
1108 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
1109 /* Vertical. */
1111 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1112 x_fill_rectangle (f, f->output_data.x->normal_gc,
1113 x0, y0, 1, y1 - y0);
1114 XSetForeground (display, f->output_data.x->normal_gc, color);
1115 x_fill_rectangle (f, f->output_data.x->normal_gc,
1116 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
1117 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1118 x_fill_rectangle (f, f->output_data.x->normal_gc,
1119 x1 - 1, y0, 1, y1 - y0);
1121 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
1122 /* Horizontal. */
1124 XSetForeground (display, f->output_data.x->normal_gc, color_first);
1125 x_fill_rectangle (f, f->output_data.x->normal_gc,
1126 x0, y0, x1 - x0, 1);
1127 XSetForeground (display, f->output_data.x->normal_gc, color);
1128 x_fill_rectangle (f, f->output_data.x->normal_gc,
1129 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
1130 XSetForeground (display, f->output_data.x->normal_gc, color_last);
1131 x_fill_rectangle (f, f->output_data.x->normal_gc,
1132 x0, y1 - 1, x1 - x0, 1);
1134 else
1136 XSetForeground (display, f->output_data.x->normal_gc, color);
1137 x_fill_rectangle (f, f->output_data.x->normal_gc,
1138 x0, y0, x1 - x0, y1 - y0);
1142 /* End update of window W.
1144 Draw vertical borders between horizontally adjacent windows, and
1145 display W's cursor if CURSOR_ON_P is non-zero.
1147 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1148 glyphs in mouse-face were overwritten. In that case we have to
1149 make sure that the mouse-highlight is properly redrawn.
1151 W may be a menu bar pseudo-window in case we don't have X toolkit
1152 support. Such windows don't have a cursor, so don't display it
1153 here. */
1155 static void
1156 x_update_window_end (struct window *w, bool cursor_on_p,
1157 bool mouse_face_overwritten_p)
1159 if (!w->pseudo_window_p)
1161 block_input ();
1163 if (cursor_on_p)
1164 display_and_set_cursor (w, true,
1165 w->output_cursor.hpos, w->output_cursor.vpos,
1166 w->output_cursor.x, w->output_cursor.y);
1168 if (draw_window_fringes (w, true))
1170 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
1171 x_draw_right_divider (w);
1172 else
1173 x_draw_vertical_border (w);
1176 unblock_input ();
1179 /* If a row with mouse-face was overwritten, arrange for
1180 XTframe_up_to_date to redisplay the mouse highlight. */
1181 if (mouse_face_overwritten_p)
1183 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
1185 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1186 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1187 hlinfo->mouse_face_window = Qnil;
1192 /* End update of frame F. This function is installed as a hook in
1193 update_end. */
1195 static void
1196 x_update_end (struct frame *f)
1198 /* Mouse highlight may be displayed again. */
1199 MOUSE_HL_INFO (f)->mouse_face_defer = false;
1201 #ifdef USE_CAIRO
1202 if (FRAME_CR_SURFACE (f))
1204 cairo_t *cr = 0;
1205 block_input();
1206 #if defined (USE_GTK) && defined (HAVE_GTK3)
1207 if (FRAME_GTK_WIDGET (f))
1209 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1210 cr = gdk_cairo_create (w);
1212 else
1213 #endif
1215 cairo_surface_t *surface;
1216 int width = FRAME_PIXEL_WIDTH (f);
1217 int height = FRAME_PIXEL_HEIGHT (f);
1218 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1219 height += FRAME_TOOL_BAR_HEIGHT (f);
1220 if (! FRAME_EXTERNAL_MENU_BAR (f))
1221 height += FRAME_MENU_BAR_HEIGHT (f);
1222 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1223 FRAME_X_WINDOW (f),
1224 FRAME_DISPLAY_INFO (f)->visual,
1225 width,
1226 height);
1227 cr = cairo_create (surface);
1228 cairo_surface_destroy (surface);
1231 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1232 cairo_paint (cr);
1233 cairo_destroy (cr);
1234 unblock_input ();
1236 #endif /* USE_CAIRO */
1238 #ifndef XFlush
1239 block_input ();
1240 XFlush (FRAME_X_DISPLAY (f));
1241 unblock_input ();
1242 #endif
1246 /* This function is called from various places in xdisp.c
1247 whenever a complete update has been performed. */
1249 static void
1250 XTframe_up_to_date (struct frame *f)
1252 if (FRAME_X_P (f))
1253 FRAME_MOUSE_UPDATE (f);
1257 /* Clear under internal border if any (GTK has its own version). */
1258 #ifndef USE_GTK
1259 void
1260 x_clear_under_internal_border (struct frame *f)
1262 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
1264 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1265 int width = FRAME_PIXEL_WIDTH (f);
1266 int height = FRAME_PIXEL_HEIGHT (f);
1267 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
1269 block_input ();
1270 x_clear_area (f, 0, 0, border, height);
1271 x_clear_area (f, 0, margin, width, border);
1272 x_clear_area (f, width - border, 0, border, height);
1273 x_clear_area (f, 0, height - border, width, border);
1274 unblock_input ();
1277 #endif
1279 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1280 arrow bitmaps, or clear the fringes if no bitmaps are required
1281 before DESIRED_ROW is made current. This function is called from
1282 update_window_line only if it is known that there are differences
1283 between bitmaps to be drawn between current row and DESIRED_ROW. */
1285 static void
1286 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
1288 eassert (w);
1290 if (!desired_row->mode_line_p && !w->pseudo_window_p)
1291 desired_row->redraw_fringe_bitmaps_p = true;
1293 #ifdef USE_X_TOOLKIT
1294 /* When a window has disappeared, make sure that no rest of
1295 full-width rows stays visible in the internal border. Could
1296 check here if updated window is the leftmost/rightmost window,
1297 but I guess it's not worth doing since vertically split windows
1298 are almost never used, internal border is rarely set, and the
1299 overhead is very small. */
1301 struct frame *f;
1302 int width, height;
1304 if (windows_or_buffers_changed
1305 && desired_row->full_width_p
1306 && (f = XFRAME (w->frame),
1307 width = FRAME_INTERNAL_BORDER_WIDTH (f),
1308 width != 0)
1309 && (height = desired_row->visible_height,
1310 height > 0))
1312 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
1314 block_input ();
1315 x_clear_area (f, 0, y, width, height);
1316 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
1317 unblock_input ();
1320 #endif
1323 static void
1324 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p)
1326 struct frame *f = XFRAME (WINDOW_FRAME (w));
1327 Display *display = FRAME_X_DISPLAY (f);
1328 Window window = FRAME_X_WINDOW (f);
1329 GC gc = f->output_data.x->normal_gc;
1330 struct face *face = p->face;
1332 /* Must clip because of partially visible lines. */
1333 x_clip_to_row (w, row, ANY_AREA, gc);
1335 if (p->bx >= 0 && !p->overlay_p)
1337 /* In case the same realized face is used for fringes and
1338 for something displayed in the text (e.g. face `region' on
1339 mono-displays, the fill style may have been changed to
1340 FillSolid in x_draw_glyph_string_background. */
1341 if (face->stipple)
1342 XSetFillStyle (display, face->gc, FillOpaqueStippled);
1343 else
1344 XSetForeground (display, face->gc, face->background);
1346 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
1348 if (!face->stipple)
1349 XSetForeground (display, face->gc, face->foreground);
1352 #ifdef USE_CAIRO
1353 if (p->which && p->which < max_fringe_bmp)
1355 XGCValues gcv;
1357 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1358 XSetForeground (display, gc, (p->cursor_p
1359 ? (p->overlay_p ? face->background
1360 : f->output_data.x->cursor_pixel)
1361 : face->foreground));
1362 XSetBackground (display, gc, face->background);
1363 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1364 p->wd, p->h, p->x, p->y, p->overlay_p);
1365 XSetForeground (display, gc, gcv.foreground);
1366 XSetBackground (display, gc, gcv.background);
1368 #else /* not USE_CAIRO */
1369 if (p->which)
1371 char *bits;
1372 Pixmap pixmap, clipmask = (Pixmap) 0;
1373 int depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
1374 XGCValues gcv;
1376 if (p->wd > 8)
1377 bits = (char *) (p->bits + p->dh);
1378 else
1379 bits = (char *) p->bits + p->dh;
1381 /* Draw the bitmap. I believe these small pixmaps can be cached
1382 by the server. */
1383 pixmap = XCreatePixmapFromBitmapData (display, window, bits, p->wd, p->h,
1384 (p->cursor_p
1385 ? (p->overlay_p ? face->background
1386 : f->output_data.x->cursor_pixel)
1387 : face->foreground),
1388 face->background, depth);
1390 if (p->overlay_p)
1392 clipmask = XCreatePixmapFromBitmapData (display,
1393 FRAME_DISPLAY_INFO (f)->root_window,
1394 bits, p->wd, p->h,
1395 1, 0, 1);
1396 gcv.clip_mask = clipmask;
1397 gcv.clip_x_origin = p->x;
1398 gcv.clip_y_origin = p->y;
1399 XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
1402 XCopyArea (display, pixmap, window, gc, 0, 0,
1403 p->wd, p->h, p->x, p->y);
1404 XFreePixmap (display, pixmap);
1406 if (p->overlay_p)
1408 gcv.clip_mask = (Pixmap) 0;
1409 XChangeGC (display, gc, GCClipMask, &gcv);
1410 XFreePixmap (display, clipmask);
1413 #endif /* not USE_CAIRO */
1415 x_reset_clip_rectangles (f, gc);
1418 /***********************************************************************
1419 Glyph display
1420 ***********************************************************************/
1424 static void x_set_glyph_string_clipping (struct glyph_string *);
1425 static void x_set_glyph_string_gc (struct glyph_string *);
1426 static void x_draw_glyph_string_foreground (struct glyph_string *);
1427 static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
1428 static void x_draw_glyph_string_box (struct glyph_string *);
1429 static void x_draw_glyph_string (struct glyph_string *);
1430 static _Noreturn void x_delete_glyphs (struct frame *, int);
1431 static void x_compute_glyph_string_overhangs (struct glyph_string *);
1432 static void x_set_cursor_gc (struct glyph_string *);
1433 static void x_set_mode_line_face_gc (struct glyph_string *);
1434 static void x_set_mouse_face_gc (struct glyph_string *);
1435 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
1436 unsigned long *, double, int);
1437 static void x_setup_relief_color (struct frame *, struct relief *,
1438 double, int, unsigned long);
1439 static void x_setup_relief_colors (struct glyph_string *);
1440 static void x_draw_image_glyph_string (struct glyph_string *);
1441 static void x_draw_image_relief (struct glyph_string *);
1442 static void x_draw_image_foreground (struct glyph_string *);
1443 static void x_draw_image_foreground_1 (struct glyph_string *, Pixmap);
1444 static void x_clear_glyph_string_rect (struct glyph_string *, int,
1445 int, int, int);
1446 static void x_draw_relief_rect (struct frame *, int, int, int, int,
1447 int, bool, bool, bool, bool, bool,
1448 XRectangle *);
1449 static void x_draw_box_rect (struct glyph_string *, int, int, int, int,
1450 int, bool, bool, XRectangle *);
1451 static void x_scroll_bar_clear (struct frame *);
1453 #ifdef GLYPH_DEBUG
1454 static void x_check_font (struct frame *, struct font *);
1455 #endif
1458 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1459 face. */
1461 static void
1462 x_set_cursor_gc (struct glyph_string *s)
1464 if (s->font == FRAME_FONT (s->f)
1465 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1466 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1467 && !s->cmp)
1468 s->gc = s->f->output_data.x->cursor_gc;
1469 else
1471 /* Cursor on non-default face: must merge. */
1472 XGCValues xgcv;
1473 unsigned long mask;
1475 xgcv.background = s->f->output_data.x->cursor_pixel;
1476 xgcv.foreground = s->face->background;
1478 /* If the glyph would be invisible, try a different foreground. */
1479 if (xgcv.foreground == xgcv.background)
1480 xgcv.foreground = s->face->foreground;
1481 if (xgcv.foreground == xgcv.background)
1482 xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
1483 if (xgcv.foreground == xgcv.background)
1484 xgcv.foreground = s->face->foreground;
1486 /* Make sure the cursor is distinct from text in this face. */
1487 if (xgcv.background == s->face->background
1488 && xgcv.foreground == s->face->foreground)
1490 xgcv.background = s->face->foreground;
1491 xgcv.foreground = s->face->background;
1494 IF_DEBUG (x_check_font (s->f, s->font));
1495 xgcv.graphics_exposures = False;
1496 mask = GCForeground | GCBackground | GCGraphicsExposures;
1498 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1499 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1500 mask, &xgcv);
1501 else
1502 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1503 = XCreateGC (s->display, s->window, mask, &xgcv);
1505 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1510 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1512 static void
1513 x_set_mouse_face_gc (struct glyph_string *s)
1515 int face_id;
1516 struct face *face;
1518 /* What face has to be used last for the mouse face? */
1519 face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
1520 face = FACE_FROM_ID (s->f, face_id);
1521 if (face == NULL)
1522 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1524 if (s->first_glyph->type == CHAR_GLYPH)
1525 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1526 else
1527 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1528 s->face = FACE_FROM_ID (s->f, face_id);
1529 prepare_face_for_display (s->f, s->face);
1531 if (s->font == s->face->font)
1532 s->gc = s->face->gc;
1533 else
1535 /* Otherwise construct scratch_cursor_gc with values from FACE
1536 except for FONT. */
1537 XGCValues xgcv;
1538 unsigned long mask;
1540 xgcv.background = s->face->background;
1541 xgcv.foreground = s->face->foreground;
1542 xgcv.graphics_exposures = False;
1543 mask = GCForeground | GCBackground | GCGraphicsExposures;
1545 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1546 XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1547 mask, &xgcv);
1548 else
1549 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1550 = XCreateGC (s->display, s->window, mask, &xgcv);
1552 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1555 eassert (s->gc != 0);
1559 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1560 Faces to use in the mode line have already been computed when the
1561 matrix was built, so there isn't much to do, here. */
1563 static void
1564 x_set_mode_line_face_gc (struct glyph_string *s)
1566 s->gc = s->face->gc;
1570 /* Set S->gc of glyph string S for drawing that glyph string. Set
1571 S->stippled_p to a non-zero value if the face of S has a stipple
1572 pattern. */
1574 static void
1575 x_set_glyph_string_gc (struct glyph_string *s)
1577 prepare_face_for_display (s->f, s->face);
1579 if (s->hl == DRAW_NORMAL_TEXT)
1581 s->gc = s->face->gc;
1582 s->stippled_p = s->face->stipple != 0;
1584 else if (s->hl == DRAW_INVERSE_VIDEO)
1586 x_set_mode_line_face_gc (s);
1587 s->stippled_p = s->face->stipple != 0;
1589 else if (s->hl == DRAW_CURSOR)
1591 x_set_cursor_gc (s);
1592 s->stippled_p = false;
1594 else if (s->hl == DRAW_MOUSE_FACE)
1596 x_set_mouse_face_gc (s);
1597 s->stippled_p = s->face->stipple != 0;
1599 else if (s->hl == DRAW_IMAGE_RAISED
1600 || s->hl == DRAW_IMAGE_SUNKEN)
1602 s->gc = s->face->gc;
1603 s->stippled_p = s->face->stipple != 0;
1605 else
1606 emacs_abort ();
1608 /* GC must have been set. */
1609 eassert (s->gc != 0);
1613 /* Set clipping for output of glyph string S. S may be part of a mode
1614 line or menu if we don't have X toolkit support. */
1616 static void
1617 x_set_glyph_string_clipping (struct glyph_string *s)
1619 XRectangle *r = s->clip;
1620 int n = get_glyph_string_clip_rects (s, r, 2);
1622 if (n > 0)
1623 x_set_clip_rectangles (s->f, s->gc, r, n);
1624 s->num_clips = n;
1628 /* Set SRC's clipping for output of glyph string DST. This is called
1629 when we are drawing DST's left_overhang or right_overhang only in
1630 the area of SRC. */
1632 static void
1633 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
1635 XRectangle r;
1637 r.x = src->x;
1638 r.width = src->width;
1639 r.y = src->y;
1640 r.height = src->height;
1641 dst->clip[0] = r;
1642 dst->num_clips = 1;
1643 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1647 /* RIF:
1648 Compute left and right overhang of glyph string S. */
1650 static void
1651 x_compute_glyph_string_overhangs (struct glyph_string *s)
1653 if (s->cmp == NULL
1654 && (s->first_glyph->type == CHAR_GLYPH
1655 || s->first_glyph->type == COMPOSITE_GLYPH))
1657 struct font_metrics metrics;
1659 if (s->first_glyph->type == CHAR_GLYPH)
1661 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1662 struct font *font = s->font;
1663 int i;
1665 for (i = 0; i < s->nchars; i++)
1666 code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
1667 font->driver->text_extents (font, code, s->nchars, &metrics);
1669 else
1671 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1673 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1675 s->right_overhang = (metrics.rbearing > metrics.width
1676 ? metrics.rbearing - metrics.width : 0);
1677 s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
1679 else if (s->cmp)
1681 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1682 s->left_overhang = - s->cmp->lbearing;
1687 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1689 static void
1690 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1692 XGCValues xgcv;
1693 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1694 XSetForeground (s->display, s->gc, xgcv.background);
1695 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1696 XSetForeground (s->display, s->gc, xgcv.foreground);
1700 /* Draw the background of glyph_string S. If S->background_filled_p
1701 is non-zero don't draw it. FORCE_P non-zero means draw the
1702 background even if it wouldn't be drawn normally. This is used
1703 when a string preceding S draws into the background of S, or S
1704 contains the first component of a composition. */
1706 static void
1707 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1709 /* Nothing to do if background has already been drawn or if it
1710 shouldn't be drawn in the first place. */
1711 if (!s->background_filled_p)
1713 int box_line_width = max (s->face->box_line_width, 0);
1715 if (s->stippled_p)
1717 /* Fill background with a stipple pattern. */
1718 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1719 x_fill_rectangle (s->f, s->gc, s->x,
1720 s->y + box_line_width,
1721 s->background_width,
1722 s->height - 2 * box_line_width);
1723 XSetFillStyle (s->display, s->gc, FillSolid);
1724 s->background_filled_p = true;
1726 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1727 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1728 font dimensions, since the actual glyphs might be
1729 much smaller. So in that case we always clear the
1730 rectangle with background color. */
1731 || FONT_TOO_HIGH (s->font)
1732 || s->font_not_found_p
1733 || s->extends_to_end_of_line_p
1734 || force_p)
1736 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1737 s->background_width,
1738 s->height - 2 * box_line_width);
1739 s->background_filled_p = true;
1745 /* Draw the foreground of glyph string S. */
1747 static void
1748 x_draw_glyph_string_foreground (struct glyph_string *s)
1750 int i, x;
1752 /* If first glyph of S has a left box line, start drawing the text
1753 of S to the right of that box line. */
1754 if (s->face->box != FACE_NO_BOX
1755 && s->first_glyph->left_box_line_p)
1756 x = s->x + eabs (s->face->box_line_width);
1757 else
1758 x = s->x;
1760 /* Draw characters of S as rectangles if S's font could not be
1761 loaded. */
1762 if (s->font_not_found_p)
1764 for (i = 0; i < s->nchars; ++i)
1766 struct glyph *g = s->first_glyph + i;
1767 x_draw_rectangle (s->f,
1768 s->gc, x, s->y, g->pixel_width - 1,
1769 s->height - 1);
1770 x += g->pixel_width;
1773 else
1775 struct font *font = s->font;
1776 int boff = font->baseline_offset;
1777 int y;
1779 if (font->vertical_centering)
1780 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1782 y = s->ybase - boff;
1783 if (s->for_overlaps
1784 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1785 font->driver->draw (s, 0, s->nchars, x, y, false);
1786 else
1787 font->driver->draw (s, 0, s->nchars, x, y, true);
1788 if (s->face->overstrike)
1789 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1793 /* Draw the foreground of composite glyph string S. */
1795 static void
1796 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1798 int i, j, x;
1799 struct font *font = s->font;
1801 /* If first glyph of S has a left box line, start drawing the text
1802 of S to the right of that box line. */
1803 if (s->face && s->face->box != FACE_NO_BOX
1804 && s->first_glyph->left_box_line_p)
1805 x = s->x + eabs (s->face->box_line_width);
1806 else
1807 x = s->x;
1809 /* S is a glyph string for a composition. S->cmp_from is the index
1810 of the first character drawn for glyphs of this composition.
1811 S->cmp_from == 0 means we are drawing the very first character of
1812 this composition. */
1814 /* Draw a rectangle for the composition if the font for the very
1815 first character of the composition could not be loaded. */
1816 if (s->font_not_found_p)
1818 if (s->cmp_from == 0)
1819 x_draw_rectangle (s->f, s->gc, x, s->y,
1820 s->width - 1, s->height - 1);
1822 else if (! s->first_glyph->u.cmp.automatic)
1824 int y = s->ybase;
1826 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1827 /* TAB in a composition means display glyphs with padding
1828 space on the left or right. */
1829 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1831 int xx = x + s->cmp->offsets[j * 2];
1832 int yy = y - s->cmp->offsets[j * 2 + 1];
1834 font->driver->draw (s, j, j + 1, xx, yy, false);
1835 if (s->face->overstrike)
1836 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1839 else
1841 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1842 Lisp_Object glyph;
1843 int y = s->ybase;
1844 int width = 0;
1846 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1848 glyph = LGSTRING_GLYPH (gstring, i);
1849 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1850 width += LGLYPH_WIDTH (glyph);
1851 else
1853 int xoff, yoff, wadjust;
1855 if (j < i)
1857 font->driver->draw (s, j, i, x, y, false);
1858 if (s->face->overstrike)
1859 font->driver->draw (s, j, i, x + 1, y, false);
1860 x += width;
1862 xoff = LGLYPH_XOFF (glyph);
1863 yoff = LGLYPH_YOFF (glyph);
1864 wadjust = LGLYPH_WADJUST (glyph);
1865 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1866 if (s->face->overstrike)
1867 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1868 false);
1869 x += wadjust;
1870 j = i + 1;
1871 width = 0;
1874 if (j < i)
1876 font->driver->draw (s, j, i, x, y, false);
1877 if (s->face->overstrike)
1878 font->driver->draw (s, j, i, x + 1, y, false);
1884 /* Draw the foreground of glyph string S for glyphless characters. */
1886 static void
1887 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1889 struct glyph *glyph = s->first_glyph;
1890 XChar2b char2b[8];
1891 int x, i, j;
1893 /* If first glyph of S has a left box line, start drawing the text
1894 of S to the right of that box line. */
1895 if (s->face && s->face->box != FACE_NO_BOX
1896 && s->first_glyph->left_box_line_p)
1897 x = s->x + eabs (s->face->box_line_width);
1898 else
1899 x = s->x;
1901 s->char2b = char2b;
1903 for (i = 0; i < s->nchars; i++, glyph++)
1905 char buf[7], *str = NULL;
1906 int len = glyph->u.glyphless.len;
1908 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1910 if (len > 0
1911 && CHAR_TABLE_P (Vglyphless_char_display)
1912 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1913 >= 1))
1915 Lisp_Object acronym
1916 = (! glyph->u.glyphless.for_no_font
1917 ? CHAR_TABLE_REF (Vglyphless_char_display,
1918 glyph->u.glyphless.ch)
1919 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1920 if (STRINGP (acronym))
1921 str = SSDATA (acronym);
1924 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1926 sprintf (buf, "%0*X",
1927 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1928 glyph->u.glyphless.ch + 0u);
1929 str = buf;
1932 if (str)
1934 int upper_len = (len + 1) / 2;
1935 unsigned code;
1937 /* It is assured that all LEN characters in STR is ASCII. */
1938 for (j = 0; j < len; j++)
1940 code = s->font->driver->encode_char (s->font, str[j]);
1941 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
1943 s->font->driver->draw (s, 0, upper_len,
1944 x + glyph->slice.glyphless.upper_xoff,
1945 s->ybase + glyph->slice.glyphless.upper_yoff,
1946 false);
1947 s->font->driver->draw (s, upper_len, len,
1948 x + glyph->slice.glyphless.lower_xoff,
1949 s->ybase + glyph->slice.glyphless.lower_yoff,
1950 false);
1952 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1953 x_draw_rectangle (s->f, s->gc,
1954 x, s->ybase - glyph->ascent,
1955 glyph->pixel_width - 1,
1956 glyph->ascent + glyph->descent - 1);
1957 x += glyph->pixel_width;
1961 #ifdef USE_X_TOOLKIT
1963 #ifdef USE_LUCID
1965 /* Return the frame on which widget WIDGET is used.. Abort if frame
1966 cannot be determined. */
1968 static struct frame *
1969 x_frame_of_widget (Widget widget)
1971 struct x_display_info *dpyinfo;
1972 Lisp_Object tail, frame;
1973 struct frame *f;
1975 dpyinfo = x_display_info_for_display (XtDisplay (widget));
1977 /* Find the top-level shell of the widget. Note that this function
1978 can be called when the widget is not yet realized, so XtWindow
1979 (widget) == 0. That's the reason we can't simply use
1980 x_any_window_to_frame. */
1981 while (!XtIsTopLevelShell (widget))
1982 widget = XtParent (widget);
1984 /* Look for a frame with that top-level widget. Allocate the color
1985 on that frame to get the right gamma correction value. */
1986 FOR_EACH_FRAME (tail, frame)
1988 f = XFRAME (frame);
1989 if (FRAME_X_P (f)
1990 && f->output_data.nothing != 1
1991 && FRAME_DISPLAY_INFO (f) == dpyinfo
1992 && f->output_data.x->widget == widget)
1993 return f;
1995 emacs_abort ();
1998 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
1999 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2000 If this produces the same color as PIXEL, try a color where all RGB
2001 values have DELTA added. Return the allocated color in *PIXEL.
2002 DISPLAY is the X display, CMAP is the colormap to operate on.
2003 Value is true if successful. */
2005 bool
2006 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2007 unsigned long *pixel, double factor, int delta)
2009 struct frame *f = x_frame_of_widget (widget);
2010 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2013 #endif /* USE_LUCID */
2016 /* Structure specifying which arguments should be passed by Xt to
2017 cvt_string_to_pixel. We want the widget's screen and colormap. */
2019 static XtConvertArgRec cvt_string_to_pixel_args[] =
2021 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2022 sizeof (Screen *)},
2023 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2024 sizeof (Colormap)}
2025 };
2028 /* The address of this variable is returned by
2029 cvt_string_to_pixel. */
2031 static Pixel cvt_string_to_pixel_value;
2034 /* Convert a color name to a pixel color.
2036 DPY is the display we are working on.
2038 ARGS is an array of *NARGS XrmValue structures holding additional
2039 information about the widget for which the conversion takes place.
2040 The contents of this array are determined by the specification
2041 in cvt_string_to_pixel_args.
2043 FROM is a pointer to an XrmValue which points to the color name to
2044 convert. TO is an XrmValue in which to return the pixel color.
2046 CLOSURE_RET is a pointer to user-data, in which we record if
2047 we allocated the color or not.
2049 Value is True if successful, False otherwise. */
2051 static Boolean
2052 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2053 XrmValue *from, XrmValue *to,
2054 XtPointer *closure_ret)
2056 Screen *screen;
2057 Colormap cmap;
2058 Pixel pixel;
2059 String color_name;
2060 XColor color;
2062 if (*nargs != 2)
2064 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2065 "wrongParameters", "cvt_string_to_pixel",
2066 "XtToolkitError",
2067 "Screen and colormap args required", NULL, NULL);
2068 return False;
2071 screen = *(Screen **) args[0].addr;
2072 cmap = *(Colormap *) args[1].addr;
2073 color_name = (String) from->addr;
2075 if (strcmp (color_name, XtDefaultBackground) == 0)
2077 *closure_ret = (XtPointer) False;
2078 pixel = WhitePixelOfScreen (screen);
2080 else if (strcmp (color_name, XtDefaultForeground) == 0)
2082 *closure_ret = (XtPointer) False;
2083 pixel = BlackPixelOfScreen (screen);
2085 else if (XParseColor (dpy, cmap, color_name, &color)
2086 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2088 pixel = color.pixel;
2089 *closure_ret = (XtPointer) True;
2091 else
2093 String params[1];
2094 Cardinal nparams = 1;
2096 params[0] = color_name;
2097 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2098 "badValue", "cvt_string_to_pixel",
2099 "XtToolkitError", "Invalid color '%s'",
2100 params, &nparams);
2101 return False;
2104 if (to->addr != NULL)
2106 if (to->size < sizeof (Pixel))
2108 to->size = sizeof (Pixel);
2109 return False;
2112 *(Pixel *) to->addr = pixel;
2114 else
2116 cvt_string_to_pixel_value = pixel;
2117 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2120 to->size = sizeof (Pixel);
2121 return True;
2125 /* Free a pixel color which was previously allocated via
2126 cvt_string_to_pixel. This is registered as the destructor
2127 for this type of resource via XtSetTypeConverter.
2129 APP is the application context in which we work.
2131 TO is a pointer to an XrmValue holding the color to free.
2132 CLOSURE is the value we stored in CLOSURE_RET for this color
2133 in cvt_string_to_pixel.
2135 ARGS and NARGS are like for cvt_string_to_pixel. */
2137 static void
2138 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2139 Cardinal *nargs)
2141 if (*nargs != 2)
2143 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2144 "XtToolkitError",
2145 "Screen and colormap arguments required",
2146 NULL, NULL);
2148 else if (closure != NULL)
2150 /* We did allocate the pixel, so free it. */
2151 Screen *screen = *(Screen **) args[0].addr;
2152 Colormap cmap = *(Colormap *) args[1].addr;
2153 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2154 (Pixel *) to->addr, 1);
2159 #endif /* USE_X_TOOLKIT */
2162 /* Value is an array of XColor structures for the contents of the
2163 color map of display DPY. Set *NCELLS to the size of the array.
2164 Note that this probably shouldn't be called for large color maps,
2165 say a 24-bit TrueColor map. */
2167 static const XColor *
2168 x_color_cells (Display *dpy, int *ncells)
2170 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2172 if (dpyinfo->color_cells == NULL)
2174 Screen *screen = dpyinfo->screen;
2175 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2176 int i;
2178 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2179 sizeof *dpyinfo->color_cells);
2180 dpyinfo->ncolor_cells = ncolor_cells;
2182 for (i = 0; i < ncolor_cells; ++i)
2183 dpyinfo->color_cells[i].pixel = i;
2185 XQueryColors (dpy, dpyinfo->cmap,
2186 dpyinfo->color_cells, ncolor_cells);
2189 *ncells = dpyinfo->ncolor_cells;
2190 return dpyinfo->color_cells;
2194 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2195 colors in COLORS. Use cached information, if available. */
2197 void
2198 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2200 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2202 if (dpyinfo->color_cells)
2204 int i;
2205 for (i = 0; i < ncolors; ++i)
2207 unsigned long pixel = colors[i].pixel;
2208 eassert (pixel < dpyinfo->ncolor_cells);
2209 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2210 colors[i] = dpyinfo->color_cells[pixel];
2213 else
2214 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2218 /* On frame F, translate pixel color to RGB values for the color in
2219 COLOR. Use cached information, if available. */
2221 void
2222 x_query_color (struct frame *f, XColor *color)
2224 x_query_colors (f, color, 1);
2228 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2229 exact match can't be allocated, try the nearest color available.
2230 Value is true if successful. Set *COLOR to the color
2231 allocated. */
2233 static bool
2234 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2236 bool rc;
2238 rc = XAllocColor (dpy, cmap, color) != 0;
2239 if (rc == 0)
2241 /* If we got to this point, the colormap is full, so we're going
2242 to try to get the next closest color. The algorithm used is
2243 a least-squares matching, which is what X uses for closest
2244 color matching with StaticColor visuals. */
2245 int nearest, i;
2246 int max_color_delta = 255;
2247 int max_delta = 3 * max_color_delta;
2248 int nearest_delta = max_delta + 1;
2249 int ncells;
2250 const XColor *cells = x_color_cells (dpy, &ncells);
2252 for (nearest = i = 0; i < ncells; ++i)
2254 int dred = (color->red >> 8) - (cells[i].red >> 8);
2255 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2256 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2257 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2259 if (delta < nearest_delta)
2261 nearest = i;
2262 nearest_delta = delta;
2266 color->red = cells[nearest].red;
2267 color->green = cells[nearest].green;
2268 color->blue = cells[nearest].blue;
2269 rc = XAllocColor (dpy, cmap, color) != 0;
2271 else
2273 /* If allocation succeeded, and the allocated pixel color is not
2274 equal to a cached pixel color recorded earlier, there was a
2275 change in the colormap, so clear the color cache. */
2276 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2277 XColor *cached_color;
2279 if (dpyinfo->color_cells
2280 && (cached_color = &dpyinfo->color_cells[color->pixel],
2281 (cached_color->red != color->red
2282 || cached_color->blue != color->blue
2283 || cached_color->green != color->green)))
2285 xfree (dpyinfo->color_cells);
2286 dpyinfo->color_cells = NULL;
2287 dpyinfo->ncolor_cells = 0;
2291 #ifdef DEBUG_X_COLORS
2292 if (rc)
2293 register_color (color->pixel);
2294 #endif /* DEBUG_X_COLORS */
2296 return rc;
2300 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
2301 exact match can't be allocated, try the nearest color available.
2302 Value is true if successful. Set *COLOR to the color
2303 allocated. */
2305 bool
2306 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2308 gamma_correct (f, color);
2309 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2313 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2314 It's necessary to do this instead of just using PIXEL directly to
2315 get color reference counts right. */
2317 unsigned long
2318 x_copy_color (struct frame *f, unsigned long pixel)
2320 XColor color;
2322 color.pixel = pixel;
2323 block_input ();
2324 x_query_color (f, &color);
2325 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2326 unblock_input ();
2327 #ifdef DEBUG_X_COLORS
2328 register_color (pixel);
2329 #endif
2330 return color.pixel;
2334 /* Brightness beyond which a color won't have its highlight brightness
2335 boosted.
2337 Nominally, highlight colors for `3d' faces are calculated by
2338 brightening an object's color by a constant scale factor, but this
2339 doesn't yield good results for dark colors, so for colors who's
2340 brightness is less than this value (on a scale of 0-65535) have an
2341 use an additional additive factor.
2343 The value here is set so that the default menu-bar/mode-line color
2344 (grey75) will not have its highlights changed at all. */
2345 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2348 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2349 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2350 If this produces the same color as PIXEL, try a color where all RGB
2351 values have DELTA added. Return the allocated color in *PIXEL.
2352 DISPLAY is the X display, CMAP is the colormap to operate on.
2353 Value is non-zero if successful. */
2355 static bool
2356 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2357 unsigned long *pixel, double factor, int delta)
2359 XColor color, new;
2360 long bright;
2361 bool success_p;
2363 /* Get RGB color values. */
2364 color.pixel = *pixel;
2365 x_query_color (f, &color);
2367 /* Change RGB values by specified FACTOR. Avoid overflow! */
2368 eassert (factor >= 0);
2369 new.red = min (0xffff, factor * color.red);
2370 new.green = min (0xffff, factor * color.green);
2371 new.blue = min (0xffff, factor * color.blue);
2373 /* Calculate brightness of COLOR. */
2374 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2376 /* We only boost colors that are darker than
2377 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2378 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2379 /* Make an additive adjustment to NEW, because it's dark enough so
2380 that scaling by FACTOR alone isn't enough. */
2382 /* How far below the limit this color is (0 - 1, 1 being darker). */
2383 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2384 /* The additive adjustment. */
2385 int min_delta = delta * dimness * factor / 2;
2387 if (factor < 1)
2389 new.red = max (0, new.red - min_delta);
2390 new.green = max (0, new.green - min_delta);
2391 new.blue = max (0, new.blue - min_delta);
2393 else
2395 new.red = min (0xffff, min_delta + new.red);
2396 new.green = min (0xffff, min_delta + new.green);
2397 new.blue = min (0xffff, min_delta + new.blue);
2401 /* Try to allocate the color. */
2402 success_p = x_alloc_nearest_color (f, cmap, &new);
2403 if (success_p)
2405 if (new.pixel == *pixel)
2407 /* If we end up with the same color as before, try adding
2408 delta to the RGB values. */
2409 x_free_colors (f, &new.pixel, 1);
2411 new.red = min (0xffff, delta + color.red);
2412 new.green = min (0xffff, delta + color.green);
2413 new.blue = min (0xffff, delta + color.blue);
2414 success_p = x_alloc_nearest_color (f, cmap, &new);
2416 else
2417 success_p = true;
2418 *pixel = new.pixel;
2421 return success_p;
2425 /* Set up the foreground color for drawing relief lines of glyph
2426 string S. RELIEF is a pointer to a struct relief containing the GC
2427 with which lines will be drawn. Use a color that is FACTOR or
2428 DELTA lighter or darker than the relief's background which is found
2429 in S->f->output_data.x->relief_background. If such a color cannot
2430 be allocated, use DEFAULT_PIXEL, instead. */
2432 static void
2433 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2434 int delta, unsigned long default_pixel)
2436 XGCValues xgcv;
2437 struct x_output *di = f->output_data.x;
2438 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2439 unsigned long pixel;
2440 unsigned long background = di->relief_background;
2441 Colormap cmap = FRAME_X_COLORMAP (f);
2442 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2443 Display *dpy = FRAME_X_DISPLAY (f);
2445 xgcv.graphics_exposures = False;
2446 xgcv.line_width = 1;
2448 /* Free previously allocated color. The color cell will be reused
2449 when it has been freed as many times as it was allocated, so this
2450 doesn't affect faces using the same colors. */
2451 if (relief->gc && relief->pixel != -1)
2453 x_free_colors (f, &relief->pixel, 1);
2454 relief->pixel = -1;
2457 /* Allocate new color. */
2458 xgcv.foreground = default_pixel;
2459 pixel = background;
2460 if (dpyinfo->n_planes != 1
2461 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2462 xgcv.foreground = relief->pixel = pixel;
2464 if (relief->gc == 0)
2466 xgcv.stipple = dpyinfo->gray;
2467 mask |= GCStipple;
2468 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
2470 else
2471 XChangeGC (dpy, relief->gc, mask, &xgcv);
2475 /* Set up colors for the relief lines around glyph string S. */
2477 static void
2478 x_setup_relief_colors (struct glyph_string *s)
2480 struct x_output *di = s->f->output_data.x;
2481 unsigned long color;
2483 if (s->face->use_box_color_for_shadows_p)
2484 color = s->face->box_color;
2485 else if (s->first_glyph->type == IMAGE_GLYPH
2486 && s->img->pixmap
2487 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2488 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2489 else
2491 XGCValues xgcv;
2493 /* Get the background color of the face. */
2494 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2495 color = xgcv.background;
2498 if (di->white_relief.gc == 0
2499 || color != di->relief_background)
2501 di->relief_background = color;
2502 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2503 WHITE_PIX_DEFAULT (s->f));
2504 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2505 BLACK_PIX_DEFAULT (s->f));
2510 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2511 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2512 to draw, it must be >= 0. RAISED_P means draw a raised
2513 relief. LEFT_P means draw a relief on the left side of
2514 the rectangle. RIGHT_P means draw a relief on the right
2515 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2516 when drawing. */
2518 static void
2519 x_draw_relief_rect (struct frame *f,
2520 int left_x, int top_y, int right_x, int bottom_y,
2521 int width, bool raised_p, bool top_p, bool bot_p,
2522 bool left_p, bool right_p,
2523 XRectangle *clip_rect)
2525 #ifdef USE_CAIRO
2526 GC top_left_gc, bottom_right_gc;
2527 int corners = 0;
2529 if (raised_p)
2531 top_left_gc = f->output_data.x->white_relief.gc;
2532 bottom_right_gc = f->output_data.x->black_relief.gc;
2534 else
2536 top_left_gc = f->output_data.x->black_relief.gc;
2537 bottom_right_gc = f->output_data.x->white_relief.gc;
2540 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2541 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2543 if (left_p)
2545 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2546 width, bottom_y + 1 - top_y);
2547 if (top_p)
2548 corners |= 1 << CORNER_TOP_LEFT;
2549 if (bot_p)
2550 corners |= 1 << CORNER_BOTTOM_LEFT;
2552 if (right_p)
2554 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2555 width, bottom_y + 1 - top_y);
2556 if (top_p)
2557 corners |= 1 << CORNER_TOP_RIGHT;
2558 if (bot_p)
2559 corners |= 1 << CORNER_BOTTOM_RIGHT;
2561 if (top_p)
2563 if (!right_p)
2564 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2565 right_x + 1 - left_x, width);
2566 else
2567 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2568 right_x + 1 - left_x, width, 1);
2570 if (bot_p)
2572 if (!left_p)
2573 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2574 right_x + 1 - left_x, width);
2575 else
2576 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2577 left_x, bottom_y + 1 - width,
2578 right_x + 1 - left_x, width, 0);
2580 if (left_p && width != 1)
2581 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2582 1, bottom_y + 1 - top_y);
2583 if (top_p && width != 1)
2584 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2585 right_x + 1 - left_x, 1);
2586 if (corners)
2588 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2589 FRAME_BACKGROUND_PIXEL (f));
2590 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2591 right_x - left_x + 1, bottom_y - top_y + 1,
2592 6, 1, corners);
2595 x_reset_clip_rectangles (f, top_left_gc);
2596 x_reset_clip_rectangles (f, bottom_right_gc);
2597 #else
2598 Display *dpy = FRAME_X_DISPLAY (f);
2599 Window window = FRAME_X_WINDOW (f);
2600 int i;
2601 GC gc;
2603 if (raised_p)
2604 gc = f->output_data.x->white_relief.gc;
2605 else
2606 gc = f->output_data.x->black_relief.gc;
2607 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2609 /* This code is more complicated than it has to be, because of two
2610 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2611 the outermost line using the black relief. (ii) Omit the four
2612 corner pixels. */
2614 /* Top. */
2615 if (top_p)
2617 if (width == 1)
2618 XDrawLine (dpy, window, gc,
2619 left_x + left_p, top_y,
2620 right_x + !right_p, top_y);
2622 for (i = 1; i < width; ++i)
2623 XDrawLine (dpy, window, gc,
2624 left_x + i * left_p, top_y + i,
2625 right_x + 1 - i * right_p, top_y + i);
2628 /* Left. */
2629 if (left_p)
2631 if (width == 1)
2632 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2634 XClearArea (dpy, window, left_x, top_y, 1, 1, False);
2635 XClearArea (dpy, window, left_x, bottom_y, 1, 1, False);
2637 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2638 XDrawLine (dpy, window, gc,
2639 left_x + i, top_y + (i + 1) * top_p,
2640 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2643 XSetClipMask (dpy, gc, None);
2644 if (raised_p)
2645 gc = f->output_data.x->black_relief.gc;
2646 else
2647 gc = f->output_data.x->white_relief.gc;
2648 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2650 if (width > 1)
2652 /* Outermost top line. */
2653 if (top_p)
2654 XDrawLine (dpy, window, gc,
2655 left_x + left_p, top_y,
2656 right_x + !right_p, top_y);
2658 /* Outermost left line. */
2659 if (left_p)
2660 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2663 /* Bottom. */
2664 if (bot_p)
2666 XDrawLine (dpy, window, gc,
2667 left_x + left_p, bottom_y,
2668 right_x + !right_p, bottom_y);
2669 for (i = 1; i < width; ++i)
2670 XDrawLine (dpy, window, gc,
2671 left_x + i * left_p, bottom_y - i,
2672 right_x + 1 - i * right_p, bottom_y - i);
2675 /* Right. */
2676 if (right_p)
2678 XClearArea (dpy, window, right_x, top_y, 1, 1, False);
2679 XClearArea (dpy, window, right_x, bottom_y, 1, 1, False);
2680 for (i = 0; i < width; ++i)
2681 XDrawLine (dpy, window, gc,
2682 right_x - i, top_y + (i + 1) * top_p,
2683 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2686 x_reset_clip_rectangles (f, gc);
2688 #endif
2692 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2693 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2694 draw, it must be >= 0. LEFT_P means draw a line on the
2695 left side of the rectangle. RIGHT_P means draw a line
2696 on the right side of the rectangle. CLIP_RECT is the clipping
2697 rectangle to use when drawing. */
2699 static void
2700 x_draw_box_rect (struct glyph_string *s,
2701 int left_x, int top_y, int right_x, int bottom_y, int width,
2702 bool left_p, bool right_p, XRectangle *clip_rect)
2704 XGCValues xgcv;
2706 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2707 XSetForeground (s->display, s->gc, s->face->box_color);
2708 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2710 /* Top. */
2711 x_fill_rectangle (s->f, s->gc,
2712 left_x, top_y, right_x - left_x + 1, width);
2714 /* Left. */
2715 if (left_p)
2716 x_fill_rectangle (s->f, s->gc,
2717 left_x, top_y, width, bottom_y - top_y + 1);
2719 /* Bottom. */
2720 x_fill_rectangle (s->f, s->gc,
2721 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2723 /* Right. */
2724 if (right_p)
2725 x_fill_rectangle (s->f, s->gc,
2726 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2728 XSetForeground (s->display, s->gc, xgcv.foreground);
2729 x_reset_clip_rectangles (s->f, s->gc);
2733 /* Draw a box around glyph string S. */
2735 static void
2736 x_draw_glyph_string_box (struct glyph_string *s)
2738 int width, left_x, right_x, top_y, bottom_y, last_x;
2739 bool raised_p, left_p, right_p;
2740 struct glyph *last_glyph;
2741 XRectangle clip_rect;
2743 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2744 ? WINDOW_RIGHT_EDGE_X (s->w)
2745 : window_box_right (s->w, s->area));
2747 /* The glyph that may have a right box line. */
2748 last_glyph = (s->cmp || s->img
2749 ? s->first_glyph
2750 : s->first_glyph + s->nchars - 1);
2752 width = eabs (s->face->box_line_width);
2753 raised_p = s->face->box == FACE_RAISED_BOX;
2754 left_x = s->x;
2755 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2756 ? last_x - 1
2757 : min (last_x, s->x + s->background_width) - 1);
2758 top_y = s->y;
2759 bottom_y = top_y + s->height - 1;
2761 left_p = (s->first_glyph->left_box_line_p
2762 || (s->hl == DRAW_MOUSE_FACE
2763 && (s->prev == NULL
2764 || s->prev->hl != s->hl)));
2765 right_p = (last_glyph->right_box_line_p
2766 || (s->hl == DRAW_MOUSE_FACE
2767 && (s->next == NULL
2768 || s->next->hl != s->hl)));
2770 get_glyph_string_clip_rect (s, &clip_rect);
2772 if (s->face->box == FACE_SIMPLE_BOX)
2773 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2774 left_p, right_p, &clip_rect);
2775 else
2777 x_setup_relief_colors (s);
2778 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2779 width, raised_p, true, true, left_p, right_p,
2780 &clip_rect);
2785 /* Draw foreground of image glyph string S. */
2787 static void
2788 x_draw_image_foreground (struct glyph_string *s)
2790 int x = s->x;
2791 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2793 /* If first glyph of S has a left box line, start drawing it to the
2794 right of that line. */
2795 if (s->face->box != FACE_NO_BOX
2796 && s->first_glyph->left_box_line_p
2797 && s->slice.x == 0)
2798 x += eabs (s->face->box_line_width);
2800 /* If there is a margin around the image, adjust x- and y-position
2801 by that margin. */
2802 if (s->slice.x == 0)
2803 x += s->img->hmargin;
2804 if (s->slice.y == 0)
2805 y += s->img->vmargin;
2807 if (s->img->pixmap)
2809 if (s->img->mask)
2811 /* We can't set both a clip mask and use XSetClipRectangles
2812 because the latter also sets a clip mask. We also can't
2813 trust on the shape extension to be available
2814 (XShapeCombineRegion). So, compute the rectangle to draw
2815 manually. */
2816 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2817 | GCFunction);
2818 XGCValues xgcv;
2819 XRectangle clip_rect, image_rect, r;
2821 xgcv.clip_mask = s->img->mask;
2822 xgcv.clip_x_origin = x;
2823 xgcv.clip_y_origin = y;
2824 xgcv.function = GXcopy;
2825 XChangeGC (s->display, s->gc, mask, &xgcv);
2827 get_glyph_string_clip_rect (s, &clip_rect);
2828 image_rect.x = x;
2829 image_rect.y = y;
2830 image_rect.width = s->slice.width;
2831 image_rect.height = s->slice.height;
2832 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2833 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2834 s->slice.x + r.x - x, s->slice.y + r.y - y,
2835 r.width, r.height, r.x, r.y);
2837 else
2839 XRectangle clip_rect, image_rect, r;
2841 get_glyph_string_clip_rect (s, &clip_rect);
2842 image_rect.x = x;
2843 image_rect.y = y;
2844 image_rect.width = s->slice.width;
2845 image_rect.height = s->slice.height;
2846 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2847 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2848 s->slice.x + r.x - x, s->slice.y + r.y - y,
2849 r.width, r.height, r.x, r.y);
2851 /* When the image has a mask, we can expect that at
2852 least part of a mouse highlight or a block cursor will
2853 be visible. If the image doesn't have a mask, make
2854 a block cursor visible by drawing a rectangle around
2855 the image. I believe it's looking better if we do
2856 nothing here for mouse-face. */
2857 if (s->hl == DRAW_CURSOR)
2859 int relief = eabs (s->img->relief);
2860 x_draw_rectangle (s->f, s->gc,
2861 x - relief, y - relief,
2862 s->slice.width + relief*2 - 1,
2863 s->slice.height + relief*2 - 1);
2867 else
2868 /* Draw a rectangle if image could not be loaded. */
2869 x_draw_rectangle (s->f, s->gc, x, y,
2870 s->slice.width - 1, s->slice.height - 1);
2874 /* Draw a relief around the image glyph string S. */
2876 static void
2877 x_draw_image_relief (struct glyph_string *s)
2879 int x1, y1, thick;
2880 bool raised_p, top_p, bot_p, left_p, right_p;
2881 int extra_x, extra_y;
2882 XRectangle r;
2883 int x = s->x;
2884 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2886 /* If first glyph of S has a left box line, start drawing it to the
2887 right of that line. */
2888 if (s->face->box != FACE_NO_BOX
2889 && s->first_glyph->left_box_line_p
2890 && s->slice.x == 0)
2891 x += eabs (s->face->box_line_width);
2893 /* If there is a margin around the image, adjust x- and y-position
2894 by that margin. */
2895 if (s->slice.x == 0)
2896 x += s->img->hmargin;
2897 if (s->slice.y == 0)
2898 y += s->img->vmargin;
2900 if (s->hl == DRAW_IMAGE_SUNKEN
2901 || s->hl == DRAW_IMAGE_RAISED)
2903 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
2904 raised_p = s->hl == DRAW_IMAGE_RAISED;
2906 else
2908 thick = eabs (s->img->relief);
2909 raised_p = s->img->relief > 0;
2912 x1 = x + s->slice.width - 1;
2913 y1 = y + s->slice.height - 1;
2915 extra_x = extra_y = 0;
2916 if (s->face->id == TOOL_BAR_FACE_ID)
2918 if (CONSP (Vtool_bar_button_margin)
2919 && INTEGERP (XCAR (Vtool_bar_button_margin))
2920 && INTEGERP (XCDR (Vtool_bar_button_margin)))
2922 extra_x = XINT (XCAR (Vtool_bar_button_margin));
2923 extra_y = XINT (XCDR (Vtool_bar_button_margin));
2925 else if (INTEGERP (Vtool_bar_button_margin))
2926 extra_x = extra_y = XINT (Vtool_bar_button_margin);
2929 top_p = bot_p = left_p = right_p = false;
2931 if (s->slice.x == 0)
2932 x -= thick + extra_x, left_p = true;
2933 if (s->slice.y == 0)
2934 y -= thick + extra_y, top_p = true;
2935 if (s->slice.x + s->slice.width == s->img->width)
2936 x1 += thick + extra_x, right_p = true;
2937 if (s->slice.y + s->slice.height == s->img->height)
2938 y1 += thick + extra_y, bot_p = true;
2940 x_setup_relief_colors (s);
2941 get_glyph_string_clip_rect (s, &r);
2942 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
2943 top_p, bot_p, left_p, right_p, &r);
2947 /* Draw the foreground of image glyph string S to PIXMAP. */
2949 static void
2950 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
2952 int x = 0;
2953 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2955 /* If first glyph of S has a left box line, start drawing it to the
2956 right of that line. */
2957 if (s->face->box != FACE_NO_BOX
2958 && s->first_glyph->left_box_line_p
2959 && s->slice.x == 0)
2960 x += eabs (s->face->box_line_width);
2962 /* If there is a margin around the image, adjust x- and y-position
2963 by that margin. */
2964 if (s->slice.x == 0)
2965 x += s->img->hmargin;
2966 if (s->slice.y == 0)
2967 y += s->img->vmargin;
2969 if (s->img->pixmap)
2971 if (s->img->mask)
2973 /* We can't set both a clip mask and use XSetClipRectangles
2974 because the latter also sets a clip mask. We also can't
2975 trust on the shape extension to be available
2976 (XShapeCombineRegion). So, compute the rectangle to draw
2977 manually. */
2978 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2979 | GCFunction);
2980 XGCValues xgcv;
2982 xgcv.clip_mask = s->img->mask;
2983 xgcv.clip_x_origin = x - s->slice.x;
2984 xgcv.clip_y_origin = y - s->slice.y;
2985 xgcv.function = GXcopy;
2986 XChangeGC (s->display, s->gc, mask, &xgcv);
2988 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2989 s->slice.x, s->slice.y,
2990 s->slice.width, s->slice.height, x, y);
2991 XSetClipMask (s->display, s->gc, None);
2993 else
2995 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2996 s->slice.x, s->slice.y,
2997 s->slice.width, s->slice.height, x, y);
2999 /* When the image has a mask, we can expect that at
3000 least part of a mouse highlight or a block cursor will
3001 be visible. If the image doesn't have a mask, make
3002 a block cursor visible by drawing a rectangle around
3003 the image. I believe it's looking better if we do
3004 nothing here for mouse-face. */
3005 if (s->hl == DRAW_CURSOR)
3007 int r = eabs (s->img->relief);
3008 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3009 s->slice.width + r*2 - 1,
3010 s->slice.height + r*2 - 1);
3014 else
3015 /* Draw a rectangle if image could not be loaded. */
3016 x_draw_rectangle (s->f, s->gc, x, y,
3017 s->slice.width - 1, s->slice.height - 1);
3021 /* Draw part of the background of glyph string S. X, Y, W, and H
3022 give the rectangle to draw. */
3024 static void
3025 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3027 if (s->stippled_p)
3029 /* Fill background with a stipple pattern. */
3030 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3031 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3032 XSetFillStyle (s->display, s->gc, FillSolid);
3034 else
3035 x_clear_glyph_string_rect (s, x, y, w, h);
3039 /* Draw image glyph string S.
3041 s->y
3042 s->x +-------------------------
3043 | s->face->box
3045 | +-------------------------
3046 | | s->img->margin
3047 | |
3048 | | +-------------------
3049 | | | the image
3051 */
3053 static void
3054 x_draw_image_glyph_string (struct glyph_string *s)
3056 int box_line_hwidth = eabs (s->face->box_line_width);
3057 int box_line_vwidth = max (s->face->box_line_width, 0);
3058 int height;
3059 Pixmap pixmap = None;
3061 height = s->height;
3062 if (s->slice.y == 0)
3063 height -= box_line_vwidth;
3064 if (s->slice.y + s->slice.height >= s->img->height)
3065 height -= box_line_vwidth;
3067 /* Fill background with face under the image. Do it only if row is
3068 taller than image or if image has a clip mask to reduce
3069 flickering. */
3070 s->stippled_p = s->face->stipple != 0;
3071 if (height > s->slice.height
3072 || s->img->hmargin
3073 || s->img->vmargin
3074 || s->img->mask
3075 || s->img->pixmap == 0
3076 || s->width != s->background_width)
3078 if (s->img->mask)
3080 /* Create a pixmap as large as the glyph string. Fill it
3081 with the background color. Copy the image to it, using
3082 its mask. Copy the temporary pixmap to the display. */
3083 Screen *screen = FRAME_X_SCREEN (s->f);
3084 int depth = DefaultDepthOfScreen (screen);
3086 /* Create a pixmap as large as the glyph string. */
3087 pixmap = XCreatePixmap (s->display, s->window,
3088 s->background_width,
3089 s->height, depth);
3091 /* Don't clip in the following because we're working on the
3092 pixmap. */
3093 XSetClipMask (s->display, s->gc, None);
3095 /* Fill the pixmap with the background color/stipple. */
3096 if (s->stippled_p)
3098 /* Fill background with a stipple pattern. */
3099 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3100 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3101 XFillRectangle (s->display, pixmap, s->gc,
3102 0, 0, s->background_width, s->height);
3103 XSetFillStyle (s->display, s->gc, FillSolid);
3104 XSetTSOrigin (s->display, s->gc, 0, 0);
3106 else
3108 XGCValues xgcv;
3109 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3110 &xgcv);
3111 XSetForeground (s->display, s->gc, xgcv.background);
3112 XFillRectangle (s->display, pixmap, s->gc,
3113 0, 0, s->background_width, s->height);
3114 XSetForeground (s->display, s->gc, xgcv.foreground);
3117 else
3119 int x = s->x;
3120 int y = s->y;
3121 int width = s->background_width;
3123 if (s->first_glyph->left_box_line_p
3124 && s->slice.x == 0)
3126 x += box_line_hwidth;
3127 width -= box_line_hwidth;
3130 if (s->slice.y == 0)
3131 y += box_line_vwidth;
3133 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3136 s->background_filled_p = true;
3139 /* Draw the foreground. */
3140 #ifdef USE_CAIRO
3141 if (s->img->cr_data)
3143 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3145 int x = s->x + s->img->hmargin;
3146 int y = s->y + s->img->vmargin;
3147 int width = s->background_width;
3149 cairo_set_source_surface (cr, s->img->cr_data,
3150 x - s->slice.x,
3151 y - s->slice.y);
3152 cairo_rectangle (cr, x, y, width, height);
3153 cairo_fill (cr);
3154 x_end_cr_clip (s->f);
3156 else
3157 #endif
3158 if (pixmap != None)
3160 x_draw_image_foreground_1 (s, pixmap);
3161 x_set_glyph_string_clipping (s);
3162 XCopyArea (s->display, pixmap, s->window, s->gc,
3163 0, 0, s->background_width, s->height, s->x, s->y);
3164 XFreePixmap (s->display, pixmap);
3166 else
3167 x_draw_image_foreground (s);
3169 /* If we must draw a relief around the image, do it. */
3170 if (s->img->relief
3171 || s->hl == DRAW_IMAGE_RAISED
3172 || s->hl == DRAW_IMAGE_SUNKEN)
3173 x_draw_image_relief (s);
3177 /* Draw stretch glyph string S. */
3179 static void
3180 x_draw_stretch_glyph_string (struct glyph_string *s)
3182 eassert (s->first_glyph->type == STRETCH_GLYPH);
3184 if (s->hl == DRAW_CURSOR
3185 && !x_stretch_cursor_p)
3187 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3188 wide as the stretch glyph. */
3189 int width, background_width = s->background_width;
3190 int x = s->x;
3192 if (!s->row->reversed_p)
3194 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3196 if (x < left_x)
3198 background_width -= left_x - x;
3199 x = left_x;
3202 else
3204 /* In R2L rows, draw the cursor on the right edge of the
3205 stretch glyph. */
3206 int right_x = window_box_right (s->w, TEXT_AREA);
3208 if (x + background_width > right_x)
3209 background_width -= x - right_x;
3210 x += background_width;
3212 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3213 if (s->row->reversed_p)
3214 x -= width;
3216 /* Draw cursor. */
3217 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3219 /* Clear rest using the GC of the original non-cursor face. */
3220 if (width < background_width)
3222 int y = s->y;
3223 int w = background_width - width, h = s->height;
3224 XRectangle r;
3225 GC gc;
3227 if (!s->row->reversed_p)
3228 x += width;
3229 else
3230 x = s->x;
3231 if (s->row->mouse_face_p
3232 && cursor_in_mouse_face_p (s->w))
3234 x_set_mouse_face_gc (s);
3235 gc = s->gc;
3237 else
3238 gc = s->face->gc;
3240 get_glyph_string_clip_rect (s, &r);
3241 x_set_clip_rectangles (s->f, gc, &r, 1);
3243 if (s->face->stipple)
3245 /* Fill background with a stipple pattern. */
3246 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3247 x_fill_rectangle (s->f, gc, x, y, w, h);
3248 XSetFillStyle (s->display, gc, FillSolid);
3250 else
3252 XGCValues xgcv;
3253 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3254 XSetForeground (s->display, gc, xgcv.background);
3255 x_fill_rectangle (s->f, gc, x, y, w, h);
3256 XSetForeground (s->display, gc, xgcv.foreground);
3259 x_reset_clip_rectangles (s->f, gc);
3262 else if (!s->background_filled_p)
3264 int background_width = s->background_width;
3265 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3267 /* Don't draw into left margin, fringe or scrollbar area
3268 except for header line and mode line. */
3269 if (x < left_x && !s->row->mode_line_p)
3271 background_width -= left_x - x;
3272 x = left_x;
3274 if (background_width > 0)
3275 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3278 s->background_filled_p = true;
3281 /*
3282 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3284 x0 wave_length = 2
3285 --
3286 y0 * * * * *
3287 |* * * * * * * * *
3288 wave_height = 3 | * * * *
3290 */
3292 static void
3293 x_draw_underwave (struct glyph_string *s)
3295 int wave_height = 3, wave_length = 2;
3296 #ifdef USE_CAIRO
3297 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3298 s->width, wave_height, wave_length);
3299 #else /* not USE_CAIRO */
3300 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3301 bool odd;
3302 XRectangle wave_clip, string_clip, final_clip;
3304 dx = wave_length;
3305 dy = wave_height - 1;
3306 x0 = s->x;
3307 y0 = s->ybase - wave_height + 3;
3308 width = s->width;
3309 xmax = x0 + width;
3311 /* Find and set clipping rectangle */
3313 wave_clip.x = x0;
3314 wave_clip.y = y0;
3315 wave_clip.width = width;
3316 wave_clip.height = wave_height;
3317 get_glyph_string_clip_rect (s, &string_clip);
3319 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3320 return;
3322 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3324 /* Draw the waves */
3326 x1 = x0 - (x0 % dx);
3327 x2 = x1 + dx;
3328 odd = (x1 / dx) & 1;
3329 y1 = y2 = y0;
3331 if (odd)
3332 y1 += dy;
3333 else
3334 y2 += dy;
3336 if (INT_MAX - dx < xmax)
3337 emacs_abort ();
3339 while (x1 <= xmax)
3341 XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
3342 x1 = x2, y1 = y2;
3343 x2 += dx, y2 = y0 + odd*dy;
3344 odd = !odd;
3347 /* Restore previous clipping rectangle(s) */
3348 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3349 #endif /* not USE_CAIRO */
3353 /* Draw glyph string S. */
3355 static void
3356 x_draw_glyph_string (struct glyph_string *s)
3358 bool relief_drawn_p = false;
3360 /* If S draws into the background of its successors, draw the
3361 background of the successors first so that S can draw into it.
3362 This makes S->next use XDrawString instead of XDrawImageString. */
3363 if (s->next && s->right_overhang && !s->for_overlaps)
3365 int width;
3366 struct glyph_string *next;
3368 for (width = 0, next = s->next;
3369 next && width < s->right_overhang;
3370 width += next->width, next = next->next)
3371 if (next->first_glyph->type != IMAGE_GLYPH)
3373 x_set_glyph_string_gc (next);
3374 x_set_glyph_string_clipping (next);
3375 if (next->first_glyph->type == STRETCH_GLYPH)
3376 x_draw_stretch_glyph_string (next);
3377 else
3378 x_draw_glyph_string_background (next, true);
3379 next->num_clips = 0;
3383 /* Set up S->gc, set clipping and draw S. */
3384 x_set_glyph_string_gc (s);
3386 /* Draw relief (if any) in advance for char/composition so that the
3387 glyph string can be drawn over it. */
3388 if (!s->for_overlaps
3389 && s->face->box != FACE_NO_BOX
3390 && (s->first_glyph->type == CHAR_GLYPH
3391 || s->first_glyph->type == COMPOSITE_GLYPH))
3394 x_set_glyph_string_clipping (s);
3395 x_draw_glyph_string_background (s, true);
3396 x_draw_glyph_string_box (s);
3397 x_set_glyph_string_clipping (s);
3398 relief_drawn_p = true;
3400 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3401 && !s->clip_tail
3402 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3403 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3404 /* We must clip just this glyph. left_overhang part has already
3405 drawn when s->prev was drawn, and right_overhang part will be
3406 drawn later when s->next is drawn. */
3407 x_set_glyph_string_clipping_exactly (s, s);
3408 else
3409 x_set_glyph_string_clipping (s);
3411 switch (s->first_glyph->type)
3413 case IMAGE_GLYPH:
3414 x_draw_image_glyph_string (s);
3415 break;
3417 case STRETCH_GLYPH:
3418 x_draw_stretch_glyph_string (s);
3419 break;
3421 case CHAR_GLYPH:
3422 if (s->for_overlaps)
3423 s->background_filled_p = true;
3424 else
3425 x_draw_glyph_string_background (s, false);
3426 x_draw_glyph_string_foreground (s);
3427 break;
3429 case COMPOSITE_GLYPH:
3430 if (s->for_overlaps || (s->cmp_from > 0
3431 && ! s->first_glyph->u.cmp.automatic))
3432 s->background_filled_p = true;
3433 else
3434 x_draw_glyph_string_background (s, true);
3435 x_draw_composite_glyph_string_foreground (s);
3436 break;
3438 case GLYPHLESS_GLYPH:
3439 if (s->for_overlaps)
3440 s->background_filled_p = true;
3441 else
3442 x_draw_glyph_string_background (s, true);
3443 x_draw_glyphless_glyph_string_foreground (s);
3444 break;
3446 default:
3447 emacs_abort ();
3450 if (!s->for_overlaps)
3452 /* Draw underline. */
3453 if (s->face->underline_p)
3455 if (s->face->underline_type == FACE_UNDER_WAVE)
3457 if (s->face->underline_defaulted_p)
3458 x_draw_underwave (s);
3459 else
3461 XGCValues xgcv;
3462 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3463 XSetForeground (s->display, s->gc, s->face->underline_color);
3464 x_draw_underwave (s);
3465 XSetForeground (s->display, s->gc, xgcv.foreground);
3468 else if (s->face->underline_type == FACE_UNDER_LINE)
3470 unsigned long thickness, position;
3471 int y;
3473 if (s->prev && s->prev->face->underline_p
3474 && s->prev->face->underline_type == FACE_UNDER_LINE)
3476 /* We use the same underline style as the previous one. */
3477 thickness = s->prev->underline_thickness;
3478 position = s->prev->underline_position;
3480 else
3482 /* Get the underline thickness. Default is 1 pixel. */
3483 if (s->font && s->font->underline_thickness > 0)
3484 thickness = s->font->underline_thickness;
3485 else
3486 thickness = 1;
3487 if (x_underline_at_descent_line)
3488 position = (s->height - thickness) - (s->ybase - s->y);
3489 else
3491 /* Get the underline position. This is the recommended
3492 vertical offset in pixels from the baseline to the top of
3493 the underline. This is a signed value according to the
3494 specs, and its default is
3496 ROUND ((maximum descent) / 2), with
3497 ROUND(x) = floor (x + 0.5) */
3499 if (x_use_underline_position_properties
3500 && s->font && s->font->underline_position >= 0)
3501 position = s->font->underline_position;
3502 else if (s->font)
3503 position = (s->font->descent + 1) / 2;
3504 else
3505 position = underline_minimum_offset;
3507 position = max (position, underline_minimum_offset);
3509 /* Check the sanity of thickness and position. We should
3510 avoid drawing underline out of the current line area. */
3511 if (s->y + s->height <= s->ybase + position)
3512 position = (s->height - 1) - (s->ybase - s->y);
3513 if (s->y + s->height < s->ybase + position + thickness)
3514 thickness = (s->y + s->height) - (s->ybase + position);
3515 s->underline_thickness = thickness;
3516 s->underline_position = position;
3517 y = s->ybase + position;
3518 if (s->face->underline_defaulted_p)
3519 x_fill_rectangle (s->f, s->gc,
3520 s->x, y, s->width, thickness);
3521 else
3523 XGCValues xgcv;
3524 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3525 XSetForeground (s->display, s->gc, s->face->underline_color);
3526 x_fill_rectangle (s->f, s->gc,
3527 s->x, y, s->width, thickness);
3528 XSetForeground (s->display, s->gc, xgcv.foreground);
3532 /* Draw overline. */
3533 if (s->face->overline_p)
3535 unsigned long dy = 0, h = 1;
3537 if (s->face->overline_color_defaulted_p)
3538 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3539 s->width, h);
3540 else
3542 XGCValues xgcv;
3543 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3544 XSetForeground (s->display, s->gc, s->face->overline_color);
3545 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3546 s->width, h);
3547 XSetForeground (s->display, s->gc, xgcv.foreground);
3551 /* Draw strike-through. */
3552 if (s->face->strike_through_p)
3554 unsigned long h = 1;
3555 unsigned long dy = (s->height - h) / 2;
3557 if (s->face->strike_through_color_defaulted_p)
3558 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3559 s->width, h);
3560 else
3562 XGCValues xgcv;
3563 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3564 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3565 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3566 s->width, h);
3567 XSetForeground (s->display, s->gc, xgcv.foreground);
3571 /* Draw relief if not yet drawn. */
3572 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3573 x_draw_glyph_string_box (s);
3575 if (s->prev)
3577 struct glyph_string *prev;
3579 for (prev = s->prev; prev; prev = prev->prev)
3580 if (prev->hl != s->hl
3581 && prev->x + prev->width + prev->right_overhang > s->x)
3583 /* As prev was drawn while clipped to its own area, we
3584 must draw the right_overhang part using s->hl now. */
3585 enum draw_glyphs_face save = prev->hl;
3587 prev->hl = s->hl;
3588 x_set_glyph_string_gc (prev);
3589 x_set_glyph_string_clipping_exactly (s, prev);
3590 if (prev->first_glyph->type == CHAR_GLYPH)
3591 x_draw_glyph_string_foreground (prev);
3592 else
3593 x_draw_composite_glyph_string_foreground (prev);
3594 x_reset_clip_rectangles (prev->f, prev->gc);
3595 prev->hl = save;
3596 prev->num_clips = 0;
3600 if (s->next)
3602 struct glyph_string *next;
3604 for (next = s->next; next; next = next->next)
3605 if (next->hl != s->hl
3606 && next->x - next->left_overhang < s->x + s->width)
3608 /* As next will be drawn while clipped to its own area,
3609 we must draw the left_overhang part using s->hl now. */
3610 enum draw_glyphs_face save = next->hl;
3612 next->hl = s->hl;
3613 x_set_glyph_string_gc (next);
3614 x_set_glyph_string_clipping_exactly (s, next);
3615 if (next->first_glyph->type == CHAR_GLYPH)
3616 x_draw_glyph_string_foreground (next);
3617 else
3618 x_draw_composite_glyph_string_foreground (next);
3619 x_reset_clip_rectangles (next->f, next->gc);
3620 next->hl = save;
3621 next->num_clips = 0;
3622 next->clip_head = s->next;
3627 /* Reset clipping. */
3628 x_reset_clip_rectangles (s->f, s->gc);
3629 s->num_clips = 0;
3632 /* Shift display to make room for inserted glyphs. */
3634 static void
3635 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3637 /* Never called on a GUI frame, see
3638 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3639 */
3640 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
3641 f->output_data.x->normal_gc,
3642 x, y, width, height,
3643 x + shift_by, y);
3646 /* Delete N glyphs at the nominal cursor position. Not implemented
3647 for X frames. */
3649 static void
3650 x_delete_glyphs (struct frame *f, register int n)
3652 emacs_abort ();
3656 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3657 If they are <= 0, this is probably an error. */
3659 static void
3660 x_clear_area1 (Display *dpy, Window window,
3661 int x, int y, int width, int height, int exposures)
3663 eassert (width > 0 && height > 0);
3664 XClearArea (dpy, window, x, y, width, height, exposures);
3668 void
3669 x_clear_area (struct frame *f, int x, int y, int width, int height)
3671 #ifdef USE_CAIRO
3672 cairo_t *cr;
3674 eassert (width > 0 && height > 0);
3676 cr = x_begin_cr_clip (f, NULL);
3677 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3678 cairo_rectangle (cr, x, y, width, height);
3679 cairo_fill (cr);
3680 x_end_cr_clip (f);
3681 #else
3682 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3683 x, y, width, height, False);
3684 #endif
3688 /* Clear an entire frame. */
3690 static void
3691 x_clear_frame (struct frame *f)
3693 /* Clearing the frame will erase any cursor, so mark them all as no
3694 longer visible. */
3695 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3697 block_input ();
3699 x_clear_window (f);
3701 /* We have to clear the scroll bars. If we have changed colors or
3702 something like that, then they should be notified. */
3703 x_scroll_bar_clear (f);
3705 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3706 /* Make sure scroll bars are redrawn. As they aren't redrawn by
3707 redisplay, do it here. */
3708 if (FRAME_GTK_WIDGET (f))
3709 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
3710 #endif
3712 XFlush (FRAME_X_DISPLAY (f));
3714 unblock_input ();
3717 /* RIF: Show hourglass cursor on frame F. */
3719 static void
3720 x_show_hourglass (struct frame *f)
3722 Display *dpy = FRAME_X_DISPLAY (f);
3724 if (dpy)
3726 struct x_output *x = FRAME_X_OUTPUT (f);
3727 #ifdef USE_X_TOOLKIT
3728 if (x->widget)
3729 #else
3730 if (FRAME_OUTER_WINDOW (f))
3731 #endif
3733 x->hourglass_p = true;
3735 if (!x->hourglass_window)
3737 unsigned long mask = CWCursor;
3738 XSetWindowAttributes attrs;
3739 #ifdef USE_GTK
3740 Window parent = FRAME_X_WINDOW (f);
3741 #else
3742 Window parent = FRAME_OUTER_WINDOW (f);
3743 #endif
3744 attrs.cursor = x->hourglass_cursor;
3746 x->hourglass_window = XCreateWindow
3747 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3748 InputOnly, CopyFromParent, mask, &attrs);
3751 XMapRaised (dpy, x->hourglass_window);
3752 XFlush (dpy);
3757 /* RIF: Cancel hourglass cursor on frame F. */
3759 static void
3760 x_hide_hourglass (struct frame *f)
3762 struct x_output *x = FRAME_X_OUTPUT (f);
3764 /* Watch out for newly created frames. */
3765 if (x->hourglass_window)
3767 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3768 /* Sync here because XTread_socket looks at the
3769 hourglass_p flag that is reset to zero below. */
3770 XSync (FRAME_X_DISPLAY (f), False);
3771 x->hourglass_p = false;
3775 /* Invert the middle quarter of the frame for .15 sec. */
3777 static void
3778 XTflash (struct frame *f)
3780 block_input ();
3783 #ifdef USE_GTK
3784 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3785 when the scroll bars and the edit widget share the same X window. */
3786 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3787 #ifdef HAVE_GTK3
3788 cairo_t *cr = gdk_cairo_create (window);
3789 cairo_set_source_rgb (cr, 1, 1, 1);
3790 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
3791 #define XFillRectangle(d, win, gc, x, y, w, h) \
3792 do { \
3793 cairo_rectangle (cr, x, y, w, h); \
3794 cairo_fill (cr); \
3795 } \
3796 while (false)
3797 #else /* ! HAVE_GTK3 */
3798 GdkGCValues vals;
3799 GdkGC *gc;
3800 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
3801 ^ FRAME_BACKGROUND_PIXEL (f));
3802 vals.function = GDK_XOR;
3803 gc = gdk_gc_new_with_values (window,
3804 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
3805 #define XFillRectangle(d, win, gc, x, y, w, h) \
3806 gdk_draw_rectangle (window, gc, true, x, y, w, h)
3807 #endif /* ! HAVE_GTK3 */
3808 #else /* ! USE_GTK */
3809 GC gc;
3811 /* Create a GC that will use the GXxor function to flip foreground
3812 pixels into background pixels. */
3814 XGCValues values;
3816 values.function = GXxor;
3817 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
3818 ^ FRAME_BACKGROUND_PIXEL (f));
3820 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3821 GCFunction | GCForeground, &values);
3823 #endif
3825 /* Get the height not including a menu bar widget. */
3826 int height = FRAME_PIXEL_HEIGHT (f);
3827 /* Height of each line to flash. */
3828 int flash_height = FRAME_LINE_HEIGHT (f);
3829 /* These will be the left and right margins of the rectangles. */
3830 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3831 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3832 int width = flash_right - flash_left;
3834 /* If window is tall, flash top and bottom line. */
3835 if (height > 3 * FRAME_LINE_HEIGHT (f))
3837 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3838 flash_left,
3839 (FRAME_INTERNAL_BORDER_WIDTH (f)
3840 + FRAME_TOP_MARGIN_HEIGHT (f)),
3841 width, flash_height);
3842 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3843 flash_left,
3844 (height - flash_height
3845 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3846 width, flash_height);
3849 else
3850 /* If it is short, flash it all. */
3851 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3852 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3853 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3855 x_flush (f);
3858 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
3859 struct timespec wakeup = timespec_add (current_timespec (), delay);
3861 /* Keep waiting until past the time wakeup or any input gets
3862 available. */
3863 while (! detect_input_pending ())
3865 struct timespec current = current_timespec ();
3866 struct timespec timeout;
3868 /* Break if result would not be positive. */
3869 if (timespec_cmp (wakeup, current) <= 0)
3870 break;
3872 /* How long `select' should wait. */
3873 timeout = make_timespec (0, 10 * 1000 * 1000);
3875 /* Try to wait that long--but we might wake up sooner. */
3876 pselect (0, NULL, NULL, NULL, &timeout, NULL);
3880 /* If window is tall, flash top and bottom line. */
3881 if (height > 3 * FRAME_LINE_HEIGHT (f))
3883 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3884 flash_left,
3885 (FRAME_INTERNAL_BORDER_WIDTH (f)
3886 + FRAME_TOP_MARGIN_HEIGHT (f)),
3887 width, flash_height);
3888 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3889 flash_left,
3890 (height - flash_height
3891 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3892 width, flash_height);
3894 else
3895 /* If it is short, flash it all. */
3896 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3897 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3898 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3900 #ifdef USE_GTK
3901 #ifdef HAVE_GTK3
3902 cairo_destroy (cr);
3903 #else
3904 g_object_unref (G_OBJECT (gc));
3905 #endif
3906 #undef XFillRectangle
3907 #else
3908 XFreeGC (FRAME_X_DISPLAY (f), gc);
3909 #endif
3910 x_flush (f);
3914 unblock_input ();
3918 static void
3919 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
3921 block_input ();
3922 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
3923 unblock_input ();
3927 /* Make audible bell. */
3929 static void
3930 XTring_bell (struct frame *f)
3932 if (FRAME_X_DISPLAY (f))
3934 if (visible_bell)
3935 XTflash (f);
3936 else
3938 block_input ();
3939 #ifdef HAVE_XKB
3940 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
3941 #else
3942 XBell (FRAME_X_DISPLAY (f), 0);
3943 #endif
3944 XFlush (FRAME_X_DISPLAY (f));
3945 unblock_input ();
3950 /***********************************************************************
3951 Line Dance
3952 ***********************************************************************/
3954 /* Perform an insert-lines or delete-lines operation, inserting N
3955 lines or deleting -N lines at vertical position VPOS. */
3957 static void
3958 x_ins_del_lines (struct frame *f, int vpos, int n)
3960 emacs_abort ();
3964 /* Scroll part of the display as described by RUN. */
3966 static void
3967 x_scroll_run (struct window *w, struct run *run)
3969 struct frame *f = XFRAME (w->frame);
3970 int x, y, width, height, from_y, to_y, bottom_y;
3972 /* Get frame-relative bounding box of the text display area of W,
3973 without mode lines. Include in this box the left and right
3974 fringe of W. */
3975 window_box (w, ANY_AREA, &x, &y, &width, &height);
3977 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
3978 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
3979 bottom_y = y + height;
3981 if (to_y < from_y)
3983 /* Scrolling up. Make sure we don't copy part of the mode
3984 line at the bottom. */
3985 if (from_y + run->height > bottom_y)
3986 height = bottom_y - from_y;
3987 else
3988 height = run->height;
3990 else
3992 /* Scrolling down. Make sure we don't copy over the mode line.
3993 at the bottom. */
3994 if (to_y + run->height > bottom_y)
3995 height = bottom_y - to_y;
3996 else
3997 height = run->height;
4000 block_input ();
4002 /* Cursor off. Will be switched on again in x_update_window_end. */
4003 x_clear_cursor (w);
4005 #ifdef USE_CAIRO
4006 SET_FRAME_GARBAGED (f);
4007 #else
4008 XCopyArea (FRAME_X_DISPLAY (f),
4009 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
4010 f->output_data.x->normal_gc,
4011 x, from_y,
4012 width, height,
4013 x, to_y);
4014 #endif
4016 unblock_input ();
4020 \f
4021 /***********************************************************************
4022 Exposure Events
4023 ***********************************************************************/
4025 \f
4026 static void
4027 frame_highlight (struct frame *f)
4029 /* We used to only do this if Vx_no_window_manager was non-nil, but
4030 the ICCCM (section 4.1.6) says that the window's border pixmap
4031 and border pixel are window attributes which are "private to the
4032 client", so we can always change it to whatever we want. */
4033 block_input ();
4034 /* I recently started to get errors in this XSetWindowBorder, depending on
4035 the window-manager in use, tho something more is at play since I've been
4036 using that same window-manager binary for ever. Let's not crash just
4037 because of this (bug#9310). */
4038 x_catch_errors (FRAME_X_DISPLAY (f));
4039 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4040 f->output_data.x->border_pixel);
4041 x_uncatch_errors ();
4042 unblock_input ();
4043 x_update_cursor (f, true);
4044 x_set_frame_alpha (f);
4047 static void
4048 frame_unhighlight (struct frame *f)
4050 /* We used to only do this if Vx_no_window_manager was non-nil, but
4051 the ICCCM (section 4.1.6) says that the window's border pixmap
4052 and border pixel are window attributes which are "private to the
4053 client", so we can always change it to whatever we want. */
4054 block_input ();
4055 /* Same as above for XSetWindowBorder (bug#9310). */
4056 x_catch_errors (FRAME_X_DISPLAY (f));
4057 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4058 f->output_data.x->border_tile);
4059 x_uncatch_errors ();
4060 unblock_input ();
4061 x_update_cursor (f, true);
4062 x_set_frame_alpha (f);
4065 /* The focus has changed. Update the frames as necessary to reflect
4066 the new situation. Note that we can't change the selected frame
4067 here, because the Lisp code we are interrupting might become confused.
4068 Each event gets marked with the frame in which it occurred, so the
4069 Lisp code can tell when the switch took place by examining the events. */
4071 static void
4072 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4074 struct frame *old_focus = dpyinfo->x_focus_frame;
4076 if (frame != dpyinfo->x_focus_frame)
4078 /* Set this before calling other routines, so that they see
4079 the correct value of x_focus_frame. */
4080 dpyinfo->x_focus_frame = frame;
4082 if (old_focus && old_focus->auto_lower)
4083 x_lower_frame (old_focus);
4085 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4086 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4087 else
4088 dpyinfo->x_pending_autoraise_frame = NULL;
4091 x_frame_rehighlight (dpyinfo);
4094 /* Handle FocusIn and FocusOut state changes for FRAME.
4095 If FRAME has focus and there exists more than one frame, puts
4096 a FOCUS_IN_EVENT into *BUFP. */
4098 static void
4099 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4101 if (type == FocusIn)
4103 if (dpyinfo->x_focus_event_frame != frame)
4105 x_new_focus_frame (dpyinfo, frame);
4106 dpyinfo->x_focus_event_frame = frame;
4108 /* Don't stop displaying the initial startup message
4109 for a switch-frame event we don't need. */
4110 /* When run as a daemon, Vterminal_frame is always NIL. */
4111 bufp->arg = (((NILP (Vterminal_frame)
4112 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4113 || EQ (Fdaemonp (), Qt))
4114 && CONSP (Vframe_list)
4115 && !NILP (XCDR (Vframe_list)))
4116 ? Qt : Qnil);
4117 bufp->kind = FOCUS_IN_EVENT;
4118 XSETFRAME (bufp->frame_or_window, frame);
4121 frame->output_data.x->focus_state |= state;
4123 #ifdef HAVE_X_I18N
4124 if (FRAME_XIC (frame))
4125 XSetICFocus (FRAME_XIC (frame));
4126 #endif
4128 else if (type == FocusOut)
4130 frame->output_data.x->focus_state &= ~state;
4132 if (dpyinfo->x_focus_event_frame == frame)
4134 dpyinfo->x_focus_event_frame = 0;
4135 x_new_focus_frame (dpyinfo, 0);
4137 bufp->kind = FOCUS_OUT_EVENT;
4138 XSETFRAME (bufp->frame_or_window, frame);
4141 #ifdef HAVE_X_I18N
4142 if (FRAME_XIC (frame))
4143 XUnsetICFocus (FRAME_XIC (frame));
4144 #endif
4145 if (frame->pointer_invisible)
4146 XTtoggle_invisible_pointer (frame, false);
4150 /* Return the Emacs frame-object corresponding to an X window.
4151 It could be the frame's main window or an icon window. */
4153 static struct frame *
4154 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4156 Lisp_Object tail, frame;
4157 struct frame *f;
4159 if (wdesc == None)
4160 return NULL;
4162 FOR_EACH_FRAME (tail, frame)
4164 f = XFRAME (frame);
4165 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4166 continue;
4167 if (f->output_data.x->hourglass_window == wdesc)
4168 return f;
4169 #ifdef USE_X_TOOLKIT
4170 if ((f->output_data.x->edit_widget
4171 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4172 /* A tooltip frame? */
4173 || (!f->output_data.x->edit_widget
4174 && FRAME_X_WINDOW (f) == wdesc)
4175 || f->output_data.x->icon_desc == wdesc)
4176 return f;
4177 #else /* not USE_X_TOOLKIT */
4178 #ifdef USE_GTK
4179 if (f->output_data.x->edit_widget)
4181 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4182 struct x_output *x = f->output_data.x;
4183 if (gwdesc != 0 && gwdesc == x->edit_widget)
4184 return f;
4186 #endif /* USE_GTK */
4187 if (FRAME_X_WINDOW (f) == wdesc
4188 || f->output_data.x->icon_desc == wdesc)
4189 return f;
4190 #endif /* not USE_X_TOOLKIT */
4192 return 0;
4195 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4197 /* Like x_window_to_frame but also compares the window with the widget's
4198 windows. */
4200 static struct frame *
4201 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4203 Lisp_Object tail, frame;
4204 struct frame *f, *found = NULL;
4205 struct x_output *x;
4207 if (wdesc == None)
4208 return NULL;
4210 FOR_EACH_FRAME (tail, frame)
4212 if (found)
4213 break;
4214 f = XFRAME (frame);
4215 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4217 /* This frame matches if the window is any of its widgets. */
4218 x = f->output_data.x;
4219 if (x->hourglass_window == wdesc)
4220 found = f;
4221 else if (x->widget)
4223 #ifdef USE_GTK
4224 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4225 if (gwdesc != 0
4226 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4227 found = f;
4228 #else
4229 if (wdesc == XtWindow (x->widget)
4230 || wdesc == XtWindow (x->column_widget)
4231 || wdesc == XtWindow (x->edit_widget))
4232 found = f;
4233 /* Match if the window is this frame's menubar. */
4234 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4235 found = f;
4236 #endif
4238 else if (FRAME_X_WINDOW (f) == wdesc)
4239 /* A tooltip frame. */
4240 found = f;
4244 return found;
4247 /* Likewise, but consider only the menu bar widget. */
4249 static struct frame *
4250 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4251 const XEvent *event)
4253 Window wdesc = event->xany.window;
4254 Lisp_Object tail, frame;
4255 struct frame *f;
4256 struct x_output *x;
4258 if (wdesc == None)
4259 return NULL;
4261 FOR_EACH_FRAME (tail, frame)
4263 f = XFRAME (frame);
4264 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4265 continue;
4266 x = f->output_data.x;
4267 #ifdef USE_GTK
4268 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4269 return f;
4270 #else
4271 /* Match if the window is this frame's menubar. */
4272 if (x->menubar_widget
4273 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4274 return f;
4275 #endif
4277 return 0;
4280 /* Return the frame whose principal (outermost) window is WDESC.
4281 If WDESC is some other (smaller) window, we return 0. */
4283 struct frame *
4284 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4286 Lisp_Object tail, frame;
4287 struct frame *f;
4288 struct x_output *x;
4290 if (wdesc == None)
4291 return NULL;
4293 FOR_EACH_FRAME (tail, frame)
4295 f = XFRAME (frame);
4296 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4297 continue;
4298 x = f->output_data.x;
4300 if (x->widget)
4302 /* This frame matches if the window is its topmost widget. */
4303 #ifdef USE_GTK
4304 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4305 if (gwdesc == x->widget)
4306 return f;
4307 #else
4308 if (wdesc == XtWindow (x->widget))
4309 return f;
4310 #endif
4312 else if (FRAME_X_WINDOW (f) == wdesc)
4313 /* Tooltip frame. */
4314 return f;
4316 return 0;
4319 #else /* !USE_X_TOOLKIT && !USE_GTK */
4321 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4322 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4324 #endif /* USE_X_TOOLKIT || USE_GTK */
4326 /* The focus may have changed. Figure out if it is a real focus change,
4327 by checking both FocusIn/Out and Enter/LeaveNotify events.
4329 Returns FOCUS_IN_EVENT event in *BUFP. */
4331 static void
4332 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4333 const XEvent *event, struct input_event *bufp)
4335 if (!frame)
4336 return;
4338 switch (event->type)
4340 case EnterNotify:
4341 case LeaveNotify:
4343 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4344 int focus_state
4345 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4347 if (event->xcrossing.detail != NotifyInferior
4348 && event->xcrossing.focus
4349 && ! (focus_state & FOCUS_EXPLICIT))
4350 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4351 FOCUS_IMPLICIT,
4352 dpyinfo, frame, bufp);
4354 break;
4356 case FocusIn:
4357 case FocusOut:
4358 x_focus_changed (event->type,
4359 (event->xfocus.detail == NotifyPointer ?
4360 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4361 dpyinfo, frame, bufp);
4362 break;
4364 case ClientMessage:
4365 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4367 enum xembed_message msg = event->xclient.data.l[1];
4368 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4369 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4371 break;
4376 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4377 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4379 void
4380 x_mouse_leave (struct x_display_info *dpyinfo)
4382 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4384 #endif
4386 /* The focus has changed, or we have redirected a frame's focus to
4387 another frame (this happens when a frame uses a surrogate
4388 mini-buffer frame). Shift the highlight as appropriate.
4390 The FRAME argument doesn't necessarily have anything to do with which
4391 frame is being highlighted or un-highlighted; we only use it to find
4392 the appropriate X display info. */
4394 static void
4395 XTframe_rehighlight (struct frame *frame)
4397 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4400 static void
4401 x_frame_rehighlight (struct x_display_info *dpyinfo)
4403 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4405 if (dpyinfo->x_focus_frame)
4407 dpyinfo->x_highlight_frame
4408 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4409 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4410 : dpyinfo->x_focus_frame);
4411 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4413 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4414 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4417 else
4418 dpyinfo->x_highlight_frame = 0;
4420 if (dpyinfo->x_highlight_frame != old_highlight)
4422 if (old_highlight)
4423 frame_unhighlight (old_highlight);
4424 if (dpyinfo->x_highlight_frame)
4425 frame_highlight (dpyinfo->x_highlight_frame);
4430 \f
4431 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4433 /* Initialize mode_switch_bit and modifier_meaning. */
4434 static void
4435 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4437 int min_code, max_code;
4438 KeySym *syms;
4439 int syms_per_code;
4440 XModifierKeymap *mods;
4442 dpyinfo->meta_mod_mask = 0;
4443 dpyinfo->shift_lock_mask = 0;
4444 dpyinfo->alt_mod_mask = 0;
4445 dpyinfo->super_mod_mask = 0;
4446 dpyinfo->hyper_mod_mask = 0;
4448 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4450 syms = XGetKeyboardMapping (dpyinfo->display,
4451 min_code, max_code - min_code + 1,
4452 &syms_per_code);
4453 mods = XGetModifierMapping (dpyinfo->display);
4455 /* Scan the modifier table to see which modifier bits the Meta and
4456 Alt keysyms are on. */
4458 int row, col; /* The row and column in the modifier table. */
4459 bool found_alt_or_meta;
4461 for (row = 3; row < 8; row++)
4463 found_alt_or_meta = false;
4464 for (col = 0; col < mods->max_keypermod; col++)
4466 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4468 /* Zeroes are used for filler. Skip them. */
4469 if (code == 0)
4470 continue;
4472 /* Are any of this keycode's keysyms a meta key? */
4474 int code_col;
4476 for (code_col = 0; code_col < syms_per_code; code_col++)
4478 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4480 switch (sym)
4482 case XK_Meta_L:
4483 case XK_Meta_R:
4484 found_alt_or_meta = true;
4485 dpyinfo->meta_mod_mask |= (1 << row);
4486 break;
4488 case XK_Alt_L:
4489 case XK_Alt_R:
4490 found_alt_or_meta = true;
4491 dpyinfo->alt_mod_mask |= (1 << row);
4492 break;
4494 case XK_Hyper_L:
4495 case XK_Hyper_R:
4496 if (!found_alt_or_meta)
4497 dpyinfo->hyper_mod_mask |= (1 << row);
4498 code_col = syms_per_code;
4499 col = mods->max_keypermod;
4500 break;
4502 case XK_Super_L:
4503 case XK_Super_R:
4504 if (!found_alt_or_meta)
4505 dpyinfo->super_mod_mask |= (1 << row);
4506 code_col = syms_per_code;
4507 col = mods->max_keypermod;
4508 break;
4510 case XK_Shift_Lock:
4511 /* Ignore this if it's not on the lock modifier. */
4512 if (!found_alt_or_meta && ((1 << row) == LockMask))
4513 dpyinfo->shift_lock_mask = LockMask;
4514 code_col = syms_per_code;
4515 col = mods->max_keypermod;
4516 break;
4524 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4525 if (! dpyinfo->meta_mod_mask)
4527 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4528 dpyinfo->alt_mod_mask = 0;
4531 /* If some keys are both alt and meta,
4532 make them just meta, not alt. */
4533 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4535 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4538 XFree (syms);
4539 XFreeModifiermap (mods);
4542 /* Convert between the modifier bits X uses and the modifier bits
4543 Emacs uses. */
4545 int
4546 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4548 int mod_meta = meta_modifier;
4549 int mod_alt = alt_modifier;
4550 int mod_hyper = hyper_modifier;
4551 int mod_super = super_modifier;
4552 Lisp_Object tem;
4554 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4555 if (INTEGERP (tem)) mod_alt = XINT (tem) & INT_MAX;
4556 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4557 if (INTEGERP (tem)) mod_meta = XINT (tem) & INT_MAX;
4558 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4559 if (INTEGERP (tem)) mod_hyper = XINT (tem) & INT_MAX;
4560 tem = Fget (Vx_super_keysym, Qmodifier_value);
4561 if (INTEGERP (tem)) mod_super = XINT (tem) & INT_MAX;
4563 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
4564 | ((state & ControlMask) ? ctrl_modifier : 0)
4565 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
4566 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
4567 | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
4568 | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
4571 static int
4572 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
4574 EMACS_INT mod_meta = meta_modifier;
4575 EMACS_INT mod_alt = alt_modifier;
4576 EMACS_INT mod_hyper = hyper_modifier;
4577 EMACS_INT mod_super = super_modifier;
4579 Lisp_Object tem;
4581 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4582 if (INTEGERP (tem)) mod_alt = XINT (tem);
4583 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4584 if (INTEGERP (tem)) mod_meta = XINT (tem);
4585 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4586 if (INTEGERP (tem)) mod_hyper = XINT (tem);
4587 tem = Fget (Vx_super_keysym, Qmodifier_value);
4588 if (INTEGERP (tem)) mod_super = XINT (tem);
4591 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0)
4592 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0)
4593 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0)
4594 | ((state & shift_modifier) ? ShiftMask : 0)
4595 | ((state & ctrl_modifier) ? ControlMask : 0)
4596 | ((state & mod_meta) ? dpyinfo->meta_mod_mask : 0));
4599 /* Convert a keysym to its name. */
4601 char *
4602 x_get_keysym_name (int keysym)
4604 char *value;
4606 block_input ();
4607 value = XKeysymToString (keysym);
4608 unblock_input ();
4610 return value;
4613 /* Mouse clicks and mouse movement. Rah.
4615 Formerly, we used PointerMotionHintMask (in standard_event_mask)
4616 so that we would have to call XQueryPointer after each MotionNotify
4617 event to ask for another such event. However, this made mouse tracking
4618 slow, and there was a bug that made it eventually stop.
4620 Simply asking for MotionNotify all the time seems to work better.
4622 In order to avoid asking for motion events and then throwing most
4623 of them away or busy-polling the server for mouse positions, we ask
4624 the server for pointer motion hints. This means that we get only
4625 one event per group of mouse movements. "Groups" are delimited by
4626 other kinds of events (focus changes and button clicks, for
4627 example), or by XQueryPointer calls; when one of these happens, we
4628 get another MotionNotify event the next time the mouse moves. This
4629 is at least as efficient as getting motion events when mouse
4630 tracking is on, and I suspect only negligibly worse when tracking
4631 is off. */
4633 /* Prepare a mouse-event in *RESULT for placement in the input queue.
4635 If the event is a button press, then note that we have grabbed
4636 the mouse. */
4638 static Lisp_Object
4639 construct_mouse_click (struct input_event *result,
4640 const XButtonEvent *event,
4641 struct frame *f)
4643 /* Make the event type NO_EVENT; we'll change that when we decide
4644 otherwise. */
4645 result->kind = MOUSE_CLICK_EVENT;
4646 result->code = event->button - Button1;
4647 result->timestamp = event->time;
4648 result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
4649 event->state)
4650 | (event->type == ButtonRelease
4651 ? up_modifier
4652 : down_modifier));
4654 XSETINT (result->x, event->x);
4655 XSETINT (result->y, event->y);
4656 XSETFRAME (result->frame_or_window, f);
4657 result->arg = Qnil;
4658 return Qnil;
4661 /* Function to report a mouse movement to the mainstream Emacs code.
4662 The input handler calls this.
4664 We have received a mouse movement event, which is given in *event.
4665 If the mouse is over a different glyph than it was last time, tell
4666 the mainstream emacs code by setting mouse_moved. If not, ask for
4667 another motion event, so we can check again the next time it moves. */
4669 static bool
4670 note_mouse_movement (struct frame *frame, const XMotionEvent *event)
4672 XRectangle *r;
4673 struct x_display_info *dpyinfo;
4675 if (!FRAME_X_OUTPUT (frame))
4676 return false;
4678 dpyinfo = FRAME_DISPLAY_INFO (frame);
4679 dpyinfo->last_mouse_movement_time = event->time;
4680 dpyinfo->last_mouse_motion_frame = frame;
4681 dpyinfo->last_mouse_motion_x = event->x;
4682 dpyinfo->last_mouse_motion_y = event->y;
4684 if (event->window != FRAME_X_WINDOW (frame))
4686 frame->mouse_moved = true;
4687 dpyinfo->last_mouse_scroll_bar = NULL;
4688 note_mouse_highlight (frame, -1, -1);
4689 dpyinfo->last_mouse_glyph_frame = NULL;
4690 return true;
4694 /* Has the mouse moved off the glyph it was on at the last sighting? */
4695 r = &dpyinfo->last_mouse_glyph;
4696 if (frame != dpyinfo->last_mouse_glyph_frame
4697 || event->x < r->x || event->x >= r->x + r->width
4698 || event->y < r->y || event->y >= r->y + r->height)
4700 frame->mouse_moved = true;
4701 dpyinfo->last_mouse_scroll_bar = NULL;
4702 note_mouse_highlight (frame, event->x, event->y);
4703 /* Remember which glyph we're now on. */
4704 remember_mouse_glyph (frame, event->x, event->y, r);
4705 dpyinfo->last_mouse_glyph_frame = frame;
4706 return true;
4709 return false;
4712 /* Return the current position of the mouse.
4713 *FP should be a frame which indicates which display to ask about.
<