aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorJan D2015-05-23 12:34:45 +0200
committerJan D2015-05-23 12:34:45 +0200
commitc03c730481bd2dc7bc857d9b4f1c41eea9bd495e (patch)
treea34eb6ad435ab877848f7464374570549ca55ec5 /src/xterm.c
parent7ac84a2570e1268cc040fcd529508307b2b22c01 (diff)
parent6aaa489dc112f51f6045f79b37cb78dd513e398f (diff)
downloademacs-c03c730481bd2dc7bc857d9b4f1c41eea9bd495e.tar.gz
emacs-c03c730481bd2dc7bc857d9b4f1c41eea9bd495e.zip
Merge branch 'cairo'.
Main work done by YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>. Small fixes and image work by Jan D. <jan.h.d@swipnet.se>.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c998
1 files changed, 903 insertions, 95 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 06ce7070bca..3734fbfee92 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 22
23#include <config.h> 23#include <config.h>
24#include <stdio.h> 24#include <stdio.h>
25#ifdef USE_CAIRO
26#include <math.h>
27#endif
25 28
26#include "lisp.h" 29#include "lisp.h"
27#include "blockinput.h" 30#include "blockinput.h"
@@ -220,6 +223,7 @@ static int x_io_error_quitter (Display *);
220static struct terminal *x_create_terminal (struct x_display_info *); 223static struct terminal *x_create_terminal (struct x_display_info *);
221static void x_update_end (struct frame *); 224static void x_update_end (struct frame *);
222static void XTframe_up_to_date (struct frame *); 225static void XTframe_up_to_date (struct frame *);
226static void x_clear_area1 (Display *, Window, int, int, int, int, int);
223static void x_clear_frame (struct frame *); 227static void x_clear_frame (struct frame *);
224static _Noreturn void x_ins_del_lines (struct frame *, int, int); 228static _Noreturn void x_ins_del_lines (struct frame *, int, int);
225static void frame_highlight (struct frame *); 229static void frame_highlight (struct frame *);
@@ -325,6 +329,587 @@ record_event (char *locus, int type)
325 329
326#endif 330#endif
327 331
332static void x_free_cr_resources (struct frame *);
333static void x_set_clip_rectangles (struct frame *, GC, XRectangle *, int);
334static void x_reset_clip_rectangles (struct frame *, GC);
335static void x_fill_rectangle (struct frame *, GC, int, int, int, int);
336static void x_draw_rectangle (struct frame *, GC, int, int, int, int);
337static void x_fill_trapezoid_for_relief (struct frame *, GC, int, int,
338 int, int, int);
339static void x_clear_window (struct frame *);
340
341#ifdef USE_CAIRO
342static struct x_gc_ext_data *x_gc_get_ext_data (struct frame *, GC, int);
343static void x_extension_initialize (struct x_display_info *);
344static cairo_status_t x_cr_accumulate_data (void *,
345 const unsigned char *,
346 unsigned int);
347
348#define FRAME_CR_CONTEXT(f) ((f)->output_data.x->cr_context)
349#define FRAME_CR_SURFACE(f) ((f)->output_data.x->cr_surface)
350
351static struct x_gc_ext_data *
352x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
353{
354 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
355 XEDataObject object;
356 XExtData **head, *ext_data;
357
358 object.gc = gc;
359 head = XEHeadOfExtensionList (object);
360 ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
361 if (ext_data == NULL)
362 {
363 if (!create_if_not_found_p)
364 return NULL;
365 else
366 {
367 ext_data = xzalloc (sizeof (*ext_data));
368 ext_data->number = dpyinfo->ext_codes->extension;
369 ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
370 XAddToExtensionList (head, ext_data);
371 }
372 }
373 return (struct x_gc_ext_data *) ext_data->private_data;
374}
375
376static void
377x_extension_initialize (struct x_display_info *dpyinfo)
378{
379 XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
380
381 dpyinfo->ext_codes = ext_codes;
382}
383
384static void
385x_cr_destroy_surface (struct frame *f)
386{
387 if (FRAME_CR_SURFACE (f))
388 {
389 cairo_t *cr = FRAME_CR_CONTEXT (f);
390 cairo_surface_destroy (FRAME_CR_SURFACE (f));
391 FRAME_CR_SURFACE (f) = 0;
392 if (cr) cairo_destroy (cr);
393 FRAME_CR_CONTEXT (f) = NULL;
394 }
395}
396
397cairo_t *
398x_begin_cr_clip (struct frame *f, GC gc)
399{
400 cairo_t *cr = FRAME_CR_CONTEXT (f);
401
402 if (!cr)
403 {
404
405 if (! FRAME_CR_SURFACE (f))
406 {
407 cairo_surface_t *surface;
408 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
409 FRAME_X_WINDOW (f),
410 FRAME_DISPLAY_INFO (f)->visual,
411 FRAME_PIXEL_WIDTH (f),
412 FRAME_PIXEL_HEIGHT (f));
413 cr = cairo_create (surface);
414 cairo_surface_destroy (surface);
415 }
416 else
417 cr = cairo_create (FRAME_CR_SURFACE (f));
418 FRAME_CR_CONTEXT (f) = cr;
419 }
420 cairo_save (cr);
421
422 if (gc)
423 {
424 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
425
426 if (gc_ext && gc_ext->n_clip_rects)
427 {
428 int i;
429
430 for (i = 0; i < gc_ext->n_clip_rects; i++)
431 cairo_rectangle (cr, gc_ext->clip_rects[i].x,
432 gc_ext->clip_rects[i].y,
433 gc_ext->clip_rects[i].width,
434 gc_ext->clip_rects[i].height);
435 cairo_clip (cr);
436 }
437 }
438
439 return cr;
440}
441
442void
443x_end_cr_clip (struct frame *f)
444{
445 cairo_restore (FRAME_CR_CONTEXT (f));
446}
447
448void
449x_set_cr_source_with_gc_foreground (struct frame *f, GC gc)
450{
451 XGCValues xgcv;
452 XColor color;
453
454 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
455 color.pixel = xgcv.foreground;
456 x_query_color (f, &color);
457 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
458 color.green / 65535.0, color.blue / 65535.0);
459}
460
461void
462x_set_cr_source_with_gc_background (struct frame *f, GC gc)
463{
464 XGCValues xgcv;
465 XColor color;
466
467 XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
468 color.pixel = xgcv.background;
469 x_query_color (f, &color);
470 cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
471 color.green / 65535.0, color.blue / 65535.0);
472}
473
474/* Fringe bitmaps. */
475
476static int max_fringe_bmp = 0;
477static cairo_pattern_t **fringe_bmp = 0;
478
479static void
480x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
481{
482 int i, stride;
483 cairo_surface_t *surface;
484 unsigned char *data;
485 cairo_pattern_t *pattern;
486
487 if (which >= max_fringe_bmp)
488 {
489 i = max_fringe_bmp;
490 max_fringe_bmp = which + 20;
491 fringe_bmp = (cairo_pattern_t **) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (cairo_pattern_t *));
492 while (i < max_fringe_bmp)
493 fringe_bmp[i++] = 0;
494 }
495
496 block_input ();
497
498 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
499 stride = cairo_image_surface_get_stride (surface);
500 data = cairo_image_surface_get_data (surface);
501
502 for (i = 0; i < h; i++)
503 {
504 *((unsigned short *) data) = bits[i];
505 data += stride;
506 }
507
508 cairo_surface_mark_dirty (surface);
509 pattern = cairo_pattern_create_for_surface (surface);
510 cairo_surface_destroy (surface);
511
512 unblock_input ();
513
514 fringe_bmp[which] = pattern;
515}
516
517static void
518x_cr_destroy_fringe_bitmap (int which)
519{
520 if (which >= max_fringe_bmp)
521 return;
522
523 if (fringe_bmp[which])
524 {
525 block_input ();
526 cairo_pattern_destroy (fringe_bmp[which]);
527 unblock_input ();
528 }
529 fringe_bmp[which] = 0;
530}
531
532static void
533x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
534 int src_x, int src_y, int width, int height,
535 int dest_x, int dest_y, bool overlay_p)
536{
537 cairo_t *cr;
538 cairo_matrix_t matrix;
539 cairo_surface_t *surface;
540 cairo_format_t format;
541
542 cr = x_begin_cr_clip (f, gc);
543 if (overlay_p)
544 cairo_rectangle (cr, dest_x, dest_y, width, height);
545 else
546 {
547 x_set_cr_source_with_gc_background (f, gc);
548 cairo_rectangle (cr, dest_x, dest_y, width, height);
549 cairo_fill_preserve (cr);
550 }
551 cairo_clip (cr);
552 cairo_matrix_init_translate (&matrix, src_x - dest_x, src_y - dest_y);
553 cairo_pattern_set_matrix (image, &matrix);
554 cairo_pattern_get_surface (image, &surface);
555 format = cairo_image_surface_get_format (surface);
556 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
557 {
558 cairo_set_source (cr, image);
559 cairo_fill (cr);
560 }
561 else
562 {
563 x_set_cr_source_with_gc_foreground (f, gc);
564 cairo_mask (cr, image);
565 }
566 x_end_cr_clip (f);
567}
568
569void
570x_cr_draw_frame (cairo_t *cr, struct frame *f)
571{
572 int width, height;
573
574 width = FRAME_PIXEL_WIDTH (f);
575 height = FRAME_PIXEL_HEIGHT (f);
576
577 x_free_cr_resources (f);
578 FRAME_CR_CONTEXT (f) = cr;
579 x_clear_area (f, 0, 0, width, height);
580 expose_frame (f, 0, 0, width, height);
581 FRAME_CR_CONTEXT (f) = NULL;
582}
583
584static cairo_status_t
585x_cr_accumulate_data (void *closure, const unsigned char *data,
586 unsigned int length)
587{
588 Lisp_Object *acc = (Lisp_Object *) closure;
589
590 *acc = Fcons (make_unibyte_string (data, length), *acc);
591
592 return CAIRO_STATUS_SUCCESS;
593}
594
595static void
596x_cr_destroy (Lisp_Object arg)
597{
598 cairo_t *cr = (cairo_t *) XSAVE_POINTER (arg, 0);
599
600 block_input ();
601 cairo_destroy (cr);
602 unblock_input ();
603}
604
605Lisp_Object
606x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
607{
608 struct frame *f;
609 cairo_surface_t *surface;
610 cairo_t *cr;
611 int width, height;
612 void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
613 Lisp_Object acc = Qnil, args[2];
614 int count = SPECPDL_INDEX ();
615
616 Fredisplay (Qt);
617
618 f = XFRAME (XCAR (frames));
619 frames = XCDR (frames);
620 width = FRAME_PIXEL_WIDTH (f);
621 height = FRAME_PIXEL_HEIGHT (f);
622
623 block_input ();
624#ifdef CAIRO_HAS_PDF_SURFACE
625 if (surface_type == CAIRO_SURFACE_TYPE_PDF)
626 {
627 surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
628 width, height);
629 surface_set_size_func = cairo_pdf_surface_set_size;
630 }
631 else
632#endif
633#ifdef CAIRO_HAS_PNG_FUNCTIONS
634 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
635 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
636 else
637#endif
638#ifdef CAIRO_HAS_PS_SURFACE
639 if (surface_type == CAIRO_SURFACE_TYPE_PS)
640 {
641 surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
642 width, height);
643 surface_set_size_func = cairo_ps_surface_set_size;
644 }
645 else
646#endif
647#ifdef CAIRO_HAS_SVG_SURFACE
648 if (surface_type == CAIRO_SURFACE_TYPE_SVG)
649 surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
650 width, height);
651 else
652#endif
653 abort ();
654
655 cr = cairo_create (surface);
656 cairo_surface_destroy (surface);
657 record_unwind_protect (x_cr_destroy, make_save_ptr (cr));
658 unblock_input ();
659
660 while (1)
661 {
662 QUIT;
663
664 block_input ();
665 x_free_cr_resources (f);
666 FRAME_CR_CONTEXT (f) = cr;
667 x_clear_area (f, 0, 0, width, height);
668 expose_frame (f, 0, 0, width, height);
669 FRAME_CR_CONTEXT (f) = NULL;
670 unblock_input ();
671
672 if (NILP (frames))
673 break;
674
675 block_input ();
676 cairo_surface_show_page (surface);
677 f = XFRAME (XCAR (frames));
678 frames = XCDR (frames);
679 width = FRAME_PIXEL_WIDTH (f);
680 height = FRAME_PIXEL_HEIGHT (f);
681 if (surface_set_size_func)
682 (*surface_set_size_func) (surface, width, height);
683 unblock_input ();
684 }
685
686#ifdef CAIRO_HAS_PNG_FUNCTIONS
687 if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
688 {
689 block_input ();
690 cairo_surface_flush (surface);
691 cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
692 unblock_input ();
693 }
694#endif
695 unbind_to (count, Qnil);
696
697 args[0] = intern ("concat");
698 args[1] = Fnreverse (acc);
699 return Fapply (2, args);
700}
701
702#endif /* USE_CAIRO */
703
704static void
705x_free_cr_resources (struct frame *f)
706{
707#ifdef USE_CAIRO
708 if (f == NULL)
709 {
710 Lisp_Object rest, frame;
711 FOR_EACH_FRAME (rest, frame)
712 if (FRAME_X_P (XFRAME (frame)))
713 x_free_cr_resources (XFRAME (frame));
714 }
715 else
716 {
717 cairo_t *cr = FRAME_CR_CONTEXT (f);
718
719 if (cr)
720 {
721 cairo_surface_t *surface = cairo_get_target (cr);
722
723 if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
724 {
725 cairo_destroy (cr);
726 FRAME_CR_CONTEXT (f) = NULL;
727 }
728 }
729 }
730#endif
731}
732
733static void
734x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
735{
736 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
737#ifdef USE_CAIRO
738 eassert (n >= 0 && n <= MAX_CLIP_RECTS);
739
740 {
741 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
742
743 gc_ext->n_clip_rects = n;
744 memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
745 }
746#endif
747}
748
749static void
750x_reset_clip_rectangles (struct frame *f, GC gc)
751{
752 XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
753#ifdef USE_CAIRO
754 {
755 struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
756
757 if (gc_ext)
758 gc_ext->n_clip_rects = 0;
759 }
760#endif
761}
762
763static void
764x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
765{
766#ifdef USE_CAIRO
767 cairo_t *cr;
768
769 cr = x_begin_cr_clip (f, gc);
770 x_set_cr_source_with_gc_foreground (f, gc);
771 cairo_rectangle (cr, x, y, width, height);
772 cairo_fill (cr);
773 x_end_cr_clip (f);
774#else
775 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
776 gc, x, y, width, height);
777#endif
778}
779
780static void
781x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
782{
783#ifdef USE_CAIRO
784 cairo_t *cr;
785
786 cr = x_begin_cr_clip (f, gc);
787 x_set_cr_source_with_gc_foreground (f, gc);
788 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
789 cairo_set_line_width (cr, 1);
790 cairo_stroke (cr);
791 x_end_cr_clip (f);
792#else
793 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
794 gc, x, y, width, height);
795#endif
796}
797
798static void
799x_clear_window (struct frame *f)
800{
801#ifdef USE_CAIRO
802 cairo_t *cr;
803
804 cr = x_begin_cr_clip (f, NULL);
805 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
806 cairo_paint (cr);
807 x_end_cr_clip (f);
808#else
809 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
810#endif
811}
812
813#ifdef USE_CAIRO
814static void
815x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
816 int width, int height, int top_p)
817{
818 cairo_t *cr;
819
820 cr = x_begin_cr_clip (f, gc);
821 x_set_cr_source_with_gc_foreground (f, gc);
822 cairo_move_to (cr, top_p ? x : x + height, y);
823 cairo_line_to (cr, x, y + height);
824 cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
825 cairo_line_to (cr, x + width, y);
826 cairo_fill (cr);
827 x_end_cr_clip (f);
828}
829
830enum corners
831 {
832 CORNER_BOTTOM_RIGHT, /* 0 -> pi/2 */
833 CORNER_BOTTOM_LEFT, /* pi/2 -> pi */
834 CORNER_TOP_LEFT, /* pi -> 3pi/2 */
835 CORNER_TOP_RIGHT, /* 3pi/2 -> 2pi */
836 CORNER_LAST
837 };
838
839static void
840x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
841 int width, int height,
842 double radius, double margin, int corners)
843{
844 cairo_t *cr;
845 int i;
846
847 cr = x_begin_cr_clip (f, gc);
848 x_set_cr_source_with_gc_background (f, gc);
849 for (i = 0; i < CORNER_LAST; i++)
850 if (corners & (1 << i))
851 {
852 double xm, ym, xc, yc;
853
854 if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
855 xm = x - margin, xc = xm + radius;
856 else
857 xm = x + width + margin, xc = xm - radius;
858 if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
859 ym = y - margin, yc = ym + radius;
860 else
861 ym = y + height + margin, yc = ym - radius;
862
863 cairo_move_to (cr, xm, ym);
864 cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
865 }
866 cairo_clip (cr);
867 cairo_rectangle (cr, x, y, width, height);
868 cairo_fill (cr);
869 x_end_cr_clip (f);
870}
871
872static void
873x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
874 int width, int height, int wave_length)
875{
876 cairo_t *cr;
877 double dx = wave_length, dy = height - 1;
878 int xoffset, n;
879
880 cr = x_begin_cr_clip (f, gc);
881 x_set_cr_source_with_gc_foreground (f, gc);
882 cairo_rectangle (cr, x, y, width, height);
883 cairo_clip (cr);
884
885 if (x >= 0)
886 {
887 xoffset = x % (wave_length * 2);
888 if (xoffset == 0)
889 xoffset = wave_length * 2;
890 }
891 else
892 xoffset = x % (wave_length * 2) + wave_length * 2;
893 n = (width + xoffset) / wave_length + 1;
894 if (xoffset > wave_length)
895 {
896 xoffset -= wave_length;
897 --n;
898 y += height - 1;
899 dy = -dy;
900 }
901
902 cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
903 while (--n >= 0)
904 {
905 cairo_rel_line_to (cr, dx, dy);
906 dy = -dy;
907 }
908 cairo_set_line_width (cr, 1);
909 cairo_stroke (cr);
910 x_end_cr_clip (f);
911}
912#endif
328 913
329 914
330/* Return the struct x_display_info corresponding to DPY. */ 915/* Return the struct x_display_info corresponding to DPY. */
@@ -452,9 +1037,42 @@ x_set_frame_alpha (struct frame *f)
452static void 1037static void
453x_update_begin (struct frame *f) 1038x_update_begin (struct frame *f)
454{ 1039{
455 /* Nothing to do. */ 1040#ifdef USE_CAIRO
456} 1041 if (! NILP (tip_frame) && XFRAME (tip_frame) == f
1042 && ! FRAME_VISIBLE_P (f))
1043 return;
1044
1045 if (! FRAME_CR_SURFACE (f))
1046 {
1047 int width, height;
1048#ifdef USE_GTK
1049 if (FRAME_GTK_WIDGET (f))
1050 {
1051 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1052 width = gdk_window_get_width (w);
1053 height = gdk_window_get_height (w);
1054 }
1055 else
1056#endif
1057 {
1058 width = FRAME_PIXEL_WIDTH (f);
1059 height = FRAME_PIXEL_HEIGHT (f);
1060 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1061 height += FRAME_TOOL_BAR_HEIGHT (f);
1062 if (! FRAME_EXTERNAL_MENU_BAR (f))
1063 height += FRAME_MENU_BAR_HEIGHT (f);
1064 }
457 1065
1066 if (width > 0 && height > 0)
1067 {
1068 block_input();
1069 FRAME_CR_SURFACE (f) = cairo_image_surface_create
1070 (CAIRO_FORMAT_ARGB32, width, height);
1071 unblock_input();
1072 }
1073 }
1074#endif /* USE_CAIRO */
1075}
458 1076
459/* Start update of window W. */ 1077/* Start update of window W. */
460 1078
@@ -496,8 +1114,12 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
496 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, 1114 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
497 face->foreground); 1115 face->foreground);
498 1116
1117#ifdef USE_CAIRO
1118 x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0);
1119#else
499 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1120 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
500 f->output_data.x->normal_gc, x, y0, x, y1); 1121 f->output_data.x->normal_gc, x, y0, x, y1);
1122#endif
501} 1123}
502 1124
503/* Draw a window divider from (x0,y0) to (x1,y1) */ 1125/* Draw a window divider from (x0,y0) to (x1,y1) */
@@ -517,39 +1139,38 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
517 ? face_last->foreground 1139 ? face_last->foreground
518 : FRAME_FOREGROUND_PIXEL (f)); 1140 : FRAME_FOREGROUND_PIXEL (f));
519 Display *display = FRAME_X_DISPLAY (f); 1141 Display *display = FRAME_X_DISPLAY (f);
520 Window window = FRAME_X_WINDOW (f);
521 1142
522 if (y1 - y0 > x1 - x0 && x1 - x0 > 2) 1143 if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
523 /* Vertical. */ 1144 /* Vertical. */
524 { 1145 {
525 XSetForeground (display, f->output_data.x->normal_gc, color_first); 1146 XSetForeground (display, f->output_data.x->normal_gc, color_first);
526 XFillRectangle (display, window, f->output_data.x->normal_gc, 1147 x_fill_rectangle (f, f->output_data.x->normal_gc,
527 x0, y0, 1, y1 - y0); 1148 x0, y0, 1, y1 - y0);
528 XSetForeground (display, f->output_data.x->normal_gc, color); 1149 XSetForeground (display, f->output_data.x->normal_gc, color);
529 XFillRectangle (display, window, f->output_data.x->normal_gc, 1150 x_fill_rectangle (f, f->output_data.x->normal_gc,
530 x0 + 1, y0, x1 - x0 - 2, y1 - y0); 1151 x0 + 1, y0, x1 - x0 - 2, y1 - y0);
531 XSetForeground (display, f->output_data.x->normal_gc, color_last); 1152 XSetForeground (display, f->output_data.x->normal_gc, color_last);
532 XFillRectangle (display, window, f->output_data.x->normal_gc, 1153 x_fill_rectangle (f, f->output_data.x->normal_gc,
533 x1 - 1, y0, 1, y1 - y0); 1154 x1 - 1, y0, 1, y1 - y0);
534 } 1155 }
535 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3) 1156 else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
536 /* Horizontal. */ 1157 /* Horizontal. */
537 { 1158 {
538 XSetForeground (display, f->output_data.x->normal_gc, color_first); 1159 XSetForeground (display, f->output_data.x->normal_gc, color_first);
539 XFillRectangle (display, window, f->output_data.x->normal_gc, 1160 x_fill_rectangle (f, f->output_data.x->normal_gc,
540 x0, y0, x1 - x0, 1); 1161 x0, y0, x1 - x0, 1);
541 XSetForeground (display, f->output_data.x->normal_gc, color); 1162 XSetForeground (display, f->output_data.x->normal_gc, color);
542 XFillRectangle (display, window, f->output_data.x->normal_gc, 1163 x_fill_rectangle (f, f->output_data.x->normal_gc,
543 x0, y0 + 1, x1 - x0, y1 - y0 - 2); 1164 x0, y0 + 1, x1 - x0, y1 - y0 - 2);
544 XSetForeground (display, f->output_data.x->normal_gc, color_last); 1165 XSetForeground (display, f->output_data.x->normal_gc, color_last);
545 XFillRectangle (display, window, f->output_data.x->normal_gc, 1166 x_fill_rectangle (f, f->output_data.x->normal_gc,
546 x0, y1 - 1, x1 - x0, 1); 1167 x0, y1 - 1, x1 - x0, 1);
547 } 1168 }
548 else 1169 else
549 { 1170 {
550 XSetForeground (display, f->output_data.x->normal_gc, color); 1171 XSetForeground (display, f->output_data.x->normal_gc, color);
551 XFillRectangle (display, window, f->output_data.x->normal_gc, 1172 x_fill_rectangle (f, f->output_data.x->normal_gc,
552 x0, y0, x1 - x0, y1 - y0); 1173 x0, y0, x1 - x0, y1 - y0);
553 } 1174 }
554} 1175}
555 1176
@@ -612,6 +1233,43 @@ x_update_end (struct frame *f)
612 /* Mouse highlight may be displayed again. */ 1233 /* Mouse highlight may be displayed again. */
613 MOUSE_HL_INFO (f)->mouse_face_defer = false; 1234 MOUSE_HL_INFO (f)->mouse_face_defer = false;
614 1235
1236#ifdef USE_CAIRO
1237 if (FRAME_CR_SURFACE (f))
1238 {
1239 cairo_t *cr = 0;
1240 block_input();
1241#if defined (USE_GTK) && defined (HAVE_GTK3)
1242 if (FRAME_GTK_WIDGET (f))
1243 {
1244 GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
1245 cr = gdk_cairo_create (w);
1246 }
1247 else
1248#endif
1249 {
1250 cairo_surface_t *surface;
1251 int width = FRAME_PIXEL_WIDTH (f);
1252 int height = FRAME_PIXEL_HEIGHT (f);
1253 if (! FRAME_EXTERNAL_TOOL_BAR (f))
1254 height += FRAME_TOOL_BAR_HEIGHT (f);
1255 if (! FRAME_EXTERNAL_MENU_BAR (f))
1256 height += FRAME_MENU_BAR_HEIGHT (f);
1257 surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
1258 FRAME_X_WINDOW (f),
1259 FRAME_DISPLAY_INFO (f)->visual,
1260 width,
1261 height);
1262 cr = cairo_create (surface);
1263 cairo_surface_destroy (surface);
1264 }
1265
1266 cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0);
1267 cairo_paint (cr);
1268 cairo_destroy (cr);
1269 unblock_input ();
1270 }
1271#endif /* USE_CAIRO */
1272
615#ifndef XFlush 1273#ifndef XFlush
616 block_input (); 1274 block_input ();
617 XFlush (FRAME_X_DISPLAY (f)); 1275 XFlush (FRAME_X_DISPLAY (f));
@@ -638,18 +1296,16 @@ x_clear_under_internal_border (struct frame *f)
638{ 1296{
639 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) 1297 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
640 { 1298 {
641 Display *display = FRAME_X_DISPLAY (f);
642 Window window = FRAME_X_WINDOW (f);
643 int border = FRAME_INTERNAL_BORDER_WIDTH (f); 1299 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
644 int width = FRAME_PIXEL_WIDTH (f); 1300 int width = FRAME_PIXEL_WIDTH (f);
645 int height = FRAME_PIXEL_HEIGHT (f); 1301 int height = FRAME_PIXEL_HEIGHT (f);
646 int margin = FRAME_TOP_MARGIN_HEIGHT (f); 1302 int margin = FRAME_TOP_MARGIN_HEIGHT (f);
647 1303
648 block_input (); 1304 block_input ();
649 x_clear_area (display, window, 0, 0, border, height); 1305 x_clear_area (f, 0, 0, border, height);
650 x_clear_area (display, window, 0, margin, width, border); 1306 x_clear_area (f, 0, margin, width, border);
651 x_clear_area (display, window, width - border, 0, border, height); 1307 x_clear_area (f, width - border, 0, border, height);
652 x_clear_area (display, window, 0, height - border, width, border); 1308 x_clear_area (f, 0, height - border, width, border);
653 unblock_input (); 1309 unblock_input ();
654 } 1310 }
655} 1311}
@@ -691,11 +1347,8 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
691 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); 1347 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
692 1348
693 block_input (); 1349 block_input ();
694 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1350 x_clear_area (f, 0, y, width, height);
695 0, y, width, height); 1351 x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
696 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
697 FRAME_PIXEL_WIDTH (f) - width,
698 y, width, height);
699 unblock_input (); 1352 unblock_input ();
700 } 1353 }
701 } 1354 }
@@ -725,13 +1378,29 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
725 else 1378 else
726 XSetForeground (display, face->gc, face->background); 1379 XSetForeground (display, face->gc, face->background);
727 1380
728 XFillRectangle (display, window, face->gc, 1381 x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny);
729 p->bx, p->by, p->nx, p->ny);
730 1382
731 if (!face->stipple) 1383 if (!face->stipple)
732 XSetForeground (display, face->gc, face->foreground); 1384 XSetForeground (display, face->gc, face->foreground);
733 } 1385 }
734 1386
1387#ifdef USE_CAIRO
1388 if (p->which && p->which < max_fringe_bmp)
1389 {
1390 XGCValues gcv;
1391
1392 XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
1393 XSetForeground (display, gc, (p->cursor_p
1394 ? (p->overlay_p ? face->background
1395 : f->output_data.x->cursor_pixel)
1396 : face->foreground));
1397 XSetBackground (display, gc, face->background);
1398 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1399 p->wd, p->h, p->x, p->y, p->overlay_p);
1400 XSetForeground (display, gc, gcv.foreground);
1401 XSetBackground (display, gc, gcv.background);
1402 }
1403#else /* not USE_CAIRO */
735 if (p->which) 1404 if (p->which)
736 { 1405 {
737 char *bits; 1406 char *bits;
@@ -776,8 +1445,9 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
776 XFreePixmap (display, clipmask); 1445 XFreePixmap (display, clipmask);
777 } 1446 }
778 } 1447 }
1448#endif /* not USE_CAIRO */
779 1449
780 XSetClipMask (display, gc, None); 1450 x_reset_clip_rectangles (f, gc);
781} 1451}
782 1452
783/*********************************************************************** 1453/***********************************************************************
@@ -985,7 +1655,7 @@ x_set_glyph_string_clipping (struct glyph_string *s)
985 int n = get_glyph_string_clip_rects (s, r, 2); 1655 int n = get_glyph_string_clip_rects (s, r, 2);
986 1656
987 if (n > 0) 1657 if (n > 0)
988 XSetClipRectangles (s->display, s->gc, 0, 0, r, n, Unsorted); 1658 x_set_clip_rectangles (s->f, s->gc, r, n);
989 s->num_clips = n; 1659 s->num_clips = n;
990} 1660}
991 1661
@@ -1005,7 +1675,7 @@ x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_stri
1005 r.height = src->height; 1675 r.height = src->height;
1006 dst->clip[0] = r; 1676 dst->clip[0] = r;
1007 dst->num_clips = 1; 1677 dst->num_clips = 1;
1008 XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted); 1678 x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
1009} 1679}
1010 1680
1011 1681
@@ -1057,7 +1727,7 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
1057 XGCValues xgcv; 1727 XGCValues xgcv;
1058 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv); 1728 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, &xgcv);
1059 XSetForeground (s->display, s->gc, xgcv.background); 1729 XSetForeground (s->display, s->gc, xgcv.background);
1060 XFillRectangle (s->display, s->window, s->gc, x, y, w, h); 1730 x_fill_rectangle (s->f, s->gc, x, y, w, h);
1061 XSetForeground (s->display, s->gc, xgcv.foreground); 1731 XSetForeground (s->display, s->gc, xgcv.foreground);
1062} 1732}
1063 1733
@@ -1081,7 +1751,7 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1081 { 1751 {
1082 /* Fill background with a stipple pattern. */ 1752 /* Fill background with a stipple pattern. */
1083 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); 1753 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1084 XFillRectangle (s->display, s->window, s->gc, s->x, 1754 x_fill_rectangle (s->f, s->gc, s->x,
1085 s->y + box_line_width, 1755 s->y + box_line_width,
1086 s->background_width, 1756 s->background_width,
1087 s->height - 2 * box_line_width); 1757 s->height - 2 * box_line_width);
@@ -1124,7 +1794,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
1124 for (i = 0; i < s->nchars; ++i) 1794 for (i = 0; i < s->nchars; ++i)
1125 { 1795 {
1126 struct glyph *g = s->first_glyph + i; 1796 struct glyph *g = s->first_glyph + i;
1127 XDrawRectangle (s->display, s->window, 1797 x_draw_rectangle (s->f,
1128 s->gc, x, s->y, g->pixel_width - 1, 1798 s->gc, x, s->y, g->pixel_width - 1,
1129 s->height - 1); 1799 s->height - 1);
1130 x += g->pixel_width; 1800 x += g->pixel_width;
@@ -1176,7 +1846,7 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1176 if (s->font_not_found_p) 1846 if (s->font_not_found_p)
1177 { 1847 {
1178 if (s->cmp_from == 0) 1848 if (s->cmp_from == 0)
1179 XDrawRectangle (s->display, s->window, s->gc, x, s->y, 1849 x_draw_rectangle (s->f, s->gc, x, s->y,
1180 s->width - 1, s->height - 1); 1850 s->width - 1, s->height - 1);
1181 } 1851 }
1182 else if (! s->first_glyph->u.cmp.automatic) 1852 else if (! s->first_glyph->u.cmp.automatic)
@@ -1310,7 +1980,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1310 false); 1980 false);
1311 } 1981 }
1312 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE) 1982 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1313 XDrawRectangle (s->display, s->window, s->gc, 1983 x_draw_rectangle (s->f, s->gc,
1314 x, s->ybase - glyph->ascent, 1984 x, s->ybase - glyph->ascent,
1315 glyph->pixel_width - 1, 1985 glyph->pixel_width - 1,
1316 glyph->ascent + glyph->descent - 1); 1986 glyph->ascent + glyph->descent - 1);
@@ -1882,6 +2552,79 @@ x_draw_relief_rect (struct frame *f,
1882 bool left_p, bool right_p, 2552 bool left_p, bool right_p,
1883 XRectangle *clip_rect) 2553 XRectangle *clip_rect)
1884{ 2554{
2555#ifdef USE_CAIRO
2556 GC top_left_gc, bottom_right_gc;
2557 int corners = 0;
2558
2559 if (raised_p)
2560 {
2561 top_left_gc = f->output_data.x->white_relief.gc;
2562 bottom_right_gc = f->output_data.x->black_relief.gc;
2563 }
2564 else
2565 {
2566 top_left_gc = f->output_data.x->black_relief.gc;
2567 bottom_right_gc = f->output_data.x->white_relief.gc;
2568 }
2569
2570 x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
2571 x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
2572
2573 if (left_p)
2574 {
2575 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2576 width, bottom_y + 1 - top_y);
2577 if (top_p)
2578 corners |= 1 << CORNER_TOP_LEFT;
2579 if (bot_p)
2580 corners |= 1 << CORNER_BOTTOM_LEFT;
2581 }
2582 if (right_p)
2583 {
2584 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
2585 width, bottom_y + 1 - top_y);
2586 if (top_p)
2587 corners |= 1 << CORNER_TOP_RIGHT;
2588 if (bot_p)
2589 corners |= 1 << CORNER_BOTTOM_RIGHT;
2590 }
2591 if (top_p)
2592 {
2593 if (!right_p)
2594 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2595 right_x + 1 - left_x, width);
2596 else
2597 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2598 right_x + 1 - left_x, width, 1);
2599 }
2600 if (bot_p)
2601 {
2602 if (!left_p)
2603 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
2604 right_x + 1 - left_x, width);
2605 else
2606 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2607 left_x, bottom_y + 1 - width,
2608 right_x + 1 - left_x, width, 0);
2609 }
2610 if (left_p && width != 1)
2611 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2612 1, bottom_y + 1 - top_y);
2613 if (top_p && width != 1)
2614 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2615 right_x + 1 - left_x, 1);
2616 if (corners)
2617 {
2618 XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
2619 FRAME_BACKGROUND_PIXEL (f));
2620 x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
2621 right_x - left_x + 1, bottom_y - top_y + 1,
2622 6, 1, corners);
2623 }
2624
2625 x_reset_clip_rectangles (f, top_left_gc);
2626 x_reset_clip_rectangles (f, bottom_right_gc);
2627#else
1885 Display *dpy = FRAME_X_DISPLAY (f); 2628 Display *dpy = FRAME_X_DISPLAY (f);
1886 Window window = FRAME_X_WINDOW (f); 2629 Window window = FRAME_X_WINDOW (f);
1887 int i; 2630 int i;
@@ -1970,7 +2713,9 @@ x_draw_relief_rect (struct frame *f,
1970 right_x - i, bottom_y + 1 - (i + 1) * bot_p); 2713 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
1971 } 2714 }
1972 2715
1973 XSetClipMask (dpy, gc, None); 2716 x_reset_clip_rectangles (f, gc);
2717
2718#endif
1974} 2719}
1975 2720
1976 2721
@@ -1990,28 +2735,28 @@ x_draw_box_rect (struct glyph_string *s,
1990 2735
1991 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); 2736 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
1992 XSetForeground (s->display, s->gc, s->face->box_color); 2737 XSetForeground (s->display, s->gc, s->face->box_color);
1993 XSetClipRectangles (s->display, s->gc, 0, 0, clip_rect, 1, Unsorted); 2738 x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
1994 2739
1995 /* Top. */ 2740 /* Top. */
1996 XFillRectangle (s->display, s->window, s->gc, 2741 x_fill_rectangle (s->f, s->gc,
1997 left_x, top_y, right_x - left_x + 1, width); 2742 left_x, top_y, right_x - left_x + 1, width);
1998 2743
1999 /* Left. */ 2744 /* Left. */
2000 if (left_p) 2745 if (left_p)
2001 XFillRectangle (s->display, s->window, s->gc, 2746 x_fill_rectangle (s->f, s->gc,
2002 left_x, top_y, width, bottom_y - top_y + 1); 2747 left_x, top_y, width, bottom_y - top_y + 1);
2003 2748
2004 /* Bottom. */ 2749 /* Bottom. */
2005 XFillRectangle (s->display, s->window, s->gc, 2750 x_fill_rectangle (s->f, s->gc,
2006 left_x, bottom_y - width + 1, right_x - left_x + 1, width); 2751 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2007 2752
2008 /* Right. */ 2753 /* Right. */
2009 if (right_p) 2754 if (right_p)
2010 XFillRectangle (s->display, s->window, s->gc, 2755 x_fill_rectangle (s->f, s->gc,
2011 right_x - width + 1, top_y, width, bottom_y - top_y + 1); 2756 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2012 2757
2013 XSetForeground (s->display, s->gc, xgcv.foreground); 2758 XSetForeground (s->display, s->gc, xgcv.foreground);
2014 XSetClipMask (s->display, s->gc, None); 2759 x_reset_clip_rectangles (s->f, s->gc);
2015} 2760}
2016 2761
2017 2762
@@ -2142,7 +2887,7 @@ x_draw_image_foreground (struct glyph_string *s)
2142 if (s->hl == DRAW_CURSOR) 2887 if (s->hl == DRAW_CURSOR)
2143 { 2888 {
2144 int relief = eabs (s->img->relief); 2889 int relief = eabs (s->img->relief);
2145 XDrawRectangle (s->display, s->window, s->gc, 2890 x_draw_rectangle (s->f, s->gc,
2146 x - relief, y - relief, 2891 x - relief, y - relief,
2147 s->slice.width + relief*2 - 1, 2892 s->slice.width + relief*2 - 1,
2148 s->slice.height + relief*2 - 1); 2893 s->slice.height + relief*2 - 1);
@@ -2151,7 +2896,7 @@ x_draw_image_foreground (struct glyph_string *s)
2151 } 2896 }
2152 else 2897 else
2153 /* Draw a rectangle if image could not be loaded. */ 2898 /* Draw a rectangle if image could not be loaded. */
2154 XDrawRectangle (s->display, s->window, s->gc, x, y, 2899 x_draw_rectangle (s->f, s->gc, x, y,
2155 s->slice.width - 1, s->slice.height - 1); 2900 s->slice.width - 1, s->slice.height - 1);
2156} 2901}
2157 2902
@@ -2290,7 +3035,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
2290 if (s->hl == DRAW_CURSOR) 3035 if (s->hl == DRAW_CURSOR)
2291 { 3036 {
2292 int r = eabs (s->img->relief); 3037 int r = eabs (s->img->relief);
2293 XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, 3038 x_draw_rectangle (s->f, s->gc, x - r, y - r,
2294 s->slice.width + r*2 - 1, 3039 s->slice.width + r*2 - 1,
2295 s->slice.height + r*2 - 1); 3040 s->slice.height + r*2 - 1);
2296 } 3041 }
@@ -2298,7 +3043,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
2298 } 3043 }
2299 else 3044 else
2300 /* Draw a rectangle if image could not be loaded. */ 3045 /* Draw a rectangle if image could not be loaded. */
2301 XDrawRectangle (s->display, pixmap, s->gc, x, y, 3046 x_draw_rectangle (s->f, s->gc, x, y,
2302 s->slice.width - 1, s->slice.height - 1); 3047 s->slice.width - 1, s->slice.height - 1);
2303} 3048}
2304 3049
@@ -2313,7 +3058,7 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
2313 { 3058 {
2314 /* Fill background with a stipple pattern. */ 3059 /* Fill background with a stipple pattern. */
2315 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); 3060 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2316 XFillRectangle (s->display, s->window, s->gc, x, y, w, h); 3061 x_fill_rectangle (s->f, s->gc, x, y, w, h);
2317 XSetFillStyle (s->display, s->gc, FillSolid); 3062 XSetFillStyle (s->display, s->gc, FillSolid);
2318 } 3063 }
2319 else 3064 else
@@ -2422,7 +3167,25 @@ x_draw_image_glyph_string (struct glyph_string *s)
2422 } 3167 }
2423 3168
2424 /* Draw the foreground. */ 3169 /* Draw the foreground. */
2425 if (pixmap != None) 3170#ifdef USE_CAIRO
3171 if (s->img->cr_data)
3172 {
3173 cairo_t *cr = x_begin_cr_clip (s->f, s->gc);
3174
3175 int x = s->x + s->img->hmargin;
3176 int y = s->y + s->img->vmargin;
3177 int width = s->background_width;
3178
3179 cairo_set_source_surface (cr, s->img->cr_data,
3180 x - s->slice.x,
3181 y - s->slice.y);
3182 cairo_rectangle (cr, x, y, width, height);
3183 cairo_fill (cr);
3184 x_end_cr_clip (s->f);
3185 }
3186 else
3187#endif
3188 if (pixmap != None)
2426 { 3189 {
2427 x_draw_image_foreground_1 (s, pixmap); 3190 x_draw_image_foreground_1 (s, pixmap);
2428 x_set_glyph_string_clipping (s); 3191 x_set_glyph_string_clipping (s);
@@ -2505,13 +3268,13 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2505 gc = s->face->gc; 3268 gc = s->face->gc;
2506 3269
2507 get_glyph_string_clip_rect (s, &r); 3270 get_glyph_string_clip_rect (s, &r);
2508 XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted); 3271 x_set_clip_rectangles (s->f, gc, &r, 1);
2509 3272
2510 if (s->face->stipple) 3273 if (s->face->stipple)
2511 { 3274 {
2512 /* Fill background with a stipple pattern. */ 3275 /* Fill background with a stipple pattern. */
2513 XSetFillStyle (s->display, gc, FillOpaqueStippled); 3276 XSetFillStyle (s->display, gc, FillOpaqueStippled);
2514 XFillRectangle (s->display, s->window, gc, x, y, w, h); 3277 x_fill_rectangle (s->f, gc, x, y, w, h);
2515 XSetFillStyle (s->display, gc, FillSolid); 3278 XSetFillStyle (s->display, gc, FillSolid);
2516 } 3279 }
2517 else 3280 else
@@ -2519,11 +3282,11 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2519 XGCValues xgcv; 3282 XGCValues xgcv;
2520 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv); 3283 XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
2521 XSetForeground (s->display, gc, xgcv.background); 3284 XSetForeground (s->display, gc, xgcv.background);
2522 XFillRectangle (s->display, s->window, gc, x, y, w, h); 3285 x_fill_rectangle (s->f, gc, x, y, w, h);
2523 XSetForeground (s->display, gc, xgcv.foreground); 3286 XSetForeground (s->display, gc, xgcv.foreground);
2524 } 3287 }
2525 3288
2526 XSetClipMask (s->display, gc, None); 3289 x_reset_clip_rectangles (s->f, gc);
2527 } 3290 }
2528 } 3291 }
2529 else if (!s->background_filled_p) 3292 else if (!s->background_filled_p)
@@ -2560,6 +3323,10 @@ static void
2560x_draw_underwave (struct glyph_string *s) 3323x_draw_underwave (struct glyph_string *s)
2561{ 3324{
2562 int wave_height = 3, wave_length = 2; 3325 int wave_height = 3, wave_length = 2;
3326#ifdef USE_CAIRO
3327 x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
3328 s->width, wave_height, wave_length);
3329#else /* not USE_CAIRO */
2563 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax; 3330 int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax;
2564 bool odd; 3331 bool odd;
2565 XRectangle wave_clip, string_clip, final_clip; 3332 XRectangle wave_clip, string_clip, final_clip;
@@ -2609,6 +3376,7 @@ x_draw_underwave (struct glyph_string *s)
2609 3376
2610 /* Restore previous clipping rectangle(s) */ 3377 /* Restore previous clipping rectangle(s) */
2611 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted); 3378 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
3379#endif /* not USE_CAIRO */
2612} 3380}
2613 3381
2614 3382
@@ -2778,14 +3546,14 @@ x_draw_glyph_string (struct glyph_string *s)
2778 s->underline_position = position; 3546 s->underline_position = position;
2779 y = s->ybase + position; 3547 y = s->ybase + position;
2780 if (s->face->underline_defaulted_p) 3548 if (s->face->underline_defaulted_p)
2781 XFillRectangle (s->display, s->window, s->gc, 3549 x_fill_rectangle (s->f, s->gc,
2782 s->x, y, s->width, thickness); 3550 s->x, y, s->width, thickness);
2783 else 3551 else
2784 { 3552 {
2785 XGCValues xgcv; 3553 XGCValues xgcv;
2786 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); 3554 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2787 XSetForeground (s->display, s->gc, s->face->underline_color); 3555 XSetForeground (s->display, s->gc, s->face->underline_color);
2788 XFillRectangle (s->display, s->window, s->gc, 3556 x_fill_rectangle (s->f, s->gc,
2789 s->x, y, s->width, thickness); 3557 s->x, y, s->width, thickness);
2790 XSetForeground (s->display, s->gc, xgcv.foreground); 3558 XSetForeground (s->display, s->gc, xgcv.foreground);
2791 } 3559 }
@@ -2797,14 +3565,14 @@ x_draw_glyph_string (struct glyph_string *s)
2797 unsigned long dy = 0, h = 1; 3565 unsigned long dy = 0, h = 1;
2798 3566
2799 if (s->face->overline_color_defaulted_p) 3567 if (s->face->overline_color_defaulted_p)
2800 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, 3568 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
2801 s->width, h); 3569 s->width, h);
2802 else 3570 else
2803 { 3571 {
2804 XGCValues xgcv; 3572 XGCValues xgcv;
2805 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); 3573 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2806 XSetForeground (s->display, s->gc, s->face->overline_color); 3574 XSetForeground (s->display, s->gc, s->face->overline_color);
2807 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, 3575 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
2808 s->width, h); 3576 s->width, h);
2809 XSetForeground (s->display, s->gc, xgcv.foreground); 3577 XSetForeground (s->display, s->gc, xgcv.foreground);
2810 } 3578 }
@@ -2817,14 +3585,14 @@ x_draw_glyph_string (struct glyph_string *s)
2817 unsigned long dy = (s->height - h) / 2; 3585 unsigned long dy = (s->height - h) / 2;
2818 3586
2819 if (s->face->strike_through_color_defaulted_p) 3587 if (s->face->strike_through_color_defaulted_p)
2820 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, 3588 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
2821 s->width, h); 3589 s->width, h);
2822 else 3590 else
2823 { 3591 {
2824 XGCValues xgcv; 3592 XGCValues xgcv;
2825 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); 3593 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2826 XSetForeground (s->display, s->gc, s->face->strike_through_color); 3594 XSetForeground (s->display, s->gc, s->face->strike_through_color);
2827 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, 3595 x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
2828 s->width, h); 3596 s->width, h);
2829 XSetForeground (s->display, s->gc, xgcv.foreground); 3597 XSetForeground (s->display, s->gc, xgcv.foreground);
2830 } 3598 }
@@ -2853,7 +3621,7 @@ x_draw_glyph_string (struct glyph_string *s)
2853 x_draw_glyph_string_foreground (prev); 3621 x_draw_glyph_string_foreground (prev);
2854 else 3622 else
2855 x_draw_composite_glyph_string_foreground (prev); 3623 x_draw_composite_glyph_string_foreground (prev);
2856 XSetClipMask (prev->display, prev->gc, None); 3624 x_reset_clip_rectangles (prev->f, prev->gc);
2857 prev->hl = save; 3625 prev->hl = save;
2858 prev->num_clips = 0; 3626 prev->num_clips = 0;
2859 } 3627 }
@@ -2878,7 +3646,7 @@ x_draw_glyph_string (struct glyph_string *s)
2878 x_draw_glyph_string_foreground (next); 3646 x_draw_glyph_string_foreground (next);
2879 else 3647 else
2880 x_draw_composite_glyph_string_foreground (next); 3648 x_draw_composite_glyph_string_foreground (next);
2881 XSetClipMask (next->display, next->gc, None); 3649 x_reset_clip_rectangles (next->f, next->gc);
2882 next->hl = save; 3650 next->hl = save;
2883 next->num_clips = 0; 3651 next->num_clips = 0;
2884 next->clip_head = s->next; 3652 next->clip_head = s->next;
@@ -2887,7 +3655,7 @@ x_draw_glyph_string (struct glyph_string *s)
2887 } 3655 }
2888 3656
2889 /* Reset clipping. */ 3657 /* Reset clipping. */
2890 XSetClipMask (s->display, s->gc, None); 3658 x_reset_clip_rectangles (s->f, s->gc);
2891 s->num_clips = 0; 3659 s->num_clips = 0;
2892} 3660}
2893 3661
@@ -2918,11 +3686,32 @@ x_delete_glyphs (struct frame *f, register int n)
2918/* Like XClearArea, but check that WIDTH and HEIGHT are reasonable. 3686/* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
2919 If they are <= 0, this is probably an error. */ 3687 If they are <= 0, this is probably an error. */
2920 3688
3689static void
3690x_clear_area1 (Display *dpy, Window window,
3691 int x, int y, int width, int height, int exposures)
3692{
3693 eassert (width > 0 && height > 0);
3694 XClearArea (dpy, window, x, y, width, height, exposures);
3695}
3696
3697
2921void 3698void
2922x_clear_area (Display *dpy, Window window, int x, int y, int width, int height) 3699x_clear_area (struct frame *f, int x, int y, int width, int height)
2923{ 3700{
3701#ifdef USE_CAIRO
3702 cairo_t *cr;
3703
2924 eassert (width > 0 && height > 0); 3704 eassert (width > 0 && height > 0);
2925 XClearArea (dpy, window, x, y, width, height, False); 3705
3706 cr = x_begin_cr_clip (f, NULL);
3707 x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc);
3708 cairo_rectangle (cr, x, y, width, height);
3709 cairo_fill (cr);
3710 x_end_cr_clip (f);
3711#else
3712 x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3713 x, y, width, height, False);
3714#endif
2926} 3715}
2927 3716
2928 3717
@@ -2937,7 +3726,7 @@ x_clear_frame (struct frame *f)
2937 3726
2938 block_input (); 3727 block_input ();
2939 3728
2940 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 3729 x_clear_window (f);
2941 3730
2942 /* We have to clear the scroll bars. If we have changed colors or 3731 /* We have to clear the scroll bars. If we have changed colors or
2943 something like that, then they should be notified. */ 3732 something like that, then they should be notified. */
@@ -3243,12 +4032,16 @@ x_scroll_run (struct window *w, struct run *run)
3243 /* Cursor off. Will be switched on again in x_update_window_end. */ 4032 /* Cursor off. Will be switched on again in x_update_window_end. */
3244 x_clear_cursor (w); 4033 x_clear_cursor (w);
3245 4034
4035#ifdef USE_CAIRO
4036 SET_FRAME_GARBAGED (f);
4037#else
3246 XCopyArea (FRAME_X_DISPLAY (f), 4038 XCopyArea (FRAME_X_DISPLAY (f),
3247 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f), 4039 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f),
3248 f->output_data.x->normal_gc, 4040 f->output_data.x->normal_gc,
3249 x, from_y, 4041 x, from_y,
3250 width, height, 4042 width, height,
3251 x, to_y); 4043 x, to_y);
4044#endif
3252 4045
3253 unblock_input (); 4046 unblock_input ();
3254} 4047}
@@ -4157,7 +4950,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
4157 dpyinfo->last_mouse_glyph_frame = f1; 4950 dpyinfo->last_mouse_glyph_frame = f1;
4158 4951
4159 *bar_window = Qnil; 4952 *bar_window = Qnil;
4160 *part = scroll_bar_above_handle; 4953 *part = 0;
4161 *fp = f1; 4954 *fp = f1;
4162 XSETINT (*x, win_x); 4955 XSETINT (*x, win_x);
4163 XSETINT (*y, win_y); 4956 XSETINT (*y, win_y);
@@ -4251,7 +5044,7 @@ x_window_to_menu_bar (Window window)
4251#ifdef USE_TOOLKIT_SCROLL_BARS 5044#ifdef USE_TOOLKIT_SCROLL_BARS
4252 5045
4253static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part, 5046static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
4254 int, int, bool); 5047 int, int, bool);
4255 5048
4256/* Lisp window being scrolled. Set when starting to interact with 5049/* Lisp window being scrolled. Set when starting to interact with
4257 a toolkit scroll bar, reset to nil when ending the interaction. */ 5050 a toolkit scroll bar, reset to nil when ending the interaction. */
@@ -5508,8 +6301,7 @@ x_scroll_bar_create (struct window *w, int top, int left,
5508 for the case that a window has been split horizontally. In 6301 for the case that a window has been split horizontally. In
5509 this case, no clear_frame is generated to reduce flickering. */ 6302 this case, no clear_frame is generated to reduce flickering. */
5510 if (width > 0 && window_box_height (w) > 0) 6303 if (width > 0 && window_box_height (w) > 0)
5511 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6304 x_clear_area (f, left, top, width, window_box_height (w));
5512 left, top, width, window_box_height (w));
5513 6305
5514 window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6306 window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5515 /* Position and size of scroll bar. */ 6307 /* Position and size of scroll bar. */
@@ -5641,7 +6433,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
5641 /* Draw the empty space above the handle. Note that we can't clear 6433 /* Draw the empty space above the handle. Note that we can't clear
5642 zero-height areas; that means "clear to end of window." */ 6434 zero-height areas; that means "clear to end of window." */
5643 if ((inside_width > 0) && (start > 0)) 6435 if ((inside_width > 0) && (start > 0))
5644 x_clear_area (FRAME_X_DISPLAY (f), w, 6436 x_clear_area1 (FRAME_X_DISPLAY (f), w,
5645 VERTICAL_SCROLL_BAR_LEFT_BORDER, 6437 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5646 VERTICAL_SCROLL_BAR_TOP_BORDER, 6438 VERTICAL_SCROLL_BAR_TOP_BORDER,
5647 inside_width, start); 6439 inside_width, start);
@@ -5652,7 +6444,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
5652 f->output_data.x->scroll_bar_foreground_pixel); 6444 f->output_data.x->scroll_bar_foreground_pixel);
5653 6445
5654 /* Draw the handle itself. */ 6446 /* Draw the handle itself. */
5655 XFillRectangle (FRAME_X_DISPLAY (f), w, gc, 6447 x_fill_rectangle (f, gc,
5656 /* x, y, width, height */ 6448 /* x, y, width, height */
5657 VERTICAL_SCROLL_BAR_LEFT_BORDER, 6449 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5658 VERTICAL_SCROLL_BAR_TOP_BORDER + start, 6450 VERTICAL_SCROLL_BAR_TOP_BORDER + start,
@@ -5666,7 +6458,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
5666 /* Draw the empty space below the handle. Note that we can't 6458 /* Draw the empty space below the handle. Note that we can't
5667 clear zero-height areas; that means "clear to end of window." */ 6459 clear zero-height areas; that means "clear to end of window." */
5668 if ((inside_width > 0) && (end < inside_height)) 6460 if ((inside_width > 0) && (end < inside_height))
5669 x_clear_area (FRAME_X_DISPLAY (f), w, 6461 x_clear_area1 (FRAME_X_DISPLAY (f), w,
5670 VERTICAL_SCROLL_BAR_LEFT_BORDER, 6462 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5671 VERTICAL_SCROLL_BAR_TOP_BORDER + end, 6463 VERTICAL_SCROLL_BAR_TOP_BORDER + end,
5672 inside_width, inside_height - end); 6464 inside_width, inside_height - end);
@@ -5733,8 +6525,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5733 if (width > 0 && height > 0) 6525 if (width > 0 && height > 0)
5734 { 6526 {
5735 block_input (); 6527 block_input ();
5736 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6528 x_clear_area (f, left, top, width, height);
5737 left, top, width, height);
5738 unblock_input (); 6529 unblock_input ();
5739 } 6530 }
5740 6531
@@ -5766,8 +6557,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5766 /* Since toolkit scroll bars are smaller than the space reserved 6557 /* Since toolkit scroll bars are smaller than the space reserved
5767 for them on the frame, we have to clear "under" them. */ 6558 for them on the frame, we have to clear "under" them. */
5768 if (width > 0 && height > 0) 6559 if (width > 0 && height > 0)
5769 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6560 x_clear_area (f, left, top, width, height);
5770 left, top, width, height);
5771#ifdef USE_GTK 6561#ifdef USE_GTK
5772 xg_update_scrollbar_pos (f, bar->x_window, top, 6562 xg_update_scrollbar_pos (f, bar->x_window, top,
5773 left, width, max (height, 1)); 6563 left, width, max (height, 1));
@@ -5853,8 +6643,7 @@ XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int posit
5853 6643
5854 /* Clear also part between window_width and 6644 /* Clear also part between window_width and
5855 WINDOW_PIXEL_WIDTH. */ 6645 WINDOW_PIXEL_WIDTH. */
5856 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6646 x_clear_area (f, left, top, pixel_width, height);
5857 left, top, pixel_width, height);
5858 unblock_input (); 6647 unblock_input ();
5859 } 6648 }
5860 6649
@@ -5885,7 +6674,7 @@ XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int posit
5885 /* Since toolkit scroll bars are smaller than the space reserved 6674 /* Since toolkit scroll bars are smaller than the space reserved
5886 for them on the frame, we have to clear "under" them. */ 6675 for them on the frame, we have to clear "under" them. */
5887 if (width > 0 && height > 0) 6676 if (width > 0 && height > 0)
5888 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6677 x_clear_area (f,
5889 WINDOW_LEFT_EDGE_X (w), top, 6678 WINDOW_LEFT_EDGE_X (w), top,
5890 pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height); 6679 pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height);
5891#ifdef USE_GTK 6680#ifdef USE_GTK
@@ -6131,7 +6920,7 @@ x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event)
6131 f->output_data.x->scroll_bar_foreground_pixel); 6920 f->output_data.x->scroll_bar_foreground_pixel);
6132 6921
6133 /* Draw a one-pixel border just inside the edges of the scroll bar. */ 6922 /* Draw a one-pixel border just inside the edges of the scroll bar. */
6134 XDrawRectangle (FRAME_X_DISPLAY (f), w, gc, 6923 x_draw_rectangle (f, gc,
6135 /* x, y, width, height */ 6924 /* x, y, width, height */
6136 0, 0, bar->width - 1, bar->height - 1); 6925 0, 0, bar->width - 1, bar->height - 1);
6137 6926
@@ -6915,11 +7704,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6915 } 7704 }
6916 else 7705 else
6917 { 7706 {
6918#ifdef USE_GTK 7707#if defined (USE_GTK) && ! defined (HAVE_GTK3) && ! defined (USE_CAIRO)
6919 /* This seems to be needed for GTK 2.6 and later, see 7708 /* This seems to be needed for GTK 2.6 and later, see
6920 http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398. */ 7709 http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398. */
6921 x_clear_area (event->xexpose.display, 7710 x_clear_area (f,
6922 event->xexpose.window,
6923 event->xexpose.x, event->xexpose.y, 7711 event->xexpose.x, event->xexpose.y,
6924 event->xexpose.width, event->xexpose.height); 7712 event->xexpose.width, event->xexpose.height);
6925#endif 7713#endif
@@ -7529,6 +8317,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7529 8317
7530 case ConfigureNotify: 8318 case ConfigureNotify:
7531 f = x_top_window_to_frame (dpyinfo, event->xconfigure.window); 8319 f = x_top_window_to_frame (dpyinfo, event->xconfigure.window);
8320#ifdef USE_CAIRO
8321 if (f) x_cr_destroy_surface (f);
8322#endif
7532#ifdef USE_GTK 8323#ifdef USE_GTK
7533 if (!f 8324 if (!f
7534 && (f = any) 8325 && (f = any)
@@ -7536,6 +8327,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7536 { 8327 {
7537 xg_frame_resized (f, event->xconfigure.width, 8328 xg_frame_resized (f, event->xconfigure.width,
7538 event->xconfigure.height); 8329 event->xconfigure.height);
8330#ifdef USE_CAIRO
8331 x_cr_destroy_surface (f);
8332#endif
7539 f = 0; 8333 f = 0;
7540 } 8334 }
7541#endif 8335#endif
@@ -7957,7 +8751,7 @@ x_clip_to_row (struct window *w, struct glyph_row *row,
7957 clip_rect.width = window_width; 8751 clip_rect.width = window_width;
7958 clip_rect.height = row->visible_height; 8752 clip_rect.height = row->visible_height;
7959 8753
7960 XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, &clip_rect, 1, Unsorted); 8754 x_set_clip_rectangles (f, gc, &clip_rect, 1);
7961} 8755}
7962 8756
7963 8757
@@ -8006,8 +8800,8 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
8006 } 8800 }
8007 /* Set clipping, draw the rectangle, and reset clipping again. */ 8801 /* Set clipping, draw the rectangle, and reset clipping again. */
8008 x_clip_to_row (w, row, TEXT_AREA, gc); 8802 x_clip_to_row (w, row, TEXT_AREA, gc);
8009 XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h - 1); 8803 x_draw_rectangle (f, gc, x, y, wd, h - 1);
8010 XSetClipMask (dpy, gc, None); 8804 x_reset_clip_rectangles (f, gc);
8011} 8805}
8012 8806
8013 8807
@@ -8085,7 +8879,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
8085 if ((cursor_glyph->resolved_level & 1) != 0) 8879 if ((cursor_glyph->resolved_level & 1) != 0)
8086 x += cursor_glyph->pixel_width - width; 8880 x += cursor_glyph->pixel_width - width;
8087 8881
8088 XFillRectangle (dpy, window, gc, x, 8882 x_fill_rectangle (f, gc, x,
8089 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), 8883 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
8090 width, row->height); 8884 width, row->height);
8091 } 8885 }
@@ -8105,13 +8899,13 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
8105 if ((cursor_glyph->resolved_level & 1) != 0 8899 if ((cursor_glyph->resolved_level & 1) != 0
8106 && cursor_glyph->pixel_width > w->phys_cursor_width - 1) 8900 && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
8107 x += cursor_glyph->pixel_width - w->phys_cursor_width + 1; 8901 x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
8108 XFillRectangle (dpy, window, gc, x, 8902 x_fill_rectangle (f, gc, x,
8109 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + 8903 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
8110 row->height - width), 8904 row->height - width),
8111 w->phys_cursor_width - 1, width); 8905 w->phys_cursor_width - 1, width);
8112 } 8906 }
8113 8907
8114 XSetClipMask (dpy, gc, None); 8908 x_reset_clip_rectangles (f, gc);
8115 } 8909 }
8116} 8910}
8117 8911
@@ -8133,7 +8927,7 @@ x_define_frame_cursor (struct frame *f, Cursor cursor)
8133static void 8927static void
8134x_clear_frame_area (struct frame *f, int x, int y, int width, int height) 8928x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
8135{ 8929{
8136 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), x, y, width, height); 8930 x_clear_area (f, x, y, width, height);
8137#ifdef USE_GTK 8931#ifdef USE_GTK
8138 /* Must queue a redraw, because scroll bars might have been cleared. */ 8932 /* Must queue a redraw, because scroll bars might have been cleared. */
8139 if (FRAME_GTK_WIDGET (f)) 8933 if (FRAME_GTK_WIDGET (f))
@@ -10247,6 +11041,7 @@ x_free_frame_resources (struct frame *f)
10247 free_frame_xic (f); 11041 free_frame_xic (f);
10248#endif 11042#endif
10249 11043
11044 x_free_cr_resources (f);
10250#ifdef USE_X_TOOLKIT 11045#ifdef USE_X_TOOLKIT
10251 if (f->output_data.x->widget) 11046 if (f->output_data.x->widget)
10252 { 11047 {
@@ -11333,6 +12128,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11333 x_session_initialize (dpyinfo); 12128 x_session_initialize (dpyinfo);
11334#endif 12129#endif
11335 12130
12131#ifdef USE_CAIRO
12132 x_extension_initialize (dpyinfo);
12133#endif
12134
11336 unblock_input (); 12135 unblock_input ();
11337 12136
11338 return dpyinfo; 12137 return dpyinfo;
@@ -11444,8 +12243,13 @@ static struct redisplay_interface x_redisplay_interface =
11444 x_get_glyph_overhangs, 12243 x_get_glyph_overhangs,
11445 x_fix_overlapping_area, 12244 x_fix_overlapping_area,
11446 x_draw_fringe_bitmap, 12245 x_draw_fringe_bitmap,
12246#ifdef USE_CAIRO
12247 x_cr_define_fringe_bitmap,
12248 x_cr_destroy_fringe_bitmap,
12249#else
11447 0, /* define_fringe_bitmap */ 12250 0, /* define_fringe_bitmap */
11448 0, /* destroy_fringe_bitmap */ 12251 0, /* destroy_fringe_bitmap */
12252#endif
11449 x_compute_glyph_string_overhangs, 12253 x_compute_glyph_string_overhangs,
11450 x_draw_glyph_string, 12254 x_draw_glyph_string,
11451 x_define_frame_cursor, 12255 x_define_frame_cursor,
@@ -11623,6 +12427,10 @@ x_initialize (void)
11623#endif 12427#endif
11624#endif 12428#endif
11625 12429
12430#ifdef USE_CAIRO
12431 x_cr_init_fringe (&x_redisplay_interface);
12432#endif
12433
11626 /* Note that there is no real way portable across R3/R4 to get the 12434 /* Note that there is no real way portable across R3/R4 to get the
11627 original error handler. */ 12435 original error handler. */
11628 XSetErrorHandler (x_error_handler); 12436 XSetErrorHandler (x_error_handler);