diff options
| author | Po Lu | 2022-05-03 09:22:06 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-03 09:22:06 +0800 |
| commit | 952cc28e58eafbdd409bf36f9ca656dae533542b (patch) | |
| tree | f51c18a73cff22d3b0b8294430b838cf59efbff6 /src/xterm.c | |
| parent | 64bcfcbd322d4fdb78c7d7dd0748dabc0e0b2cbc (diff) | |
| download | emacs-952cc28e58eafbdd409bf36f9ca656dae533542b.tar.gz emacs-952cc28e58eafbdd409bf36f9ca656dae533542b.zip | |
Clean up X11 double buffering code
This fixes several latent bugs where code went down the path
with double buffering enabled when it wasn't, and vice versa.
* src/xfns.c (x_set_inhibit_double_buffering): Improve
commentary and only define when HAVE_XDBE.
(x_mark_frame_dirty): Only set buffer flip flag when HAVE_XDBE.
(initial_set_up_x_back_buffer): Clean up coding style and remove
unnecessary block_input pair.
(Fx_double_buffered_p): Always return nil if !HAVE_XDBE.
(x_frame_parm_handlers): Don't set double buffering handler if
!HAVE_XDBE.
* src/xftfont.c (xftfont_drop_xrender_surfaces, xftfont_driver):
Only define when XDBE is available.
* src/xterm.c (x_drop_xrender_surfaces): Likewise.
(x_clear_window): Don't test double buffering flags when
!HAVE_XDBE.
(show_back_buffer): Only define when HAVE_XDBE.
(x_flip_and_flush): Don't try to flip when !HAVE_XDBE.
(XTframe_up_to_date): Likewise.
(XTbuffer_flipping_unblocked_hook): Only define when Xdbe is
available.
(x_clear_area): Don't test double buffering flags when Xdbe is
not available.
(flush_dirty_back_buffer_on): Don't define if there's no DBE.
(handle_one_xevent, x_create_terminal): Likewise.
* src/xterm.h (FRAME_X_DRAWABLE): Fix coding style.
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/src/xterm.c b/src/xterm.c index 517869dde34..adfe90522d4 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -3780,6 +3780,7 @@ x_flush (struct frame *f) | |||
| 3780 | unblock_input (); | 3780 | unblock_input (); |
| 3781 | } | 3781 | } |
| 3782 | 3782 | ||
| 3783 | #ifdef HAVE_XDBE | ||
| 3783 | static void | 3784 | static void |
| 3784 | x_drop_xrender_surfaces (struct frame *f) | 3785 | x_drop_xrender_surfaces (struct frame *f) |
| 3785 | { | 3786 | { |
| @@ -3795,6 +3796,7 @@ x_drop_xrender_surfaces (struct frame *f) | |||
| 3795 | } | 3796 | } |
| 3796 | #endif | 3797 | #endif |
| 3797 | } | 3798 | } |
| 3799 | #endif | ||
| 3798 | 3800 | ||
| 3799 | #ifdef HAVE_XRENDER | 3801 | #ifdef HAVE_XRENDER |
| 3800 | void | 3802 | void |
| @@ -5127,9 +5129,14 @@ x_clear_window (struct frame *f) | |||
| 5127 | x_end_cr_clip (f); | 5129 | x_end_cr_clip (f); |
| 5128 | #else | 5130 | #else |
| 5129 | #ifndef USE_GTK | 5131 | #ifndef USE_GTK |
| 5130 | if (FRAME_X_DOUBLE_BUFFERED_P (f) || (f->alpha_background != 1.0)) | 5132 | if (f->alpha_background != 1.0 |
| 5133 | #ifdef HAVE_XDBE | ||
| 5134 | || FRAME_X_DOUBLE_BUFFERED_P (f) | ||
| 5131 | #endif | 5135 | #endif |
| 5132 | x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); | 5136 | ) |
| 5137 | #endif | ||
| 5138 | x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), | ||
| 5139 | FRAME_PIXEL_HEIGHT (f)); | ||
| 5133 | #ifndef USE_GTK | 5140 | #ifndef USE_GTK |
| 5134 | else | 5141 | else |
| 5135 | XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 5142 | XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| @@ -5456,13 +5463,15 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) | |||
| 5456 | /* Show the frame back buffer. If frame is double-buffered, | 5463 | /* Show the frame back buffer. If frame is double-buffered, |
| 5457 | atomically publish to the user's screen graphics updates made since | 5464 | atomically publish to the user's screen graphics updates made since |
| 5458 | the last call to show_back_buffer. */ | 5465 | the last call to show_back_buffer. */ |
| 5466 | |||
| 5467 | #ifdef HAVE_XDBE | ||
| 5459 | static void | 5468 | static void |
| 5460 | show_back_buffer (struct frame *f) | 5469 | show_back_buffer (struct frame *f) |
| 5461 | { | 5470 | { |
| 5462 | block_input (); | 5471 | block_input (); |
| 5472 | |||
| 5463 | if (FRAME_X_DOUBLE_BUFFERED_P (f)) | 5473 | if (FRAME_X_DOUBLE_BUFFERED_P (f)) |
| 5464 | { | 5474 | { |
| 5465 | #ifdef HAVE_XDBE | ||
| 5466 | #ifdef USE_CAIRO | 5475 | #ifdef USE_CAIRO |
| 5467 | cairo_t *cr = FRAME_CR_CONTEXT (f); | 5476 | cairo_t *cr = FRAME_CR_CONTEXT (f); |
| 5468 | if (cr) | 5477 | if (cr) |
| @@ -5473,13 +5482,12 @@ show_back_buffer (struct frame *f) | |||
| 5473 | swap_info.swap_window = FRAME_X_WINDOW (f); | 5482 | swap_info.swap_window = FRAME_X_WINDOW (f); |
| 5474 | swap_info.swap_action = XdbeCopied; | 5483 | swap_info.swap_action = XdbeCopied; |
| 5475 | XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1); | 5484 | XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1); |
| 5476 | #else | ||
| 5477 | eassert (!"should have back-buffer only with XDBE"); | ||
| 5478 | #endif | ||
| 5479 | } | 5485 | } |
| 5480 | FRAME_X_NEED_BUFFER_FLIP (f) = false; | 5486 | FRAME_X_NEED_BUFFER_FLIP (f) = false; |
| 5487 | |||
| 5481 | unblock_input (); | 5488 | unblock_input (); |
| 5482 | } | 5489 | } |
| 5490 | #endif | ||
| 5483 | 5491 | ||
| 5484 | /* Updates back buffer and flushes changes to display. Called from | 5492 | /* Updates back buffer and flushes changes to display. Called from |
| 5485 | minibuf read code. Note that we display the back buffer even if | 5493 | minibuf read code. Note that we display the back buffer even if |
| @@ -5488,8 +5496,10 @@ static void | |||
| 5488 | x_flip_and_flush (struct frame *f) | 5496 | x_flip_and_flush (struct frame *f) |
| 5489 | { | 5497 | { |
| 5490 | block_input (); | 5498 | block_input (); |
| 5499 | #ifdef HAVE_XDBE | ||
| 5491 | if (FRAME_X_NEED_BUFFER_FLIP (f)) | 5500 | if (FRAME_X_NEED_BUFFER_FLIP (f)) |
| 5492 | show_back_buffer (f); | 5501 | show_back_buffer (f); |
| 5502 | #endif | ||
| 5493 | x_flush (f); | 5503 | x_flush (f); |
| 5494 | unblock_input (); | 5504 | unblock_input (); |
| 5495 | } | 5505 | } |
| @@ -5538,8 +5548,12 @@ XTframe_up_to_date (struct frame *f) | |||
| 5538 | eassert (FRAME_X_P (f)); | 5548 | eassert (FRAME_X_P (f)); |
| 5539 | block_input (); | 5549 | block_input (); |
| 5540 | FRAME_MOUSE_UPDATE (f); | 5550 | FRAME_MOUSE_UPDATE (f); |
| 5541 | if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f)) | 5551 | |
| 5552 | #ifdef HAVE_XDBE | ||
| 5553 | if (!buffer_flipping_blocked_p () | ||
| 5554 | && FRAME_X_NEED_BUFFER_FLIP (f)) | ||
| 5542 | show_back_buffer (f); | 5555 | show_back_buffer (f); |
| 5556 | #endif | ||
| 5543 | 5557 | ||
| 5544 | #ifdef HAVE_XSYNC | 5558 | #ifdef HAVE_XSYNC |
| 5545 | #ifndef HAVE_GTK3 | 5559 | #ifndef HAVE_GTK3 |
| @@ -5592,12 +5606,14 @@ XTframe_up_to_date (struct frame *f) | |||
| 5592 | unblock_input (); | 5606 | unblock_input (); |
| 5593 | } | 5607 | } |
| 5594 | 5608 | ||
| 5609 | #ifdef HAVE_XDBE | ||
| 5595 | static void | 5610 | static void |
| 5596 | XTbuffer_flipping_unblocked_hook (struct frame *f) | 5611 | XTbuffer_flipping_unblocked_hook (struct frame *f) |
| 5597 | { | 5612 | { |
| 5598 | if (FRAME_X_NEED_BUFFER_FLIP (f)) | 5613 | if (FRAME_X_NEED_BUFFER_FLIP (f)) |
| 5599 | show_back_buffer (f); | 5614 | show_back_buffer (f); |
| 5600 | } | 5615 | } |
| 5616 | #endif | ||
| 5601 | 5617 | ||
| 5602 | /** | 5618 | /** |
| 5603 | * x_clear_under_internal_border: | 5619 | * x_clear_under_internal_border: |
| @@ -8716,8 +8732,11 @@ x_clear_area (struct frame *f, int x, int y, int width, int height) | |||
| 8716 | x_end_cr_clip (f); | 8732 | x_end_cr_clip (f); |
| 8717 | #else | 8733 | #else |
| 8718 | #ifndef USE_GTK | 8734 | #ifndef USE_GTK |
| 8719 | if (FRAME_X_DOUBLE_BUFFERED_P (f) | 8735 | if (f->alpha_background != 1.0 |
| 8720 | || f->alpha_background != 1.0) | 8736 | #ifdef HAVE_XDBE |
| 8737 | || FRAME_X_DOUBLE_BUFFERED_P (f) | ||
| 8738 | #endif | ||
| 8739 | ) | ||
| 8721 | #endif | 8740 | #endif |
| 8722 | { | 8741 | { |
| 8723 | #if defined HAVE_XRENDER && \ | 8742 | #if defined HAVE_XRENDER && \ |
| @@ -13738,7 +13757,9 @@ x_net_wm_state (struct frame *f, Window window) | |||
| 13738 | store_frame_param (f, Qshaded, shaded ? Qt : Qnil); | 13757 | store_frame_param (f, Qshaded, shaded ? Qt : Qnil); |
| 13739 | } | 13758 | } |
| 13740 | 13759 | ||
| 13741 | /* Flip back buffers on FRAME if it has undrawn content. */ | 13760 | /* Flip back buffers on F if it has undrawn content. */ |
| 13761 | |||
| 13762 | #ifdef HAVE_XDBE | ||
| 13742 | static void | 13763 | static void |
| 13743 | flush_dirty_back_buffer_on (struct frame *f) | 13764 | flush_dirty_back_buffer_on (struct frame *f) |
| 13744 | { | 13765 | { |
| @@ -13749,6 +13770,7 @@ flush_dirty_back_buffer_on (struct frame *f) | |||
| 13749 | show_back_buffer (f); | 13770 | show_back_buffer (f); |
| 13750 | unblock_input (); | 13771 | unblock_input (); |
| 13751 | } | 13772 | } |
| 13773 | #endif | ||
| 13752 | 13774 | ||
| 13753 | #ifdef HAVE_GTK3 | 13775 | #ifdef HAVE_GTK3 |
| 13754 | void | 13776 | void |
| @@ -14707,8 +14729,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14707 | SET_FRAME_ICONIFIED (f, false); | 14729 | SET_FRAME_ICONIFIED (f, false); |
| 14708 | } | 14730 | } |
| 14709 | 14731 | ||
| 14732 | #ifdef HAVE_XDBE | ||
| 14710 | if (FRAME_X_DOUBLE_BUFFERED_P (f)) | 14733 | if (FRAME_X_DOUBLE_BUFFERED_P (f)) |
| 14711 | x_drop_xrender_surfaces (f); | 14734 | x_drop_xrender_surfaces (f); |
| 14735 | #endif | ||
| 14712 | f->output_data.x->has_been_visible = true; | 14736 | f->output_data.x->has_been_visible = true; |
| 14713 | SET_FRAME_GARBAGED (f); | 14737 | SET_FRAME_GARBAGED (f); |
| 14714 | unblock_input (); | 14738 | unblock_input (); |
| @@ -14753,8 +14777,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14753 | #endif | 14777 | #endif |
| 14754 | } | 14778 | } |
| 14755 | 14779 | ||
| 14780 | #ifdef HAVE_XDBE | ||
| 14756 | if (!FRAME_GARBAGED_P (f)) | 14781 | if (!FRAME_GARBAGED_P (f)) |
| 14757 | show_back_buffer (f); | 14782 | show_back_buffer (f); |
| 14783 | #endif | ||
| 14758 | } | 14784 | } |
| 14759 | else | 14785 | else |
| 14760 | { | 14786 | { |
| @@ -14802,7 +14828,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14802 | #ifdef USE_GTK | 14828 | #ifdef USE_GTK |
| 14803 | x_clear_under_internal_border (f); | 14829 | x_clear_under_internal_border (f); |
| 14804 | #endif | 14830 | #endif |
| 14831 | #ifdef HAVE_XDBE | ||
| 14805 | show_back_buffer (f); | 14832 | show_back_buffer (f); |
| 14833 | #endif | ||
| 14806 | } | 14834 | } |
| 14807 | #ifdef USE_X_TOOLKIT | 14835 | #ifdef USE_X_TOOLKIT |
| 14808 | else | 14836 | else |
| @@ -16016,8 +16044,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 16016 | for size changes: that's not sufficient. We miss some | 16044 | for size changes: that's not sufficient. We miss some |
| 16017 | surface invalidations and flicker. */ | 16045 | surface invalidations and flicker. */ |
| 16018 | block_input (); | 16046 | block_input (); |
| 16047 | #ifdef HAVE_XDBE | ||
| 16019 | if (f && FRAME_X_DOUBLE_BUFFERED_P (f)) | 16048 | if (f && FRAME_X_DOUBLE_BUFFERED_P (f)) |
| 16020 | x_drop_xrender_surfaces (f); | 16049 | x_drop_xrender_surfaces (f); |
| 16050 | #endif | ||
| 16021 | unblock_input (); | 16051 | unblock_input (); |
| 16022 | #if defined USE_CAIRO && !defined USE_GTK | 16052 | #if defined USE_CAIRO && !defined USE_GTK |
| 16023 | if (f) | 16053 | if (f) |
| @@ -19447,11 +19477,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19447 | redisplay. To ensure that these changes become visible, draw | 19477 | redisplay. To ensure that these changes become visible, draw |
| 19448 | them here. */ | 19478 | them here. */ |
| 19449 | 19479 | ||
| 19480 | #ifdef HAVE_XDBE | ||
| 19450 | if (f) | 19481 | if (f) |
| 19451 | flush_dirty_back_buffer_on (f); | 19482 | flush_dirty_back_buffer_on (f); |
| 19452 | 19483 | ||
| 19453 | if (any && any != f) | 19484 | if (any && any != f) |
| 19454 | flush_dirty_back_buffer_on (any); | 19485 | flush_dirty_back_buffer_on (any); |
| 19486 | #endif | ||
| 19455 | return count; | 19487 | return count; |
| 19456 | } | 19488 | } |
| 19457 | 19489 | ||
| @@ -24309,7 +24341,9 @@ x_create_terminal (struct x_display_info *dpyinfo) | |||
| 24309 | terminal->update_end_hook = x_update_end; | 24341 | terminal->update_end_hook = x_update_end; |
| 24310 | terminal->read_socket_hook = XTread_socket; | 24342 | terminal->read_socket_hook = XTread_socket; |
| 24311 | terminal->frame_up_to_date_hook = XTframe_up_to_date; | 24343 | terminal->frame_up_to_date_hook = XTframe_up_to_date; |
| 24344 | #ifdef HAVE_XDBE | ||
| 24312 | terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook; | 24345 | terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook; |
| 24346 | #endif | ||
| 24313 | terminal->defined_color_hook = x_defined_color; | 24347 | terminal->defined_color_hook = x_defined_color; |
| 24314 | terminal->query_frame_background_color = x_query_frame_background_color; | 24348 | terminal->query_frame_background_color = x_query_frame_background_color; |
| 24315 | terminal->query_colors = x_query_colors; | 24349 | terminal->query_colors = x_query_colors; |