diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 998 |
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 *); | |||
| 220 | static struct terminal *x_create_terminal (struct x_display_info *); | 223 | static struct terminal *x_create_terminal (struct x_display_info *); |
| 221 | static void x_update_end (struct frame *); | 224 | static void x_update_end (struct frame *); |
| 222 | static void XTframe_up_to_date (struct frame *); | 225 | static void XTframe_up_to_date (struct frame *); |
| 226 | static void x_clear_area1 (Display *, Window, int, int, int, int, int); | ||
| 223 | static void x_clear_frame (struct frame *); | 227 | static void x_clear_frame (struct frame *); |
| 224 | static _Noreturn void x_ins_del_lines (struct frame *, int, int); | 228 | static _Noreturn void x_ins_del_lines (struct frame *, int, int); |
| 225 | static void frame_highlight (struct frame *); | 229 | static void frame_highlight (struct frame *); |
| @@ -325,6 +329,587 @@ record_event (char *locus, int type) | |||
| 325 | 329 | ||
| 326 | #endif | 330 | #endif |
| 327 | 331 | ||
| 332 | static void x_free_cr_resources (struct frame *); | ||
| 333 | static void x_set_clip_rectangles (struct frame *, GC, XRectangle *, int); | ||
| 334 | static void x_reset_clip_rectangles (struct frame *, GC); | ||
| 335 | static void x_fill_rectangle (struct frame *, GC, int, int, int, int); | ||
| 336 | static void x_draw_rectangle (struct frame *, GC, int, int, int, int); | ||
| 337 | static void x_fill_trapezoid_for_relief (struct frame *, GC, int, int, | ||
| 338 | int, int, int); | ||
| 339 | static void x_clear_window (struct frame *); | ||
| 340 | |||
| 341 | #ifdef USE_CAIRO | ||
| 342 | static struct x_gc_ext_data *x_gc_get_ext_data (struct frame *, GC, int); | ||
| 343 | static void x_extension_initialize (struct x_display_info *); | ||
| 344 | static 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 | |||
| 351 | static struct x_gc_ext_data * | ||
| 352 | x_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 | |||
| 376 | static void | ||
| 377 | x_extension_initialize (struct x_display_info *dpyinfo) | ||
| 378 | { | ||
| 379 | XExtCodes *ext_codes = XAddExtension (dpyinfo->display); | ||
| 380 | |||
| 381 | dpyinfo->ext_codes = ext_codes; | ||
| 382 | } | ||
| 383 | |||
| 384 | static void | ||
| 385 | x_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 | |||
| 397 | cairo_t * | ||
| 398 | x_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 | |||
| 442 | void | ||
| 443 | x_end_cr_clip (struct frame *f) | ||
| 444 | { | ||
| 445 | cairo_restore (FRAME_CR_CONTEXT (f)); | ||
| 446 | } | ||
| 447 | |||
| 448 | void | ||
| 449 | x_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 | |||
| 461 | void | ||
| 462 | x_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 | |||
| 476 | static int max_fringe_bmp = 0; | ||
| 477 | static cairo_pattern_t **fringe_bmp = 0; | ||
| 478 | |||
| 479 | static void | ||
| 480 | x_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 | |||
| 517 | static void | ||
| 518 | x_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 | |||
| 532 | static void | ||
| 533 | x_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 | |||
| 569 | void | ||
| 570 | x_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 | |||
| 584 | static cairo_status_t | ||
| 585 | x_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 | |||
| 595 | static void | ||
| 596 | x_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 | |||
| 605 | Lisp_Object | ||
| 606 | x_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 | |||
| 704 | static void | ||
| 705 | x_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 | |||
| 733 | static void | ||
| 734 | x_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 | |||
| 749 | static void | ||
| 750 | x_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 | |||
| 763 | static void | ||
| 764 | x_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 | |||
| 780 | static void | ||
| 781 | x_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 | |||
| 798 | static void | ||
| 799 | x_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 | ||
| 814 | static void | ||
| 815 | x_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 | |||
| 830 | enum 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 | |||
| 839 | static void | ||
| 840 | x_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 | |||
| 872 | static void | ||
| 873 | x_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) | |||
| 452 | static void | 1037 | static void |
| 453 | x_update_begin (struct frame *f) | 1038 | x_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 | |||
| 2560 | x_draw_underwave (struct glyph_string *s) | 3323 | x_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 | ||
| 3689 | static void | ||
| 3690 | x_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 | |||
| 2921 | void | 3698 | void |
| 2922 | x_clear_area (Display *dpy, Window window, int x, int y, int width, int height) | 3699 | x_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 | ||
| 4253 | static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part, | 5046 | static 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) | |||
| 8133 | static void | 8927 | static void |
| 8134 | x_clear_frame_area (struct frame *f, int x, int y, int width, int height) | 8928 | x_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); |