Merge from gnulib
[emacs.git] / src / xterm.c
blob4f5dfed9ae8f37483deebe6ead4cf78a57893abf
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 (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 || s->font_not_found_p
1728 || s->extends_to_end_of_line_p
1729 || force_p)
1731 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1732 s->background_width,
1733 s->height - 2 * box_line_width);
1734 s->background_filled_p = true;
1740 /* Draw the foreground of glyph string S. */
1742 static void
1743 x_draw_glyph_string_foreground (struct glyph_string *s)
1745 int i, x;
1747 /* If first glyph of S has a left box line, start drawing the text
1748 of S to the right of that box line. */
1749 if (s->face->box != FACE_NO_BOX
1750 && s->first_glyph->left_box_line_p)
1751 x = s->x + eabs (s->face->box_line_width);
1752 else
1753 x = s->x;
1755 /* Draw characters of S as rectangles if S's font could not be
1756 loaded. */
1757 if (s->font_not_found_p)
1759 for (i = 0; i < s->nchars; ++i)
1761 struct glyph *g = s->first_glyph + i;
1762 x_draw_rectangle (s->f,
1763 s->gc, x, s->y, g->pixel_width - 1,
1764 s->height - 1);
1765 x += g->pixel_width;
1768 else
1770 struct font *font = s->font;
1771 int boff = font->baseline_offset;
1772 int y;
1774 if (font->vertical_centering)
1775 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1777 y = s->ybase - boff;
1778 if (s->for_overlaps
1779 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1780 font->driver->draw (s, 0, s->nchars, x, y, false);
1781 else
1782 font->driver->draw (s, 0, s->nchars, x, y, true);
1783 if (s->face->overstrike)
1784 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1788 /* Draw the foreground of composite glyph string S. */
1790 static void
1791 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1793 int i, j, x;
1794 struct font *font = s->font;
1796 /* If first glyph of S has a left box line, start drawing the text
1797 of S to the right of that box line. */
1798 if (s->face && s->face->box != FACE_NO_BOX
1799 && s->first_glyph->left_box_line_p)
1800 x = s->x + eabs (s->face->box_line_width);
1801 else
1802 x = s->x;
1804 /* S is a glyph string for a composition. S->cmp_from is the index
1805 of the first character drawn for glyphs of this composition.
1806 S->cmp_from == 0 means we are drawing the very first character of
1807 this composition. */
1809 /* Draw a rectangle for the composition if the font for the very
1810 first character of the composition could not be loaded. */
1811 if (s->font_not_found_p)
1813 if (s->cmp_from == 0)
1814 x_draw_rectangle (s->f, s->gc, x, s->y,
1815 s->width - 1, s->height - 1);
1817 else if (! s->first_glyph->u.cmp.automatic)
1819 int y = s->ybase;
1821 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1822 /* TAB in a composition means display glyphs with padding
1823 space on the left or right. */
1824 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1826 int xx = x + s->cmp->offsets[j * 2];
1827 int yy = y - s->cmp->offsets[j * 2 + 1];
1829 font->driver->draw (s, j, j + 1, xx, yy, false);
1830 if (s->face->overstrike)
1831 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1834 else
1836 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1837 Lisp_Object glyph;
1838 int y = s->ybase;
1839 int width = 0;
1841 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1843 glyph = LGSTRING_GLYPH (gstring, i);
1844 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1845 width += LGLYPH_WIDTH (glyph);
1846 else
1848 int xoff, yoff, wadjust;
1850 if (j < i)
1852 font->driver->draw (s, j, i, x, y, false);
1853 if (s->face->overstrike)
1854 font->driver->draw (s, j, i, x + 1, y, false);
1855 x += width;
1857 xoff = LGLYPH_XOFF (glyph);
1858 yoff = LGLYPH_YOFF (glyph);
1859 wadjust = LGLYPH_WADJUST (glyph);
1860 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1861 if (s->face->overstrike)
1862 font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
1863 false);
1864 x += wadjust;
1865 j = i + 1;
1866 width = 0;
1869 if (j < i)
1871 font->driver->draw (s, j, i, x, y, false);
1872 if (s->face->overstrike)
1873 font->driver->draw (s, j, i, x + 1, y, false);
1879 /* Draw the foreground of glyph string S for glyphless characters. */
1881 static void
1882 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1884 struct glyph *glyph = s->first_glyph;
1885 XChar2b char2b[8];
1886 int x, i, j;
1888 /* If first glyph of S has a left box line, start drawing the text
1889 of S to the right of that box line. */
1890 if (s->face && s->face->box != FACE_NO_BOX
1891 && s->first_glyph->left_box_line_p)
1892 x = s->x + eabs (s->face->box_line_width);
1893 else
1894 x = s->x;
1896 s->char2b = char2b;
1898 for (i = 0; i < s->nchars; i++, glyph++)
1900 char buf[7], *str = NULL;
1901 int len = glyph->u.glyphless.len;
1903 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1905 if (len > 0
1906 && CHAR_TABLE_P (Vglyphless_char_display)
1907 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1908 >= 1))
1910 Lisp_Object acronym
1911 = (! glyph->u.glyphless.for_no_font
1912 ? CHAR_TABLE_REF (Vglyphless_char_display,
1913 glyph->u.glyphless.ch)
1914 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1915 if (STRINGP (acronym))
1916 str = SSDATA (acronym);
1919 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1921 sprintf (buf, "%0*X",
1922 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1923 glyph->u.glyphless.ch + 0u);
1924 str = buf;
1927 if (str)
1929 int upper_len = (len + 1) / 2;
1930 unsigned code;
1932 /* It is assured that all LEN characters in STR is ASCII. */
1933 for (j = 0; j < len; j++)
1935 code = s->font->driver->encode_char (s->font, str[j]);
1936 STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
1938 s->font->driver->draw (s, 0, upper_len,
1939 x + glyph->slice.glyphless.upper_xoff,
1940 s->ybase + glyph->slice.glyphless.upper_yoff,
1941 false);
1942 s->font->driver->draw (s, upper_len, len,
1943 x + glyph->slice.glyphless.lower_xoff,
1944 s->ybase + glyph->slice.glyphless.lower_yoff,
1945 false);
1947 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1948 x_draw_rectangle (s->f, s->gc,
1949 x, s->ybase - glyph->ascent,
1950 glyph->pixel_width - 1,
1951 glyph->ascent + glyph->descent - 1);
1952 x += glyph->pixel_width;
1956 #ifdef USE_X_TOOLKIT
1958 #ifdef USE_LUCID
1960 /* Return the frame on which widget WIDGET is used.. Abort if frame
1961 cannot be determined. */
1963 static struct frame *
1964 x_frame_of_widget (Widget widget)
1966 struct x_display_info *dpyinfo;
1967 Lisp_Object tail, frame;
1968 struct frame *f;
1970 dpyinfo = x_display_info_for_display (XtDisplay (widget));
1972 /* Find the top-level shell of the widget. Note that this function
1973 can be called when the widget is not yet realized, so XtWindow
1974 (widget) == 0. That's the reason we can't simply use
1975 x_any_window_to_frame. */
1976 while (!XtIsTopLevelShell (widget))
1977 widget = XtParent (widget);
1979 /* Look for a frame with that top-level widget. Allocate the color
1980 on that frame to get the right gamma correction value. */
1981 FOR_EACH_FRAME (tail, frame)
1983 f = XFRAME (frame);
1984 if (FRAME_X_P (f)
1985 && f->output_data.nothing != 1
1986 && FRAME_DISPLAY_INFO (f) == dpyinfo
1987 && f->output_data.x->widget == widget)
1988 return f;
1990 emacs_abort ();
1993 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
1994 or DELTA. Try a color with RGB values multiplied by FACTOR first.
1995 If this produces the same color as PIXEL, try a color where all RGB
1996 values have DELTA added. Return the allocated color in *PIXEL.
1997 DISPLAY is the X display, CMAP is the colormap to operate on.
1998 Value is true if successful. */
2000 bool
2001 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
2002 unsigned long *pixel, double factor, int delta)
2004 struct frame *f = x_frame_of_widget (widget);
2005 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
2008 #endif /* USE_LUCID */
2011 /* Structure specifying which arguments should be passed by Xt to
2012 cvt_string_to_pixel. We want the widget's screen and colormap. */
2014 static XtConvertArgRec cvt_string_to_pixel_args[] =
2016 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
2017 sizeof (Screen *)},
2018 {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
2019 sizeof (Colormap)}
2020 };
2023 /* The address of this variable is returned by
2024 cvt_string_to_pixel. */
2026 static Pixel cvt_string_to_pixel_value;
2029 /* Convert a color name to a pixel color.
2031 DPY is the display we are working on.
2033 ARGS is an array of *NARGS XrmValue structures holding additional
2034 information about the widget for which the conversion takes place.
2035 The contents of this array are determined by the specification
2036 in cvt_string_to_pixel_args.
2038 FROM is a pointer to an XrmValue which points to the color name to
2039 convert. TO is an XrmValue in which to return the pixel color.
2041 CLOSURE_RET is a pointer to user-data, in which we record if
2042 we allocated the color or not.
2044 Value is True if successful, False otherwise. */
2046 static Boolean
2047 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
2048 XrmValue *from, XrmValue *to,
2049 XtPointer *closure_ret)
2051 Screen *screen;
2052 Colormap cmap;
2053 Pixel pixel;
2054 String color_name;
2055 XColor color;
2057 if (*nargs != 2)
2059 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2060 "wrongParameters", "cvt_string_to_pixel",
2061 "XtToolkitError",
2062 "Screen and colormap args required", NULL, NULL);
2063 return False;
2066 screen = *(Screen **) args[0].addr;
2067 cmap = *(Colormap *) args[1].addr;
2068 color_name = (String) from->addr;
2070 if (strcmp (color_name, XtDefaultBackground) == 0)
2072 *closure_ret = (XtPointer) False;
2073 pixel = WhitePixelOfScreen (screen);
2075 else if (strcmp (color_name, XtDefaultForeground) == 0)
2077 *closure_ret = (XtPointer) False;
2078 pixel = BlackPixelOfScreen (screen);
2080 else if (XParseColor (dpy, cmap, color_name, &color)
2081 && x_alloc_nearest_color_1 (dpy, cmap, &color))
2083 pixel = color.pixel;
2084 *closure_ret = (XtPointer) True;
2086 else
2088 String params[1];
2089 Cardinal nparams = 1;
2091 params[0] = color_name;
2092 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
2093 "badValue", "cvt_string_to_pixel",
2094 "XtToolkitError", "Invalid color `%s'",
2095 params, &nparams);
2096 return False;
2099 if (to->addr != NULL)
2101 if (to->size < sizeof (Pixel))
2103 to->size = sizeof (Pixel);
2104 return False;
2107 *(Pixel *) to->addr = pixel;
2109 else
2111 cvt_string_to_pixel_value = pixel;
2112 to->addr = (XtPointer) &cvt_string_to_pixel_value;
2115 to->size = sizeof (Pixel);
2116 return True;
2120 /* Free a pixel color which was previously allocated via
2121 cvt_string_to_pixel. This is registered as the destructor
2122 for this type of resource via XtSetTypeConverter.
2124 APP is the application context in which we work.
2126 TO is a pointer to an XrmValue holding the color to free.
2127 CLOSURE is the value we stored in CLOSURE_RET for this color
2128 in cvt_string_to_pixel.
2130 ARGS and NARGS are like for cvt_string_to_pixel. */
2132 static void
2133 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
2134 Cardinal *nargs)
2136 if (*nargs != 2)
2138 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
2139 "XtToolkitError",
2140 "Screen and colormap arguments required",
2141 NULL, NULL);
2143 else if (closure != NULL)
2145 /* We did allocate the pixel, so free it. */
2146 Screen *screen = *(Screen **) args[0].addr;
2147 Colormap cmap = *(Colormap *) args[1].addr;
2148 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
2149 (Pixel *) to->addr, 1);
2154 #endif /* USE_X_TOOLKIT */
2157 /* Value is an array of XColor structures for the contents of the
2158 color map of display DPY. Set *NCELLS to the size of the array.
2159 Note that this probably shouldn't be called for large color maps,
2160 say a 24-bit TrueColor map. */
2162 static const XColor *
2163 x_color_cells (Display *dpy, int *ncells)
2165 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2167 if (dpyinfo->color_cells == NULL)
2169 Screen *screen = dpyinfo->screen;
2170 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
2171 int i;
2173 dpyinfo->color_cells = xnmalloc (ncolor_cells,
2174 sizeof *dpyinfo->color_cells);
2175 dpyinfo->ncolor_cells = ncolor_cells;
2177 for (i = 0; i < ncolor_cells; ++i)
2178 dpyinfo->color_cells[i].pixel = i;
2180 XQueryColors (dpy, dpyinfo->cmap,
2181 dpyinfo->color_cells, ncolor_cells);
2184 *ncells = dpyinfo->ncolor_cells;
2185 return dpyinfo->color_cells;
2189 /* On frame F, translate pixel colors to RGB values for the NCOLORS
2190 colors in COLORS. Use cached information, if available. */
2192 void
2193 x_query_colors (struct frame *f, XColor *colors, int ncolors)
2195 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2197 if (dpyinfo->color_cells)
2199 int i;
2200 for (i = 0; i < ncolors; ++i)
2202 unsigned long pixel = colors[i].pixel;
2203 eassert (pixel < dpyinfo->ncolor_cells);
2204 eassert (dpyinfo->color_cells[pixel].pixel == pixel);
2205 colors[i] = dpyinfo->color_cells[pixel];
2208 else
2209 XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
2213 /* On frame F, translate pixel color to RGB values for the color in
2214 COLOR. Use cached information, if available. */
2216 void
2217 x_query_color (struct frame *f, XColor *color)
2219 x_query_colors (f, color, 1);
2223 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
2224 exact match can't be allocated, try the nearest color available.
2225 Value is true if successful. Set *COLOR to the color
2226 allocated. */
2228 static bool
2229 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
2231 bool rc;
2233 rc = XAllocColor (dpy, cmap, color) != 0;
2234 if (rc == 0)
2236 /* If we got to this point, the colormap is full, so we're going
2237 to try to get the next closest color. The algorithm used is
2238 a least-squares matching, which is what X uses for closest
2239 color matching with StaticColor visuals. */
2240 int nearest, i;
2241 int max_color_delta = 255;
2242 int max_delta = 3 * max_color_delta;
2243 int nearest_delta = max_delta + 1;
2244 int ncells;
2245 const XColor *cells = x_color_cells (dpy, &ncells);
2247 for (nearest = i = 0; i < ncells; ++i)
2249 int dred = (color->red >> 8) - (cells[i].red >> 8);
2250 int dgreen = (color->green >> 8) - (cells[i].green >> 8);
2251 int dblue = (color->blue >> 8) - (cells[i].blue >> 8);
2252 int delta = dred * dred + dgreen * dgreen + dblue * dblue;
2254 if (delta < nearest_delta)
2256 nearest = i;
2257 nearest_delta = delta;
2261 color->red = cells[nearest].red;
2262 color->green = cells[nearest].green;
2263 color->blue = cells[nearest].blue;
2264 rc = XAllocColor (dpy, cmap, color) != 0;
2266 else
2268 /* If allocation succeeded, and the allocated pixel color is not
2269 equal to a cached pixel color recorded earlier, there was a
2270 change in the colormap, so clear the color cache. */
2271 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
2272 XColor *cached_color;
2274 if (dpyinfo->color_cells
2275 && (cached_color = &dpyinfo->color_cells[color->pixel],
2276 (cached_color->red != color->red
2277 || cached_color->blue != color->blue
2278 || cached_color->green != color->green)))
2280 xfree (dpyinfo->color_cells);
2281 dpyinfo->color_cells = NULL;
2282 dpyinfo->ncolor_cells = 0;
2286 #ifdef DEBUG_X_COLORS
2287 if (rc)
2288 register_color (color->pixel);
2289 #endif /* DEBUG_X_COLORS */
2291 return rc;
2295 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
2296 exact match can't be allocated, try the nearest color available.
2297 Value is true if successful. Set *COLOR to the color
2298 allocated. */
2300 bool
2301 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
2303 gamma_correct (f, color);
2304 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
2308 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2309 It's necessary to do this instead of just using PIXEL directly to
2310 get color reference counts right. */
2312 unsigned long
2313 x_copy_color (struct frame *f, unsigned long pixel)
2315 XColor color;
2317 color.pixel = pixel;
2318 block_input ();
2319 x_query_color (f, &color);
2320 XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
2321 unblock_input ();
2322 #ifdef DEBUG_X_COLORS
2323 register_color (pixel);
2324 #endif
2325 return color.pixel;
2329 /* Brightness beyond which a color won't have its highlight brightness
2330 boosted.
2332 Nominally, highlight colors for `3d' faces are calculated by
2333 brightening an object's color by a constant scale factor, but this
2334 doesn't yield good results for dark colors, so for colors who's
2335 brightness is less than this value (on a scale of 0-65535) have an
2336 use an additional additive factor.
2338 The value here is set so that the default menu-bar/mode-line color
2339 (grey75) will not have its highlights changed at all. */
2340 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
2343 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
2344 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2345 If this produces the same color as PIXEL, try a color where all RGB
2346 values have DELTA added. Return the allocated color in *PIXEL.
2347 DISPLAY is the X display, CMAP is the colormap to operate on.
2348 Value is non-zero if successful. */
2350 static bool
2351 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
2352 unsigned long *pixel, double factor, int delta)
2354 XColor color, new;
2355 long bright;
2356 bool success_p;
2358 /* Get RGB color values. */
2359 color.pixel = *pixel;
2360 x_query_color (f, &color);
2362 /* Change RGB values by specified FACTOR. Avoid overflow! */
2363 eassert (factor >= 0);
2364 new.red = min (0xffff, factor * color.red);
2365 new.green = min (0xffff, factor * color.green);
2366 new.blue = min (0xffff, factor * color.blue);
2368 /* Calculate brightness of COLOR. */
2369 bright = (2 * color.red + 3 * color.green + color.blue) / 6;
2371 /* We only boost colors that are darker than
2372 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2373 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2374 /* Make an additive adjustment to NEW, because it's dark enough so
2375 that scaling by FACTOR alone isn't enough. */
2377 /* How far below the limit this color is (0 - 1, 1 being darker). */
2378 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2379 /* The additive adjustment. */
2380 int min_delta = delta * dimness * factor / 2;
2382 if (factor < 1)
2384 new.red = max (0, new.red - min_delta);
2385 new.green = max (0, new.green - min_delta);
2386 new.blue = max (0, new.blue - min_delta);
2388 else
2390 new.red = min (0xffff, min_delta + new.red);
2391 new.green = min (0xffff, min_delta + new.green);
2392 new.blue = min (0xffff, min_delta + new.blue);
2396 /* Try to allocate the color. */
2397 success_p = x_alloc_nearest_color (f, cmap, &new);
2398 if (success_p)
2400 if (new.pixel == *pixel)
2402 /* If we end up with the same color as before, try adding
2403 delta to the RGB values. */
2404 x_free_colors (f, &new.pixel, 1);
2406 new.red = min (0xffff, delta + color.red);
2407 new.green = min (0xffff, delta + color.green);
2408 new.blue = min (0xffff, delta + color.blue);
2409 success_p = x_alloc_nearest_color (f, cmap, &new);
2411 else
2412 success_p = true;
2413 *pixel = new.pixel;
2416 return success_p;
2420 /* Set up the foreground color for drawing relief lines of glyph
2421 string S. RELIEF is a pointer to a struct relief containing the GC
2422 with which lines will be drawn. Use a color that is FACTOR or
2423 DELTA lighter or darker than the relief's background which is found
2424 in S->f->output_data.x->relief_background. If such a color cannot
2425 be allocated, use DEFAULT_PIXEL, instead. */
2427 static void
2428 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
2429 int delta, unsigned long default_pixel)
2431 XGCValues xgcv;
2432 struct x_output *di = f->output_data.x;
2433 unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
2434 unsigned long pixel;
2435 unsigned long background = di->relief_background;
2436 Colormap cmap = FRAME_X_COLORMAP (f);
2437 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
2438 Display *dpy = FRAME_X_DISPLAY (f);
2440 xgcv.graphics_exposures = False;
2441 xgcv.line_width = 1;
2443 /* Free previously allocated color. The color cell will be reused
2444 when it has been freed as many times as it was allocated, so this
2445 doesn't affect faces using the same colors. */
2446 if (relief->gc && relief->pixel != -1)
2448 x_free_colors (f, &relief->pixel, 1);
2449 relief->pixel = -1;
2452 /* Allocate new color. */
2453 xgcv.foreground = default_pixel;
2454 pixel = background;
2455 if (dpyinfo->n_planes != 1
2456 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
2457 xgcv.foreground = relief->pixel = pixel;
2459 if (relief->gc == 0)
2461 xgcv.stipple = dpyinfo->gray;
2462 mask |= GCStipple;
2463 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv);
2465 else
2466 XChangeGC (dpy, relief->gc, mask, &xgcv);
2470 /* Set up colors for the relief lines around glyph string S. */
2472 static void
2473 x_setup_relief_colors (struct glyph_string *s)
2475 struct x_output *di = s->f->output_data.x;
2476 unsigned long color;
2478 if (s->face->use_box_color_for_shadows_p)
2479 color = s->face->box_color;
2480 else if (s->first_glyph->type == IMAGE_GLYPH
2481 && s->img->pixmap
2482 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2483 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2484 else
2486 XGCValues xgcv;
2488 /* Get the background color of the face. */
2489 XGetGCValues (s->display, s->gc, GCBackground, &xgcv);
2490 color = xgcv.background;
2493 if (di->white_relief.gc == 0
2494 || color != di->relief_background)
2496 di->relief_background = color;
2497 x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
2498 WHITE_PIX_DEFAULT (s->f));
2499 x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
2500 BLACK_PIX_DEFAULT (s->f));
2505 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2506 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2507 to draw, it must be >= 0. RAISED_P means draw a raised
2508 relief. LEFT_P means draw a relief on the left side of
2509 the rectangle. RIGHT_P means draw a relief on the right
2510 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2511 when drawing. */
2513 static void
2514 x_draw_relief_rect (struct frame *f,
2515 int left_x, int top_y, int right_x, int bottom_y,
2516 int width, bool raised_p, bool top_p, bool bot_p,
2517 bool left_p, bool right_p,
2518 XRectangle *clip_rect)
2520 #ifdef USE_CAIRO
2521 GC top_left_gc, bottom_right_gc;
2522 int corners = 0;
2524 if (raised_p)
2526 top_left_gc = f->output_data.x->white_relief.gc;
2527 bottom_right_gc = f->output_data.x->black_relief.gc;
2529 else
2531 top_left_gc = f->output_data.x->black_relief.gc;
2532 bottom_right_gc = f->output_data.x->white_relief.gc;
2535 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2536 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2538 if (left_p)
2540 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2541 width, bottom_y + 1 - top_y);
2542 if (top_p)
2543 corners |= 1 << CORNER_TOP_LEFT;
2544 if (bot_p)
2545 corners |= 1 << CORNER_BOTTOM_LEFT;
2547 if (right_p)
2549 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2550 width, bottom_y + 1 - top_y);
2551 if (top_p)
2552 corners |= 1 << CORNER_TOP_RIGHT;
2553 if (bot_p)
2554 corners |= 1 << CORNER_BOTTOM_RIGHT;
2556 if (top_p)
2558 if (!right_p)
2559 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2560 right_x + 1 - left_x, width);
2561 else
2562 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2563 right_x + 1 - left_x, width, 1);
2565 if (bot_p)
2567 if (!left_p)
2568 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2569 right_x + 1 - left_x, width);
2570 else
2571 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2572 left_x, bottom_y + 1 - width,
2573 right_x + 1 - left_x, width, 0);
2575 if (left_p && width != 1)
2576 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2577 1, bottom_y + 1 - top_y);
2578 if (top_p && width != 1)
2579 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2580 right_x + 1 - left_x, 1);
2581 if (corners)
2583 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2584 FRAME_BACKGROUND_PIXEL (f));
2585 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2586 right_x - left_x + 1, bottom_y - top_y + 1,
2587 6, 1, corners);
2590 x_reset_clip_rectangles (f, top_left_gc);
2591 x_reset_clip_rectangles (f, bottom_right_gc);
2592 #else
2593 Display *dpy = FRAME_X_DISPLAY (f);
2594 Window window = FRAME_X_WINDOW (f);
2595 int i;
2596 GC gc;
2598 if (raised_p)
2599 gc = f->output_data.x->white_relief.gc;
2600 else
2601 gc = f->output_data.x->black_relief.gc;
2602 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2604 /* This code is more complicated than it has to be, because of two
2605 minor hacks to make the boxes look nicer: (i) if width > 1, draw
2606 the outermost line using the black relief. (ii) Omit the four
2607 corner pixels. */
2609 /* Top. */
2610 if (top_p)
2612 if (width == 1)
2613 XDrawLine (dpy, window, gc,
2614 left_x + left_p, top_y,
2615 right_x + !right_p, top_y);
2617 for (i = 1; i < width; ++i)
2618 XDrawLine (dpy, window, gc,
2619 left_x + i * left_p, top_y + i,
2620 right_x + 1 - i * right_p, top_y + i);
2623 /* Left. */
2624 if (left_p)
2626 if (width == 1)
2627 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2629 XClearArea (dpy, window, left_x, top_y, 1, 1, False);
2630 XClearArea (dpy, window, left_x, bottom_y, 1, 1, False);
2632 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2633 XDrawLine (dpy, window, gc,
2634 left_x + i, top_y + (i + 1) * top_p,
2635 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
2638 XSetClipMask (dpy, gc, None);
2639 if (raised_p)
2640 gc = f->output_data.x->black_relief.gc;
2641 else
2642 gc = f->output_data.x->white_relief.gc;
2643 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2645 if (width > 1)
2647 /* Outermost top line. */
2648 if (top_p)
2649 XDrawLine (dpy, window, gc,
2650 left_x + left_p, top_y,
2651 right_x + !right_p, top_y);
2653 /* Outermost left line. */
2654 if (left_p)
2655 XDrawLine (dpy, window, gc, left_x, top_y + 1, left_x, bottom_y);
2658 /* Bottom. */
2659 if (bot_p)
2661 XDrawLine (dpy, window, gc,
2662 left_x + left_p, bottom_y,
2663 right_x + !right_p, bottom_y);
2664 for (i = 1; i < width; ++i)
2665 XDrawLine (dpy, window, gc,
2666 left_x + i * left_p, bottom_y - i,
2667 right_x + 1 - i * right_p, bottom_y - i);
2670 /* Right. */
2671 if (right_p)
2673 XClearArea (dpy, window, right_x, top_y, 1, 1, False);
2674 XClearArea (dpy, window, right_x, bottom_y, 1, 1, False);
2675 for (i = 0; i < width; ++i)
2676 XDrawLine (dpy, window, gc,
2677 right_x - i, top_y + (i + 1) * top_p,
2678 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
2681 x_reset_clip_rectangles (f, gc);
2683 #endif
2687 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2688 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2689 draw, it must be >= 0. LEFT_P means draw a line on the
2690 left side of the rectangle. RIGHT_P means draw a line
2691 on the right side of the rectangle. CLIP_RECT is the clipping
2692 rectangle to use when drawing. */
2694 static void
2695 x_draw_box_rect (struct glyph_string *s,
2696 int left_x, int top_y, int right_x, int bottom_y, int width,
2697 bool left_p, bool right_p, XRectangle *clip_rect)
2699 XGCValues xgcv;
2701 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2702 XSetForeground (s->display, s->gc, s->face->box_color);
2703 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
2705 /* Top. */
2706 x_fill_rectangle (s->f, s->gc,
2707 left_x, top_y, right_x - left_x + 1, width);
2709 /* Left. */
2710 if (left_p)
2711 x_fill_rectangle (s->f, s->gc,
2712 left_x, top_y, width, bottom_y - top_y + 1);
2714 /* Bottom. */
2715 x_fill_rectangle (s->f, s->gc,
2716 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2718 /* Right. */
2719 if (right_p)
2720 x_fill_rectangle (s->f, s->gc,
2721 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2723 XSetForeground (s->display, s->gc, xgcv.foreground);
2724 x_reset_clip_rectangles (s->f, s->gc);
2728 /* Draw a box around glyph string S. */
2730 static void
2731 x_draw_glyph_string_box (struct glyph_string *s)
2733 int width, left_x, right_x, top_y, bottom_y, last_x;
2734 bool raised_p, left_p, right_p;
2735 struct glyph *last_glyph;
2736 XRectangle clip_rect;
2738 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
2739 ? WINDOW_RIGHT_EDGE_X (s->w)
2740 : window_box_right (s->w, s->area));
2742 /* The glyph that may have a right box line. */
2743 last_glyph = (s->cmp || s->img
2744 ? s->first_glyph
2745 : s->first_glyph + s->nchars - 1);
2747 width = eabs (s->face->box_line_width);
2748 raised_p = s->face->box == FACE_RAISED_BOX;
2749 left_x = s->x;
2750 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2751 ? last_x - 1
2752 : min (last_x, s->x + s->background_width) - 1);
2753 top_y = s->y;
2754 bottom_y = top_y + s->height - 1;
2756 left_p = (s->first_glyph->left_box_line_p
2757 || (s->hl == DRAW_MOUSE_FACE
2758 && (s->prev == NULL
2759 || s->prev->hl != s->hl)));
2760 right_p = (last_glyph->right_box_line_p
2761 || (s->hl == DRAW_MOUSE_FACE
2762 && (s->next == NULL
2763 || s->next->hl != s->hl)));
2765 get_glyph_string_clip_rect (s, &clip_rect);
2767 if (s->face->box == FACE_SIMPLE_BOX)
2768 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2769 left_p, right_p, &clip_rect);
2770 else
2772 x_setup_relief_colors (s);
2773 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
2774 width, raised_p, true, true, left_p, right_p,
2775 &clip_rect);
2780 /* Draw foreground of image glyph string S. */
2782 static void
2783 x_draw_image_foreground (struct glyph_string *s)
2785 int x = s->x;
2786 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2788 /* If first glyph of S has a left box line, start drawing it to the
2789 right of that line. */
2790 if (s->face->box != FACE_NO_BOX
2791 && s->first_glyph->left_box_line_p
2792 && s->slice.x == 0)
2793 x += eabs (s->face->box_line_width);
2795 /* If there is a margin around the image, adjust x- and y-position
2796 by that margin. */
2797 if (s->slice.x == 0)
2798 x += s->img->hmargin;
2799 if (s->slice.y == 0)
2800 y += s->img->vmargin;
2802 if (s->img->pixmap)
2804 if (s->img->mask)
2806 /* We can't set both a clip mask and use XSetClipRectangles
2807 because the latter also sets a clip mask. We also can't
2808 trust on the shape extension to be available
2809 (XShapeCombineRegion). So, compute the rectangle to draw
2810 manually. */
2811 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2812 | GCFunction);
2813 XGCValues xgcv;
2814 XRectangle clip_rect, image_rect, r;
2816 xgcv.clip_mask = s->img->mask;
2817 xgcv.clip_x_origin = x;
2818 xgcv.clip_y_origin = y;
2819 xgcv.function = GXcopy;
2820 XChangeGC (s->display, s->gc, mask, &xgcv);
2822 get_glyph_string_clip_rect (s, &clip_rect);
2823 image_rect.x = x;
2824 image_rect.y = y;
2825 image_rect.width = s->slice.width;
2826 image_rect.height = s->slice.height;
2827 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2828 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2829 s->slice.x + r.x - x, s->slice.y + r.y - y,
2830 r.width, r.height, r.x, r.y);
2832 else
2834 XRectangle clip_rect, image_rect, r;
2836 get_glyph_string_clip_rect (s, &clip_rect);
2837 image_rect.x = x;
2838 image_rect.y = y;
2839 image_rect.width = s->slice.width;
2840 image_rect.height = s->slice.height;
2841 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2842 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
2843 s->slice.x + r.x - x, s->slice.y + r.y - y,
2844 r.width, r.height, r.x, r.y);
2846 /* When the image has a mask, we can expect that at
2847 least part of a mouse highlight or a block cursor will
2848 be visible. If the image doesn't have a mask, make
2849 a block cursor visible by drawing a rectangle around
2850 the image. I believe it's looking better if we do
2851 nothing here for mouse-face. */
2852 if (s->hl == DRAW_CURSOR)
2854 int relief = eabs (s->img->relief);
2855 x_draw_rectangle (s->f, s->gc,
2856 x - relief, y - relief,
2857 s->slice.width + relief*2 - 1,
2858 s->slice.height + relief*2 - 1);
2862 else
2863 /* Draw a rectangle if image could not be loaded. */
2864 x_draw_rectangle (s->f, s->gc, x, y,
2865 s->slice.width - 1, s->slice.height - 1);
2869 /* Draw a relief around the image glyph string S. */
2871 static void
2872 x_draw_image_relief (struct glyph_string *s)
2874 int x1, y1, thick;
2875 bool raised_p, top_p, bot_p, left_p, right_p;
2876 int extra_x, extra_y;
2877 XRectangle r;
2878 int x = s->x;
2879 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2881 /* If first glyph of S has a left box line, start drawing it to the
2882 right of that line. */
2883 if (s->face->box != FACE_NO_BOX
2884 && s->first_glyph->left_box_line_p
2885 && s->slice.x == 0)
2886 x += eabs (s->face->box_line_width);
2888 /* If there is a margin around the image, adjust x- and y-position
2889 by that margin. */
2890 if (s->slice.x == 0)
2891 x += s->img->hmargin;
2892 if (s->slice.y == 0)
2893 y += s->img->vmargin;
2895 if (s->hl == DRAW_IMAGE_SUNKEN
2896 || s->hl == DRAW_IMAGE_RAISED)
2898 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
2899 raised_p = s->hl == DRAW_IMAGE_RAISED;
2901 else
2903 thick = eabs (s->img->relief);
2904 raised_p = s->img->relief > 0;
2907 x1 = x + s->slice.width - 1;
2908 y1 = y + s->slice.height - 1;
2910 extra_x = extra_y = 0;
2911 if (s->face->id == TOOL_BAR_FACE_ID)
2913 if (CONSP (Vtool_bar_button_margin)
2914 && INTEGERP (XCAR (Vtool_bar_button_margin))
2915 && INTEGERP (XCDR (Vtool_bar_button_margin)))
2917 extra_x = XINT (XCAR (Vtool_bar_button_margin));
2918 extra_y = XINT (XCDR (Vtool_bar_button_margin));
2920 else if (INTEGERP (Vtool_bar_button_margin))
2921 extra_x = extra_y = XINT (Vtool_bar_button_margin);
2924 top_p = bot_p = left_p = right_p = false;
2926 if (s->slice.x == 0)
2927 x -= thick + extra_x, left_p = true;
2928 if (s->slice.y == 0)
2929 y -= thick + extra_y, top_p = true;
2930 if (s->slice.x + s->slice.width == s->img->width)
2931 x1 += thick + extra_x, right_p = true;
2932 if (s->slice.y + s->slice.height == s->img->height)
2933 y1 += thick + extra_y, bot_p = true;
2935 x_setup_relief_colors (s);
2936 get_glyph_string_clip_rect (s, &r);
2937 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
2938 top_p, bot_p, left_p, right_p, &r);
2942 /* Draw the foreground of image glyph string S to PIXMAP. */
2944 static void
2945 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
2947 int x = 0;
2948 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2950 /* If first glyph of S has a left box line, start drawing it to the
2951 right of that line. */
2952 if (s->face->box != FACE_NO_BOX
2953 && s->first_glyph->left_box_line_p
2954 && s->slice.x == 0)
2955 x += eabs (s->face->box_line_width);
2957 /* If there is a margin around the image, adjust x- and y-position
2958 by that margin. */
2959 if (s->slice.x == 0)
2960 x += s->img->hmargin;
2961 if (s->slice.y == 0)
2962 y += s->img->vmargin;
2964 if (s->img->pixmap)
2966 if (s->img->mask)
2968 /* We can't set both a clip mask and use XSetClipRectangles
2969 because the latter also sets a clip mask. We also can't
2970 trust on the shape extension to be available
2971 (XShapeCombineRegion). So, compute the rectangle to draw
2972 manually. */
2973 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2974 | GCFunction);
2975 XGCValues xgcv;
2977 xgcv.clip_mask = s->img->mask;
2978 xgcv.clip_x_origin = x - s->slice.x;
2979 xgcv.clip_y_origin = y - s->slice.y;
2980 xgcv.function = GXcopy;
2981 XChangeGC (s->display, s->gc, mask, &xgcv);
2983 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2984 s->slice.x, s->slice.y,
2985 s->slice.width, s->slice.height, x, y);
2986 XSetClipMask (s->display, s->gc, None);
2988 else
2990 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2991 s->slice.x, s->slice.y,
2992 s->slice.width, s->slice.height, x, y);
2994 /* When the image has a mask, we can expect that at
2995 least part of a mouse highlight or a block cursor will
2996 be visible. If the image doesn't have a mask, make
2997 a block cursor visible by drawing a rectangle around
2998 the image. I believe it's looking better if we do
2999 nothing here for mouse-face. */
3000 if (s->hl == DRAW_CURSOR)
3002 int r = eabs (s->img->relief);
3003 x_draw_rectangle (s->f, s->gc, x - r, y - r,
3004 s->slice.width + r*2 - 1,
3005 s->slice.height + r*2 - 1);
3009 else
3010 /* Draw a rectangle if image could not be loaded. */
3011 x_draw_rectangle (s->f, s->gc, x, y,
3012 s->slice.width - 1, s->slice.height - 1);
3016 /* Draw part of the background of glyph string S. X, Y, W, and H
3017 give the rectangle to draw. */
3019 static void
3020 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3022 if (s->stippled_p)
3024 /* Fill background with a stipple pattern. */
3025 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3026 x_fill_rectangle (s->f, s->gc, x, y, w, h);
3027 XSetFillStyle (s->display, s->gc, FillSolid);
3029 else
3030 x_clear_glyph_string_rect (s, x, y, w, h);
3034 /* Draw image glyph string S.
3036 s->y
3037 s->x +-------------------------
3038 | s->face->box
3040 | +-------------------------
3041 | | s->img->margin
3042 | |
3043 | | +-------------------
3044 | | | the image
3046 */
3048 static void
3049 x_draw_image_glyph_string (struct glyph_string *s)
3051 int box_line_hwidth = eabs (s->face->box_line_width);
3052 int box_line_vwidth = max (s->face->box_line_width, 0);
3053 int height;
3054 Pixmap pixmap = None;
3056 height = s->height;
3057 if (s->slice.y == 0)
3058 height -= box_line_vwidth;
3059 if (s->slice.y + s->slice.height >= s->img->height)
3060 height -= box_line_vwidth;
3062 /* Fill background with face under the image. Do it only if row is
3063 taller than image or if image has a clip mask to reduce
3064 flickering. */
3065 s->stippled_p = s->face->stipple != 0;
3066 if (height > s->slice.height
3067 || s->img->hmargin
3068 || s->img->vmargin
3069 || s->img->mask
3070 || s->img->pixmap == 0
3071 || s->width != s->background_width)
3073 if (s->img->mask)
3075 /* Create a pixmap as large as the glyph string. Fill it
3076 with the background color. Copy the image to it, using
3077 its mask. Copy the temporary pixmap to the display. */
3078 Screen *screen = FRAME_X_SCREEN (s->f);
3079 int depth = DefaultDepthOfScreen (screen);
3081 /* Create a pixmap as large as the glyph string. */
3082 pixmap = XCreatePixmap (s->display, s->window,
3083 s->background_width,
3084 s->height, depth);
3086 /* Don't clip in the following because we're working on the
3087 pixmap. */
3088 XSetClipMask (s->display, s->gc, None);
3090 /* Fill the pixmap with the background color/stipple. */
3091 if (s->stippled_p)
3093 /* Fill background with a stipple pattern. */
3094 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3095 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
3096 XFillRectangle (s->display, pixmap, s->gc,
3097 0, 0, s->background_width, s->height);
3098 XSetFillStyle (s->display, s->gc, FillSolid);
3099 XSetTSOrigin (s->display, s->gc, 0, 0);
3101 else
3103 XGCValues xgcv;
3104 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3105 &xgcv);
3106 XSetForeground (s->display, s->gc, xgcv.background);
3107 XFillRectangle (s->display, pixmap, s->gc,
3108 0, 0, s->background_width, s->height);
3109 XSetForeground (s->display, s->gc, xgcv.foreground);
3112 else
3114 int x = s->x;
3115 int y = s->y;
3116 int width = s->background_width;
3118 if (s->first_glyph->left_box_line_p
3119 && s->slice.x == 0)
3121 x += box_line_hwidth;
3122 width -= box_line_hwidth;
3125 if (s->slice.y == 0)
3126 y += box_line_vwidth;
3128 x_draw_glyph_string_bg_rect (s, x, y, width, height);
3131 s->background_filled_p = true;
3134 /* Draw the foreground. */
3135 #ifdef USE_CAIRO
3136 if (s->img->cr_data)
3138 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3140 int x = s->x + s->img->hmargin;
3141 int y = s->y + s->img->vmargin;
3142 int width = s->background_width;
3144 cairo_set_source_surface (cr, s->img->cr_data,
3145 x - s->slice.x,
3146 y - s->slice.y);
3147 cairo_rectangle (cr, x, y, width, height);
3148 cairo_fill (cr);
3149 x_end_cr_clip (s->f);
3151 else
3152 #endif
3153 if (pixmap != None)
3155 x_draw_image_foreground_1 (s, pixmap);
3156 x_set_glyph_string_clipping (s);
3157 XCopyArea (s->display, pixmap, s->window, s->gc,
3158 0, 0, s->background_width, s->height, s->x, s->y);
3159 XFreePixmap (s->display, pixmap);
3161 else
3162 x_draw_image_foreground (s);
3164 /* If we must draw a relief around the image, do it. */
3165 if (s->img->relief
3166 || s->hl == DRAW_IMAGE_RAISED
3167 || s->hl == DRAW_IMAGE_SUNKEN)
3168 x_draw_image_relief (s);
3172 /* Draw stretch glyph string S. */
3174 static void
3175 x_draw_stretch_glyph_string (struct glyph_string *s)
3177 eassert (s->first_glyph->type == STRETCH_GLYPH);
3179 if (s->hl == DRAW_CURSOR
3180 && !x_stretch_cursor_p)
3182 /* If `x-stretch-cursor' is nil, don't draw a block cursor as
3183 wide as the stretch glyph. */
3184 int width, background_width = s->background_width;
3185 int x = s->x;
3187 if (!s->row->reversed_p)
3189 int left_x = window_box_left_offset (s->w, TEXT_AREA);
3191 if (x < left_x)
3193 background_width -= left_x - x;
3194 x = left_x;
3197 else
3199 /* In R2L rows, draw the cursor on the right edge of the
3200 stretch glyph. */
3201 int right_x = window_box_right (s->w, TEXT_AREA);
3203 if (x + background_width > right_x)
3204 background_width -= x - right_x;
3205 x += background_width;
3207 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
3208 if (s->row->reversed_p)
3209 x -= width;
3211 /* Draw cursor. */
3212 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
3214 /* Clear rest using the GC of the original non-cursor face. */
3215 if (width < background_width)
3217 int y = s->y;
3218 int w = background_width - width, h = s->height;
3219 XRectangle r;
3220 GC gc;
3222 if (!s->row->reversed_p)
3223 x += width;
3224 else
3225 x = s->x;
3226 if (s->row->mouse_face_p
3227 && cursor_in_mouse_face_p (s->w))
3229 x_set_mouse_face_gc (s);
3230 gc = s->gc;
3232 else
3233 gc = s->face->gc;
3235 get_glyph_string_clip_rect (s, &r);
3236 x_set_clip_rectangles (s->f, gc, &r, 1);
3238 if (s->face->stipple)
3240 /* Fill background with a stipple pattern. */
3241 XSetFillStyle (s->display, gc, FillOpaqueStippled);
3242 x_fill_rectangle (s->f, gc, x, y, w, h);
3243 XSetFillStyle (s->display, gc, FillSolid);
3245 else
3247 XGCValues xgcv;
3248 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
3249 XSetForeground (s->display, gc, xgcv.background);
3250 x_fill_rectangle (s->f, gc, x, y, w, h);
3251 XSetForeground (s->display, gc, xgcv.foreground);
3254 x_reset_clip_rectangles (s->f, gc);
3257 else if (!s->background_filled_p)
3259 int background_width = s->background_width;
3260 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
3262 /* Don't draw into left margin, fringe or scrollbar area
3263 except for header line and mode line. */
3264 if (x < left_x && !s->row->mode_line_p)
3266 background_width -= left_x - x;
3267 x = left_x;
3269 if (background_width > 0)
3270 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
3273 s->background_filled_p = true;
3276 /*
3277 Draw a wavy line under S. The wave fills wave_height pixels from y0.
3279 x0 wave_length = 2
3280 --
3281 y0 * * * * *
3282 |* * * * * * * * *
3283 wave_height = 3 | * * * *
3285 */
3287 static void
3288 x_draw_underwave (struct glyph_string *s)
3290 int wave_height = 3, wave_length = 2;
3291 #ifdef USE_CAIRO
3292 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3293 s->width, wave_height, wave_length);
3294 #else /* not USE_CAIRO */
3295 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
3296 bool odd;
3297 XRectangle wave_clip, string_clip, final_clip;
3299 dx = wave_length;
3300 dy = wave_height - 1;
3301 x0 = s->x;
3302 y0 = s->ybase - wave_height + 3;
3303 width = s->width;
3304 xmax = x0 + width;
3306 /* Find and set clipping rectangle */
3308 wave_clip.x = x0;
3309 wave_clip.y = y0;
3310 wave_clip.width = width;
3311 wave_clip.height = wave_height;
3312 get_glyph_string_clip_rect (s, &string_clip);
3314 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
3315 return;
3317 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
3319 /* Draw the waves */
3321 x1 = x0 - (x0 % dx);
3322 x2 = x1 + dx;
3323 odd = (x1 / dx) & 1;
3324 y1 = y2 = y0;
3326 if (odd)
3327 y1 += dy;
3328 else
3329 y2 += dy;
3331 if (INT_MAX - dx < xmax)
3332 emacs_abort ();
3334 while (x1 <= xmax)
3336 XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
3337 x1 = x2, y1 = y2;
3338 x2 += dx, y2 = y0 + odd*dy;
3339 odd = !odd;
3342 /* Restore previous clipping rectangle(s) */
3343 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3344 #endif /* not USE_CAIRO */
3348 /* Draw glyph string S. */
3350 static void
3351 x_draw_glyph_string (struct glyph_string *s)
3353 bool relief_drawn_p = false;
3355 /* If S draws into the background of its successors, draw the
3356 background of the successors first so that S can draw into it.
3357 This makes S->next use XDrawString instead of XDrawImageString. */
3358 if (s->next && s->right_overhang && !s->for_overlaps)
3360 int width;
3361 struct glyph_string *next;
3363 for (width = 0, next = s->next;
3364 next && width < s->right_overhang;
3365 width += next->width, next = next->next)
3366 if (next->first_glyph->type != IMAGE_GLYPH)
3368 x_set_glyph_string_gc (next);
3369 x_set_glyph_string_clipping (next);
3370 if (next->first_glyph->type == STRETCH_GLYPH)
3371 x_draw_stretch_glyph_string (next);
3372 else
3373 x_draw_glyph_string_background (next, true);
3374 next->num_clips = 0;
3378 /* Set up S->gc, set clipping and draw S. */
3379 x_set_glyph_string_gc (s);
3381 /* Draw relief (if any) in advance for char/composition so that the
3382 glyph string can be drawn over it. */
3383 if (!s->for_overlaps
3384 && s->face->box != FACE_NO_BOX
3385 && (s->first_glyph->type == CHAR_GLYPH
3386 || s->first_glyph->type == COMPOSITE_GLYPH))
3389 x_set_glyph_string_clipping (s);
3390 x_draw_glyph_string_background (s, true);
3391 x_draw_glyph_string_box (s);
3392 x_set_glyph_string_clipping (s);
3393 relief_drawn_p = true;
3395 else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
3396 && !s->clip_tail
3397 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
3398 || (s->next && s->next->hl != s->hl && s->right_overhang)))
3399 /* We must clip just this glyph. left_overhang part has already
3400 drawn when s->prev was drawn, and right_overhang part will be
3401 drawn later when s->next is drawn. */
3402 x_set_glyph_string_clipping_exactly (s, s);
3403 else
3404 x_set_glyph_string_clipping (s);
3406 switch (s->first_glyph->type)
3408 case IMAGE_GLYPH:
3409 x_draw_image_glyph_string (s);
3410 break;
3412 case STRETCH_GLYPH:
3413 x_draw_stretch_glyph_string (s);
3414 break;
3416 case CHAR_GLYPH:
3417 if (s->for_overlaps)
3418 s->background_filled_p = true;
3419 else
3420 x_draw_glyph_string_background (s, false);
3421 x_draw_glyph_string_foreground (s);
3422 break;
3424 case COMPOSITE_GLYPH:
3425 if (s->for_overlaps || (s->cmp_from > 0
3426 && ! s->first_glyph->u.cmp.automatic))
3427 s->background_filled_p = true;
3428 else
3429 x_draw_glyph_string_background (s, true);
3430 x_draw_composite_glyph_string_foreground (s);
3431 break;
3433 case GLYPHLESS_GLYPH:
3434 if (s->for_overlaps)
3435 s->background_filled_p = true;
3436 else
3437 x_draw_glyph_string_background (s, true);
3438 x_draw_glyphless_glyph_string_foreground (s);
3439 break;
3441 default:
3442 emacs_abort ();
3445 if (!s->for_overlaps)
3447 /* Draw underline. */
3448 if (s->face->underline_p)
3450 if (s->face->underline_type == FACE_UNDER_WAVE)
3452 if (s->face->underline_defaulted_p)
3453 x_draw_underwave (s);
3454 else
3456 XGCValues xgcv;
3457 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3458 XSetForeground (s->display, s->gc, s->face->underline_color);
3459 x_draw_underwave (s);
3460 XSetForeground (s->display, s->gc, xgcv.foreground);
3463 else if (s->face->underline_type == FACE_UNDER_LINE)
3465 unsigned long thickness, position;
3466 int y;
3468 if (s->prev && s->prev->face->underline_p
3469 && s->prev->face->underline_type == FACE_UNDER_LINE)
3471 /* We use the same underline style as the previous one. */
3472 thickness = s->prev->underline_thickness;
3473 position = s->prev->underline_position;
3475 else
3477 /* Get the underline thickness. Default is 1 pixel. */
3478 if (s->font && s->font->underline_thickness > 0)
3479 thickness = s->font->underline_thickness;
3480 else
3481 thickness = 1;
3482 if (x_underline_at_descent_line)
3483 position = (s->height - thickness) - (s->ybase - s->y);
3484 else
3486 /* Get the underline position. This is the recommended
3487 vertical offset in pixels from the baseline to the top of
3488 the underline. This is a signed value according to the
3489 specs, and its default is
3491 ROUND ((maximum descent) / 2), with
3492 ROUND(x) = floor (x + 0.5) */
3494 if (x_use_underline_position_properties
3495 && s->font && s->font->underline_position >= 0)
3496 position = s->font->underline_position;
3497 else if (s->font)
3498 position = (s->font->descent + 1) / 2;
3499 else
3500 position = underline_minimum_offset;
3502 position = max (position, underline_minimum_offset);
3504 /* Check the sanity of thickness and position. We should
3505 avoid drawing underline out of the current line area. */
3506 if (s->y + s->height <= s->ybase + position)
3507 position = (s->height - 1) - (s->ybase - s->y);
3508 if (s->y + s->height < s->ybase + position + thickness)
3509 thickness = (s->y + s->height) - (s->ybase + position);
3510 s->underline_thickness = thickness;
3511 s->underline_position = position;
3512 y = s->ybase + position;
3513 if (s->face->underline_defaulted_p)
3514 x_fill_rectangle (s->f, s->gc,
3515 s->x, y, s->width, thickness);
3516 else
3518 XGCValues xgcv;
3519 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3520 XSetForeground (s->display, s->gc, s->face->underline_color);
3521 x_fill_rectangle (s->f, s->gc,
3522 s->x, y, s->width, thickness);
3523 XSetForeground (s->display, s->gc, xgcv.foreground);
3527 /* Draw overline. */
3528 if (s->face->overline_p)
3530 unsigned long dy = 0, h = 1;
3532 if (s->face->overline_color_defaulted_p)
3533 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3534 s->width, h);
3535 else
3537 XGCValues xgcv;
3538 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3539 XSetForeground (s->display, s->gc, s->face->overline_color);
3540 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3541 s->width, h);
3542 XSetForeground (s->display, s->gc, xgcv.foreground);
3546 /* Draw strike-through. */
3547 if (s->face->strike_through_p)
3549 unsigned long h = 1;
3550 unsigned long dy = (s->height - h) / 2;
3552 if (s->face->strike_through_color_defaulted_p)
3553 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3554 s->width, h);
3555 else
3557 XGCValues xgcv;
3558 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
3559 XSetForeground (s->display, s->gc, s->face->strike_through_color);
3560 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
3561 s->width, h);
3562 XSetForeground (s->display, s->gc, xgcv.foreground);
3566 /* Draw relief if not yet drawn. */
3567 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
3568 x_draw_glyph_string_box (s);
3570 if (s->prev)
3572 struct glyph_string *prev;
3574 for (prev = s->prev; prev; prev = prev->prev)
3575 if (prev->hl != s->hl
3576 && prev->x + prev->width + prev->right_overhang > s->x)
3578 /* As prev was drawn while clipped to its own area, we
3579 must draw the right_overhang part using s->hl now. */
3580 enum draw_glyphs_face save = prev->hl;
3582 prev->hl = s->hl;
3583 x_set_glyph_string_gc (prev);
3584 x_set_glyph_string_clipping_exactly (s, prev);
3585 if (prev->first_glyph->type == CHAR_GLYPH)
3586 x_draw_glyph_string_foreground (prev);
3587 else
3588 x_draw_composite_glyph_string_foreground (prev);
3589 x_reset_clip_rectangles (prev->f, prev->gc);
3590 prev->hl = save;
3591 prev->num_clips = 0;
3595 if (s->next)
3597 struct glyph_string *next;
3599 for (next = s->next; next; next = next->next)
3600 if (next->hl != s->hl
3601 && next->x - next->left_overhang < s->x + s->width)
3603 /* As next will be drawn while clipped to its own area,
3604 we must draw the left_overhang part using s->hl now. */
3605 enum draw_glyphs_face save = next->hl;
3607 next->hl = s->hl;
3608 x_set_glyph_string_gc (next);
3609 x_set_glyph_string_clipping_exactly (s, next);
3610 if (next->first_glyph->type == CHAR_GLYPH)
3611 x_draw_glyph_string_foreground (next);
3612 else
3613 x_draw_composite_glyph_string_foreground (next);
3614 x_reset_clip_rectangles (next->f, next->gc);
3615 next->hl = save;
3616 next->num_clips = 0;
3617 next->clip_head = s->next;
3622 /* Reset clipping. */
3623 x_reset_clip_rectangles (s->f, s->gc);
3624 s->num_clips = 0;
3627 /* Shift display to make room for inserted glyphs. */
3629 static void
3630 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
3632 /* Never called on a GUI frame, see
3633 http://lists.gnu.org/archive/html/emacs-devel/2015-05/msg00456.html
3634 */
3635 XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
3636 f->output_data.x->normal_gc,
3637 x, y, width, height,
3638 x + shift_by, y);
3641 /* Delete N glyphs at the nominal cursor position. Not implemented
3642 for X frames. */
3644 static void
3645 x_delete_glyphs (struct frame *f, register int n)
3647 emacs_abort ();
3651 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
3652 If they are <= 0, this is probably an error. */
3654 static void
3655 x_clear_area1 (Display *dpy, Window window,
3656 int x, int y, int width, int height, int exposures)
3658 eassert (width > 0 && height > 0);
3659 XClearArea (dpy, window, x, y, width, height, exposures);
3663 void
3664 x_clear_area (struct frame *f, int x, int y, int width, int height)
3666 #ifdef USE_CAIRO
3667 cairo_t *cr;
3669 eassert (width > 0 && height > 0);
3671 cr = x_begin_cr_clip (f, NULL);
3672 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3673 cairo_rectangle (cr, x, y, width, height);
3674 cairo_fill (cr);
3675 x_end_cr_clip (f);
3676 #else
3677 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3678 x, y, width, height, False);
3679 #endif
3683 /* Clear an entire frame. */
3685 static void
3686 x_clear_frame (struct frame *f)
3688 /* Clearing the frame will erase any cursor, so mark them all as no
3689 longer visible. */
3690 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3692 block_input ();
3694 x_clear_window (f);
3696 /* We have to clear the scroll bars. If we have changed colors or
3697 something like that, then they should be notified. */
3698 x_scroll_bar_clear (f);
3700 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3701 /* Make sure scroll bars are redrawn. As they aren't redrawn by
3702 redisplay, do it here. */
3703 if (FRAME_GTK_WIDGET (f))
3704 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
3705 #endif
3707 XFlush (FRAME_X_DISPLAY (f));
3709 unblock_input ();
3712 /* RIF: Show hourglass cursor on frame F. */
3714 static void
3715 x_show_hourglass (struct frame *f)
3717 Display *dpy = FRAME_X_DISPLAY (f);
3719 if (dpy)
3721 struct x_output *x = FRAME_X_OUTPUT (f);
3722 #ifdef USE_X_TOOLKIT
3723 if (x->widget)
3724 #else
3725 if (FRAME_OUTER_WINDOW (f))
3726 #endif
3728 x->hourglass_p = true;
3730 if (!x->hourglass_window)
3732 unsigned long mask = CWCursor;
3733 XSetWindowAttributes attrs;
3734 #ifdef USE_GTK
3735 Window parent = FRAME_X_WINDOW (f);
3736 #else
3737 Window parent = FRAME_OUTER_WINDOW (f);
3738 #endif
3739 attrs.cursor = x->hourglass_cursor;
3741 x->hourglass_window = XCreateWindow
3742 (dpy, parent, 0, 0, 32000, 32000, 0, 0,
3743 InputOnly, CopyFromParent, mask, &attrs);
3746 XMapRaised (dpy, x->hourglass_window);
3747 XFlush (dpy);
3752 /* RIF: Cancel hourglass cursor on frame F. */
3754 static void
3755 x_hide_hourglass (struct frame *f)
3757 struct x_output *x = FRAME_X_OUTPUT (f);
3759 /* Watch out for newly created frames. */
3760 if (x->hourglass_window)
3762 XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
3763 /* Sync here because XTread_socket looks at the
3764 hourglass_p flag that is reset to zero below. */
3765 XSync (FRAME_X_DISPLAY (f), False);
3766 x->hourglass_p = false;
3770 /* Invert the middle quarter of the frame for .15 sec. */
3772 static void
3773 XTflash (struct frame *f)
3775 block_input ();
3778 #ifdef USE_GTK
3779 /* Use Gdk routines to draw. This way, we won't draw over scroll bars
3780 when the scroll bars and the edit widget share the same X window. */
3781 GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
3782 #ifdef HAVE_GTK3
3783 cairo_t *cr = gdk_cairo_create (window);
3784 cairo_set_source_rgb (cr, 1, 1, 1);
3785 cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
3786 #define XFillRectangle(d, win, gc, x, y, w, h) \
3787 do { \
3788 cairo_rectangle (cr, x, y, w, h); \
3789 cairo_fill (cr); \
3790 } \
3791 while (false)
3792 #else /* ! HAVE_GTK3 */
3793 GdkGCValues vals;
3794 GdkGC *gc;
3795 vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
3796 ^ FRAME_BACKGROUND_PIXEL (f));
3797 vals.function = GDK_XOR;
3798 gc = gdk_gc_new_with_values (window,
3799 &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
3800 #define XFillRectangle(d, win, gc, x, y, w, h) \
3801 gdk_draw_rectangle (window, gc, true, x, y, w, h)
3802 #endif /* ! HAVE_GTK3 */
3803 #else /* ! USE_GTK */
3804 GC gc;
3806 /* Create a GC that will use the GXxor function to flip foreground
3807 pixels into background pixels. */
3809 XGCValues values;
3811 values.function = GXxor;
3812 values.foreground = (FRAME_FOREGROUND_PIXEL (f)
3813 ^ FRAME_BACKGROUND_PIXEL (f));
3815 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3816 GCFunction | GCForeground, &values);
3818 #endif
3820 /* Get the height not including a menu bar widget. */
3821 int height = FRAME_PIXEL_HEIGHT (f);
3822 /* Height of each line to flash. */
3823 int flash_height = FRAME_LINE_HEIGHT (f);
3824 /* These will be the left and right margins of the rectangles. */
3825 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3826 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3827 int width = flash_right - flash_left;
3829 /* If window is tall, flash top and bottom line. */
3830 if (height > 3 * FRAME_LINE_HEIGHT (f))
3832 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3833 flash_left,
3834 (FRAME_INTERNAL_BORDER_WIDTH (f)
3835 + FRAME_TOP_MARGIN_HEIGHT (f)),
3836 width, flash_height);
3837 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3838 flash_left,
3839 (height - flash_height
3840 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3841 width, flash_height);
3844 else
3845 /* If it is short, flash it all. */
3846 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3847 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3848 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3850 x_flush (f);
3853 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
3854 struct timespec wakeup = timespec_add (current_timespec (), delay);
3856 /* Keep waiting until past the time wakeup or any input gets
3857 available. */
3858 while (! detect_input_pending ())
3860 struct timespec current = current_timespec ();
3861 struct timespec timeout;
3863 /* Break if result would not be positive. */
3864 if (timespec_cmp (wakeup, current) <= 0)
3865 break;
3867 /* How long `select' should wait. */
3868 timeout = make_timespec (0, 10 * 1000 * 1000);
3870 /* Try to wait that long--but we might wake up sooner. */
3871 pselect (0, NULL, NULL, NULL, &timeout, NULL);
3875 /* If window is tall, flash top and bottom line. */
3876 if (height > 3 * FRAME_LINE_HEIGHT (f))
3878 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3879 flash_left,
3880 (FRAME_INTERNAL_BORDER_WIDTH (f)
3881 + FRAME_TOP_MARGIN_HEIGHT (f)),
3882 width, flash_height);
3883 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3884 flash_left,
3885 (height - flash_height
3886 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3887 width, flash_height);
3889 else
3890 /* If it is short, flash it all. */
3891 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
3892 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3893 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3895 #ifdef USE_GTK
3896 #ifdef HAVE_GTK3
3897 cairo_destroy (cr);
3898 #else
3899 g_object_unref (G_OBJECT (gc));
3900 #endif
3901 #undef XFillRectangle
3902 #else
3903 XFreeGC (FRAME_X_DISPLAY (f), gc);
3904 #endif
3905 x_flush (f);
3909 unblock_input ();
3913 static void
3914 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
3916 block_input ();
3917 FRAME_DISPLAY_INFO (f)->toggle_visible_pointer (f, invisible);
3918 unblock_input ();
3922 /* Make audible bell. */
3924 static void
3925 XTring_bell (struct frame *f)
3927 if (FRAME_X_DISPLAY (f))
3929 if (visible_bell)
3930 XTflash (f);
3931 else
3933 block_input ();
3934 #ifdef HAVE_XKB
3935 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
3936 #else
3937 XBell (FRAME_X_DISPLAY (f), 0);
3938 #endif
3939 XFlush (FRAME_X_DISPLAY (f));
3940 unblock_input ();
3945 /***********************************************************************
3946 Line Dance
3947 ***********************************************************************/
3949 /* Perform an insert-lines or delete-lines operation, inserting N
3950 lines or deleting -N lines at vertical position VPOS. */
3952 static void
3953 x_ins_del_lines (struct frame *f, int vpos, int n)
3955 emacs_abort ();
3959 /* Scroll part of the display as described by RUN. */
3961 static void
3962 x_scroll_run (struct window *w, struct run *run)
3964 struct frame *f = XFRAME (w->frame);
3965 int x, y, width, height, from_y, to_y, bottom_y;
3967 /* Get frame-relative bounding box of the text display area of W,
3968 without mode lines. Include in this box the left and right
3969 fringe of W. */
3970 window_box (w, ANY_AREA, &x, &y, &width, &height);
3972 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
3973 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
3974 bottom_y = y + height;
3976 if (to_y < from_y)
3978 /* Scrolling up. Make sure we don't copy part of the mode
3979 line at the bottom. */
3980 if (from_y + run->height > bottom_y)
3981 height = bottom_y - from_y;
3982 else
3983 height = run->height;
3985 else
3987 /* Scrolling down. Make sure we don't copy over the mode line.
3988 at the bottom. */
3989 if (to_y + run->height > bottom_y)
3990 height = bottom_y - to_y;
3991 else
3992 height = run->height;
3995 block_input ();
3997 /* Cursor off. Will be switched on again in x_update_window_end. */
3998 x_clear_cursor (w);
4000 #ifdef USE_CAIRO
4001 SET_FRAME_GARBAGED (f);
4002 #else
4003 XCopyArea (FRAME_X_DISPLAY (f),
4004 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
4005 f->output_data.x->normal_gc,
4006 x, from_y,
4007 width, height,
4008 x, to_y);
4009 #endif
4011 unblock_input ();
4015 \f
4016 /***********************************************************************
4017 Exposure Events
4018 ***********************************************************************/
4020 \f
4021 static void
4022 frame_highlight (struct frame *f)
4024 /* We used to only do this if Vx_no_window_manager was non-nil, but
4025 the ICCCM (section 4.1.6) says that the window's border pixmap
4026 and border pixel are window attributes which are "private to the
4027 client", so we can always change it to whatever we want. */
4028 block_input ();
4029 /* I recently started to get errors in this XSetWindowBorder, depending on
4030 the window-manager in use, tho something more is at play since I've been
4031 using that same window-manager binary for ever. Let's not crash just
4032 because of this (bug#9310). */
4033 x_catch_errors (FRAME_X_DISPLAY (f));
4034 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4035 f->output_data.x->border_pixel);
4036 x_uncatch_errors ();
4037 unblock_input ();
4038 x_update_cursor (f, true);
4039 x_set_frame_alpha (f);
4042 static void
4043 frame_unhighlight (struct frame *f)
4045 /* We used to only do this if Vx_no_window_manager was non-nil, but
4046 the ICCCM (section 4.1.6) says that the window's border pixmap
4047 and border pixel are window attributes which are "private to the
4048 client", so we can always change it to whatever we want. */
4049 block_input ();
4050 /* Same as above for XSetWindowBorder (bug#9310). */
4051 x_catch_errors (FRAME_X_DISPLAY (f));
4052 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4053 f->output_data.x->border_tile);
4054 x_uncatch_errors ();
4055 unblock_input ();
4056 x_update_cursor (f, true);
4057 x_set_frame_alpha (f);
4060 /* The focus has changed. Update the frames as necessary to reflect
4061 the new situation. Note that we can't change the selected frame
4062 here, because the Lisp code we are interrupting might become confused.
4063 Each event gets marked with the frame in which it occurred, so the
4064 Lisp code can tell when the switch took place by examining the events. */
4066 static void
4067 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
4069 struct frame *old_focus = dpyinfo->x_focus_frame;
4071 if (frame != dpyinfo->x_focus_frame)
4073 /* Set this before calling other routines, so that they see
4074 the correct value of x_focus_frame. */
4075 dpyinfo->x_focus_frame = frame;
4077 if (old_focus && old_focus->auto_lower)
4078 x_lower_frame (old_focus);
4080 if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
4081 dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
4082 else
4083 dpyinfo->x_pending_autoraise_frame = NULL;
4086 x_frame_rehighlight (dpyinfo);
4089 /* Handle FocusIn and FocusOut state changes for FRAME.
4090 If FRAME has focus and there exists more than one frame, puts
4091 a FOCUS_IN_EVENT into *BUFP. */
4093 static void
4094 x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct frame *frame, struct input_event *bufp)
4096 if (type == FocusIn)
4098 if (dpyinfo->x_focus_event_frame != frame)
4100 x_new_focus_frame (dpyinfo, frame);
4101 dpyinfo->x_focus_event_frame = frame;
4103 /* Don't stop displaying the initial startup message
4104 for a switch-frame event we don't need. */
4105 /* When run as a daemon, Vterminal_frame is always NIL. */
4106 bufp->arg = (((NILP (Vterminal_frame)
4107 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4108 || EQ (Fdaemonp (), Qt))
4109 && CONSP (Vframe_list)
4110 && !NILP (XCDR (Vframe_list)))
4111 ? Qt : Qnil);
4112 bufp->kind = FOCUS_IN_EVENT;
4113 XSETFRAME (bufp->frame_or_window, frame);
4116 frame->output_data.x->focus_state |= state;
4118 #ifdef HAVE_X_I18N
4119 if (FRAME_XIC (frame))
4120 XSetICFocus (FRAME_XIC (frame));
4121 #endif
4123 else if (type == FocusOut)
4125 frame->output_data.x->focus_state &= ~state;
4127 if (dpyinfo->x_focus_event_frame == frame)
4129 dpyinfo->x_focus_event_frame = 0;
4130 x_new_focus_frame (dpyinfo, 0);
4132 bufp->kind = FOCUS_OUT_EVENT;
4133 XSETFRAME (bufp->frame_or_window, frame);
4136 #ifdef HAVE_X_I18N
4137 if (FRAME_XIC (frame))
4138 XUnsetICFocus (FRAME_XIC (frame));
4139 #endif
4140 if (frame->pointer_invisible)
4141 XTtoggle_invisible_pointer (frame, false);
4145 /* Return the Emacs frame-object corresponding to an X window.
4146 It could be the frame's main window or an icon window. */
4148 static struct frame *
4149 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4151 Lisp_Object tail, frame;
4152 struct frame *f;
4154 if (wdesc == None)
4155 return NULL;
4157 FOR_EACH_FRAME (tail, frame)
4159 f = XFRAME (frame);
4160 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4161 continue;
4162 if (f->output_data.x->hourglass_window == wdesc)
4163 return f;
4164 #ifdef USE_X_TOOLKIT
4165 if ((f->output_data.x->edit_widget
4166 && XtWindow (f->output_data.x->edit_widget) == wdesc)
4167 /* A tooltip frame? */
4168 || (!f->output_data.x->edit_widget
4169 && FRAME_X_WINDOW (f) == wdesc)
4170 || f->output_data.x->icon_desc == wdesc)
4171 return f;
4172 #else /* not USE_X_TOOLKIT */
4173 #ifdef USE_GTK
4174 if (f->output_data.x->edit_widget)
4176 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4177 struct x_output *x = f->output_data.x;
4178 if (gwdesc != 0 && gwdesc == x->edit_widget)
4179 return f;
4181 #endif /* USE_GTK */
4182 if (FRAME_X_WINDOW (f) == wdesc
4183 || f->output_data.x->icon_desc == wdesc)
4184 return f;
4185 #endif /* not USE_X_TOOLKIT */
4187 return 0;
4190 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
4192 /* Like x_window_to_frame but also compares the window with the widget's
4193 windows. */
4195 static struct frame *
4196 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4198 Lisp_Object tail, frame;
4199 struct frame *f, *found = NULL;
4200 struct x_output *x;
4202 if (wdesc == None)
4203 return NULL;
4205 FOR_EACH_FRAME (tail, frame)
4207 if (found)
4208 break;
4209 f = XFRAME (frame);
4210 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
4212 /* This frame matches if the window is any of its widgets. */
4213 x = f->output_data.x;
4214 if (x->hourglass_window == wdesc)
4215 found = f;
4216 else if (x->widget)
4218 #ifdef USE_GTK
4219 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4220 if (gwdesc != 0
4221 && gtk_widget_get_toplevel (gwdesc) == x->widget)
4222 found = f;
4223 #else
4224 if (wdesc == XtWindow (x->widget)
4225 || wdesc == XtWindow (x->column_widget)
4226 || wdesc == XtWindow (x->edit_widget))
4227 found = f;
4228 /* Match if the window is this frame's menubar. */
4229 else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
4230 found = f;
4231 #endif
4233 else if (FRAME_X_WINDOW (f) == wdesc)
4234 /* A tooltip frame. */
4235 found = f;
4239 return found;
4242 /* Likewise, but consider only the menu bar widget. */
4244 static struct frame *
4245 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
4246 const XEvent *event)
4248 Window wdesc = event->xany.window;
4249 Lisp_Object tail, frame;
4250 struct frame *f;
4251 struct x_output *x;
4253 if (wdesc == None)
4254 return NULL;
4256 FOR_EACH_FRAME (tail, frame)
4258 f = XFRAME (frame);
4259 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4260 continue;
4261 x = f->output_data.x;
4262 #ifdef USE_GTK
4263 if (x->menubar_widget && xg_event_is_for_menubar (f, event))
4264 return f;
4265 #else
4266 /* Match if the window is this frame's menubar. */
4267 if (x->menubar_widget
4268 && lw_window_is_in_menubar (wdesc, x->menubar_widget))
4269 return f;
4270 #endif
4272 return 0;
4275 /* Return the frame whose principal (outermost) window is WDESC.
4276 If WDESC is some other (smaller) window, we return 0. */
4278 struct frame *
4279 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
4281 Lisp_Object tail, frame;
4282 struct frame *f;
4283 struct x_output *x;
4285 if (wdesc == None)
4286 return NULL;
4288 FOR_EACH_FRAME (tail, frame)
4290 f = XFRAME (frame);
4291 if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
4292 continue;
4293 x = f->output_data.x;
4295 if (x->widget)
4297 /* This frame matches if the window is its topmost widget. */
4298 #ifdef USE_GTK
4299 GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
4300 if (gwdesc == x->widget)
4301 return f;
4302 #else
4303 if (wdesc == XtWindow (x->widget))
4304 return f;
4305 #endif
4307 else if (FRAME_X_WINDOW (f) == wdesc)
4308 /* Tooltip frame. */
4309 return f;
4311 return 0;
4314 #else /* !USE_X_TOOLKIT && !USE_GTK */
4316 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
4317 #define x_top_window_to_frame(d, i) x_window_to_frame (d, i)
4319 #endif /* USE_X_TOOLKIT || USE_GTK */
4321 /* The focus may have changed. Figure out if it is a real focus change,
4322 by checking both FocusIn/Out and Enter/LeaveNotify events.
4324 Returns FOCUS_IN_EVENT event in *BUFP. */
4326 static void
4327 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
4328 const XEvent *event, struct input_event *bufp)
4330 if (!frame)
4331 return;
4333 switch (event->type)
4335 case EnterNotify:
4336 case LeaveNotify:
4338 struct frame *focus_frame = dpyinfo->x_focus_event_frame;
4339 int focus_state
4340 = focus_frame ? focus_frame->output_data.x->focus_state : 0;
4342 if (event->xcrossing.detail != NotifyInferior
4343 && event->xcrossing.focus
4344 && ! (focus_state & FOCUS_EXPLICIT))
4345 x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
4346 FOCUS_IMPLICIT,
4347 dpyinfo, frame, bufp);
4349 break;
4351 case FocusIn:
4352 case FocusOut:
4353 x_focus_changed (event->type,
4354 (event->xfocus.detail == NotifyPointer ?
4355 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
4356 dpyinfo, frame, bufp);
4357 break;
4359 case ClientMessage:
4360 if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
4362 enum xembed_message msg = event->xclient.data.l[1];
4363 x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
4364 FOCUS_EXPLICIT, dpyinfo, frame, bufp);
4366 break;
4371 #if !defined USE_X_TOOLKIT && !defined USE_GTK
4372 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4374 void
4375 x_mouse_leave (struct x_display_info *dpyinfo)
4377 x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
4379 #endif
4381 /* The focus has changed, or we have redirected a frame's focus to
4382 another frame (this happens when a frame uses a surrogate
4383 mini-buffer frame). Shift the highlight as appropriate.
4385 The FRAME argument doesn't necessarily have anything to do with which
4386 frame is being highlighted or un-highlighted; we only use it to find
4387 the appropriate X display info. */
4389 static void
4390 XTframe_rehighlight (struct frame *frame)
4392 x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
4395 static void
4396 x_frame_rehighlight (struct x_display_info *dpyinfo)
4398 struct frame *old_highlight = dpyinfo->x_highlight_frame;
4400 if (dpyinfo->x_focus_frame)
4402 dpyinfo->x_highlight_frame
4403 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
4404 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
4405 : dpyinfo->x_focus_frame);
4406 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
4408 fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
4409 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
4412 else
4413 dpyinfo->x_highlight_frame = 0;
4415 if (dpyinfo->x_highlight_frame != old_highlight)
4417 if (old_highlight)
4418 frame_unhighlight (old_highlight);
4419 if (dpyinfo->x_highlight_frame)
4420 frame_highlight (dpyinfo->x_highlight_frame);
4425 \f
4426 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
4428 /* Initialize mode_switch_bit and modifier_meaning. */
4429 static void
4430 x_find_modifier_meanings (struct x_display_info *dpyinfo)
4432 int min_code, max_code;
4433 KeySym *syms;
4434 int syms_per_code;
4435 XModifierKeymap *mods;
4437 dpyinfo->meta_mod_mask = 0;
4438 dpyinfo->shift_lock_mask = 0;
4439 dpyinfo->alt_mod_mask = 0;
4440 dpyinfo->super_mod_mask = 0;
4441 dpyinfo->hyper_mod_mask = 0;
4443 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
4445 syms = XGetKeyboardMapping (dpyinfo->display,
4446 min_code, max_code - min_code + 1,
4447 &syms_per_code);
4448 mods = XGetModifierMapping (dpyinfo->display);
4450 /* Scan the modifier table to see which modifier bits the Meta and
4451 Alt keysyms are on. */
4453 int row, col; /* The row and column in the modifier table. */
4454 bool found_alt_or_meta;
4456 for (row = 3; row < 8; row++)
4458 found_alt_or_meta = false;
4459 for (col = 0; col < mods->max_keypermod; col++)
4461 KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
4463 /* Zeroes are used for filler. Skip them. */
4464 if (code == 0)
4465 continue;
4467 /* Are any of this keycode's keysyms a meta key? */
4469 int code_col;
4471 for (code_col = 0; code_col < syms_per_code; code_col++)
4473 int sym = syms[((code - min_code) * syms_per_code) + code_col];
4475 switch (sym)
4477 case XK_Meta_L:
4478 case XK_Meta_R:
4479 found_alt_or_meta = true;
4480 dpyinfo->meta_mod_mask |= (1 << row);
4481 break;
4483 case XK_Alt_L:
4484 case XK_Alt_R:
4485 found_alt_or_meta = true;
4486 dpyinfo->alt_mod_mask |= (1 << row);
4487 break;
4489 case XK_Hyper_L:
4490 case XK_Hyper_R:
4491 if (!found_alt_or_meta)
4492 dpyinfo->hyper_mod_mask |= (1 << row);
4493 code_col = syms_per_code;
4494 col = mods->max_keypermod;
4495 break;
4497 case XK_Super_L:
4498 case XK_Super_R:
4499 if (!found_alt_or_meta)
4500 dpyinfo->super_mod_mask |= (1 << row);
4501 code_col = syms_per_code;
4502 col = mods->max_keypermod;
4503 break;
4505 case XK_Shift_Lock:
4506 /* Ignore this if it's not on the lock modifier. */
4507 if (!found_alt_or_meta && ((1 << row) == LockMask))
4508 dpyinfo->shift_lock_mask = LockMask;
4509 code_col = syms_per_code;
4510 col = mods->max_keypermod;
4511 break;
4519 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4520 if (! dpyinfo->meta_mod_mask)
4522 dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
4523 dpyinfo->alt_mod_mask = 0;
4526 /* If some keys are both alt and meta,
4527 make them just meta, not alt. */
4528 if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
4530 dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
4533 XFree (syms);
4534 XFreeModifiermap (mods);
4537 /* Convert between the modifier bits X uses and the modifier bits
4538 Emacs uses. */
4540 int
4541 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
4543 int mod_meta = meta_modifier;
4544 int mod_alt = alt_modifier;
4545 int mod_hyper = hyper_modifier;
4546 int mod_super = super_modifier;
4547 Lisp_Object tem;
4549 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4550 if (INTEGERP (tem)) mod_alt = XINT (tem) & INT_MAX;
4551 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4552 if (INTEGERP (tem)) mod_meta = XINT (tem) & INT_MAX;
4553 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4554 if (INTEGERP (tem)) mod_hyper = XINT (tem) & INT_MAX;
4555 tem = Fget (Vx_super_keysym, Qmodifier_value);
4556 if (INTEGERP (tem)) mod_super = XINT (tem) & INT_MAX;
4558 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
4559 | ((state & ControlMask) ? ctrl_modifier : 0)
4560 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
4561 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
4562 | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
4563 | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
4566 static int
4567 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, EMACS_INT state)
4569 EMACS_INT mod_meta = meta_modifier;
4570 EMACS_INT mod_alt = alt_modifier;
4571 EMACS_INT mod_hyper = hyper_modifier;
4572 EMACS_INT mod_super = super_modifier;
4574 Lisp_Object tem;
4576 tem = Fget (Vx_alt_keysym, Qmodifier_value);
4577 if (INTEGERP (tem)) mod_alt = XINT (tem);
4578 tem = Fget (Vx_meta_keysym, Qmodifier_value);
4579 if (INTEGERP (tem)) mod_meta = XINT (tem);
4580 tem = Fget (Vx_hyper_keysym, Qmodifier_value);
4581 if (INTEGERP (tem)) mod_hyper = XINT (tem);
4582 tem = Fget (Vx_super_keysym, Qmodifier_value);
4583 if (INTEGERP (tem)) mod_super = XINT (tem);
4586 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0)
4587 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0)
4588 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0)
4589 | ((state & shift_modifier) ? ShiftMask : 0)
4590 | ((state & ctrl_modifier) ? ControlMask : 0)
4591 | ((state & mod_meta) ? dpyinfo->meta_mod_mask : 0));
4594 /* Convert a keysym to its name. */
4596 char *
4597 x_get_keysym_name (int keysym)
4599 char *value;
4601 block_input ();
4602 value = XKeysymToString (keysym);
4603 unblock_input ();
4605 return value;
4608 /* Mouse clicks and mouse movement. Rah.
4610 Formerly, we used PointerMotionHintMask (in standard_event_mask)
4611 so that we would have to call XQueryPointer after each MotionNotify
4612 event to ask for another such event. However, this made mouse tracking
4613 slow, and there was a bug that made it eventually stop.
4615 Simply asking for MotionNotify all the time seems to work better.
4617 In order to avoid asking for motion events and then throwing most
4618 of them away or busy-polling the server for mouse positions, we ask
4619 the server for pointer motion hints. This means that we get only
4620 one event per group of mouse movements. "Groups" are delimited by
4621 other kinds of events (focus changes and button clicks, for
4622 example), or by XQueryPointer calls; when one of these happens, we
4623 get another MotionNotify event the next time the mouse moves. This
4624 is at least as efficient as getting motion events when mouse
4625 tracking is on, and I suspect only negligibly worse when tracking
4626 is off. */
4628 /* Prepare a mouse-event in *RESULT for placement in the input queue.
4630 If the event is a button press, then note that we have grabbed
4631 the mouse. */
4633 static Lisp_Object
4634 construct_mouse_click (struct input_event *result,
4635 const XButtonEvent *event,
4636 struct frame *f)
4638 /* Make the event type NO_EVENT; we'll change that when we decide
4639 otherwise. */
4640 result->kind = MOUSE_CLICK_EVENT;
4641 result->code = event->button - Button1;
4642 result->timestamp = event->time;
4643 result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
4644 event->state)
4645 | (event->type == ButtonRelease
4646 ? up_modifier
4647 : down_modifier));
4649 XSETINT (result->x, event->x);
4650 XSETINT (result->y, event->y);
4651 XSETFRAME (result->frame_or_window, f);
4652 result->arg = Qnil;
4653 return Qnil;
4656 /* Function to report a mouse movement to the mainstream Emacs code.
4657 The input handler calls this.
4659 We have received a mouse movement event, which is given in *event.
4660 If the mouse is over a different glyph than it was last time, tell
4661 the mainstream emacs code by setting mouse_moved. If not, ask for
4662 another motion event, so we can check again the next time it moves. */
4664 static bool
4665 note_mouse_movement (struct frame *frame, const XMotionEvent *event)
4667 XRectangle *r;
4668 struct x_display_info *dpyinfo;
4670 if (!FRAME_X_OUTPUT (frame))
4671 return false;
4673 dpyinfo = FRAME_DISPLAY_INFO (frame);
4674 dpyinfo->last_mouse_movement_time = event->time;
4675 dpyinfo->last_mouse_motion_frame = frame;
4676 dpyinfo->last_mouse_motion_x = event->x;
4677 dpyinfo->last_mouse_motion_y = event->y;
4679 if (event->window != FRAME_X_WINDOW (frame))
4681 frame->mouse_moved = true;
4682 dpyinfo->last_mouse_scroll_bar = NULL;
4683 note_mouse_highlight (frame, -1, -1);
4684 dpyinfo->last_mouse_glyph_frame = NULL;
4685 return true;
4689 /* Has the mouse moved off the glyph it was on at the last sighting? */
4690 r = &dpyinfo->last_mouse_glyph;
4691 if (frame != dpyinfo->last_mouse_glyph_frame
4692 || event->x < r->x || event->x >= r->x + r->width
4693 || event->y < r->y || event->y >= r->y + r->height)
4695 frame->mouse_moved = true;
4696 dpyinfo->last_mouse_scroll_bar = NULL;
4697 note_mouse_highlight (frame, event->x, event->y);
4698 /* Remember which glyph we're now on. */
4699 remember_mouse_glyph (frame, event->x, event->y, r);
4700 dpyinfo->last_mouse_glyph_frame = frame;
4701 return true;
4704 return false;
4707 /* Return the current position of the mouse.
4708 *FP should be a frame which indicates which display to ask about.
4710 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4711 and *PART to the frame, window, and scroll bar part that the mouse
4712 is over. Set *X and *Y to the portion and whole of the mouse's
4713 position on the scroll bar.
4715 If the mouse movement started elsewhere, set *FP to the frame the