@@ -61,8 +61,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
6161
6262#define STORE_KEYSYM_FOR_DEBUG (keysym ) ((void)0)
6363
64- #define FRAME_CR_CONTEXT (f ) ((f)->output_data.pgtk->cr_context)
65- #define FRAME_CR_SURFACE (f ) ((f)->output_data.pgtk->cr_surface)
64+ #define FRAME_CR_CONTEXT (f ) ((f)->output_data.pgtk->cr_context)
65+ #define FRAME_CR_ACTIVE_CONTEXT (f ) ((f)->output_data.pgtk->cr_active)
66+ #define FRAME_CR_SURFACE (f ) (cairo_get_target(FRAME_CR_CONTEXT(f)))
6667#define FRAME_CR_SURFACE_DESIRED_WIDTH (f ) \
6768 ((f)->output_data.pgtk->cr_surface_desired_width)
6869#define FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) \
@@ -95,6 +96,22 @@ static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
9596static struct frame *
9697pgtk_any_window_to_frame (GdkWindow * window );
9798
99+ static void flip_cr_context (struct frame * f )
100+ {
101+ APGTK_TRACE ("flip_cr_context" );
102+ cairo_t * cr = FRAME_CR_ACTIVE_CONTEXT (f );
103+
104+ block_input ();
105+ if ( cr != FRAME_CR_CONTEXT (f ))
106+ {
107+ cairo_destroy (cr );
108+ FRAME_CR_ACTIVE_CONTEXT (f ) = cairo_reference (FRAME_CR_CONTEXT (f ));
109+
110+ }
111+ unblock_input ();
112+ }
113+
114+
98115static void evq_enqueue (union buffered_input_event * ev )
99116{
100117 struct event_queue_t * evq = & event_q ;
@@ -2665,8 +2682,6 @@ pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
26652682 xic_set_preeditarea (w , x , y );
26662683#endif
26672684 }
2668-
2669- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
26702685}
26712686
26722687static void
@@ -2769,24 +2784,6 @@ pgtk_scroll_run (struct window *w, struct run *run)
27692784static void
27702785pgtk_update_begin (struct frame * f )
27712786{
2772- if (! NILP (tip_frame ) && XFRAME (tip_frame ) == f
2773- && ! FRAME_VISIBLE_P (f ))
2774- return ;
2775-
2776- if (! FRAME_CR_SURFACE (f ))
2777- {
2778- int width = FRAME_PIXEL_WIDTH (f );
2779- int height = FRAME_PIXEL_HEIGHT (f );
2780-
2781- if (width > 0 && height > 0 )
2782- {
2783- block_input ();
2784- FRAME_CR_SURFACE (f ) = cairo_image_surface_create
2785- (CAIRO_FORMAT_ARGB32 , width , height );
2786- unblock_input ();
2787- }
2788- }
2789-
27902787 pgtk_clear_under_internal_border (f );
27912788}
27922789
@@ -2949,8 +2946,12 @@ pgtk_update_window_end (struct window *w, bool cursor_on_p,
29492946static void
29502947pgtk_update_end (struct frame * f )
29512948{
2949+ GtkWidget * widget = FRAME_GTK_WIDGET (f );
29522950 /* Mouse highlight may be displayed again. */
29532951 MOUSE_HL_INFO (f )-> mouse_face_defer = false;
2952+
2953+ gtk_widget_queue_draw (widget );
2954+ flip_cr_context (f );
29542955}
29552956
29562957/* Return the current position of the mouse.
@@ -3123,13 +3124,10 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
31233124 int src_x , int src_y , int width , int height ,
31243125 int dest_x , int dest_y , bool overlay_p )
31253126{
3126- cairo_t * cr ;
3127- cairo_matrix_t matrix ;
3128- cairo_surface_t * surface ;
3129- cairo_format_t format ;
3127+ cairo_t * cr = pgtk_begin_cr_clip (f );
31303128
31313129 PGTK_TRACE ("pgtk_cr_draw_image: 0: %d,%d,%d,%d,%d,%d,%d." , src_x , src_y , width , height , dest_x , dest_y , overlay_p );
3132- cr = pgtk_begin_cr_clip ( f );
3130+
31333131 if (overlay_p )
31343132 cairo_rectangle (cr , dest_x , dest_y , width , height );
31353133 else
@@ -3138,42 +3136,24 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
31383136 cairo_rectangle (cr , dest_x , dest_y , width , height );
31393137 cairo_fill_preserve (cr );
31403138 }
3141- cairo_clip (cr );
3142- cairo_matrix_init_translate ( & matrix , src_x - dest_x , src_y - dest_y );
3143- cairo_pattern_set_matrix ( image , & matrix ) ;
3139+ cairo_translate (cr , dest_x - src_x , dest_y - src_y );
3140+
3141+ cairo_surface_t * surface ;
31443142 cairo_pattern_get_surface (image , & surface );
3145- format = cairo_image_surface_get_format (surface );
3143+ cairo_format_t format = cairo_image_surface_get_format (surface );
31463144 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1 )
31473145 {
3148- PGTK_TRACE ("other format." );
31493146 cairo_set_source (cr , image );
31503147 cairo_fill (cr );
31513148 }
31523149 else
31533150 {
3154- if (format == CAIRO_FORMAT_A8 )
3155- PGTK_TRACE ("format A8." );
3156- else if (format == CAIRO_FORMAT_A1 )
3157- PGTK_TRACE ("format A1." );
3158- else
3159- PGTK_TRACE ("format ??." );
31603151 pgtk_set_cr_source_with_gc_foreground (f , gc );
3161- cairo_rectangle_list_t * rects = cairo_copy_clip_rectangle_list (cr );
3162- PGTK_TRACE ("rects:" );
3163- PGTK_TRACE (" status: %u" , rects -> status );
3164- PGTK_TRACE (" rectangles:" );
3165- for (int i = 0 ; i < rects -> num_rectangles ; i ++ ) {
3166- PGTK_TRACE (" %fx%f+%f+%f" ,
3167- rects -> rectangles [i ].width ,
3168- rects -> rectangles [i ].height ,
3169- rects -> rectangles [i ].x ,
3170- rects -> rectangles [i ].y );
3171- }
3172- cairo_rectangle_list_destroy (rects );
3152+ cairo_clip (cr );
31733153 cairo_mask (cr , image );
31743154 }
3155+
31753156 pgtk_end_cr_clip (f );
3176- PGTK_TRACE ("pgtk_cr_draw_image: 9." );
31773157}
31783158
31793159static void
@@ -3358,8 +3338,6 @@ recover_from_visible_bell(struct atimer *timer)
33583338
33593339 if (FRAME_X_OUTPUT (f )-> atimer_visible_bell != NULL )
33603340 FRAME_X_OUTPUT (f )-> atimer_visible_bell = NULL ;
3361-
3362- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
33633341}
33643342
33653343static void
@@ -3419,8 +3397,6 @@ pgtk_flash (struct frame *f)
34193397 width , height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f ));
34203398
34213399 FRAME_X_OUTPUT (f )-> cr_surface_visible_bell = surface ;
3422- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
3423-
34243400 {
34253401 struct timespec delay = make_timespec (0 , 50 * 1000 * 1000 );
34263402 if (FRAME_X_OUTPUT (f )-> atimer_visible_bell != NULL ) {
@@ -4828,12 +4804,12 @@ pgtk_handle_draw(GtkWidget *widget, cairo_t *cr, gpointer *data)
48284804 PGTK_TRACE (" f=%p" , f );
48294805 if (f != NULL ) {
48304806 src = FRAME_X_OUTPUT (f )-> cr_surface_visible_bell ;
4831- if (src == NULL )
4832- src = FRAME_CR_SURFACE ( f );
4807+ if (src == NULL && FRAME_CR_ACTIVE_CONTEXT ( f ) != NULL )
4808+ src = cairo_get_target ( FRAME_CR_ACTIVE_CONTEXT ( f ) );
48334809 }
4834- PGTK_TRACE (" surface=%p" , src );
4810+ APGTK_TRACE (" surface=%p" , src );
48354811 if (src != NULL ) {
4836- PGTK_TRACE (" resized_p=%d" , f -> resized_p );
4812+ APGTK_TRACE (" resized_p=%d" , f -> resized_p );
48374813 PGTK_TRACE (" garbaged=%d" , f -> garbaged );
48384814 PGTK_TRACE (" scroll_bar_width=%f" , (double ) PGTK_SCROLL_BAR_WIDTH (f ));
48394815 // PGTK_TRACE(" scroll_bar_adjust=%d", PGTK_SCROLL_BAR_ADJUST(f));
@@ -6580,27 +6556,10 @@ pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height)
65806556 if (FRAME_CR_SURFACE_DESIRED_WIDTH (f ) != width
65816557 || FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) != height )
65826558 {
6583- cairo_surface_t * old_surface = FRAME_CR_SURFACE (f );
6584- cairo_t * cr = NULL ;
6585- cairo_t * old_cr = FRAME_CR_CONTEXT (f );
6586- FRAME_CR_SURFACE (f ) = gdk_window_create_similar_surface (gtk_widget_get_window (FRAME_GTK_WIDGET (f )),
6587- CAIRO_CONTENT_COLOR_ALPHA ,
6588- width ,
6589- height );
6590-
6591- if (old_surface ){
6592- cr = cairo_create (FRAME_CR_SURFACE (f ));
6593- cairo_set_source_surface (cr , old_surface , 0 , 0 );
6594-
6595- cairo_paint (cr );
6596- FRAME_CR_CONTEXT (f ) = cr ;
6597-
6598- cairo_destroy (old_cr );
6599- cairo_surface_destroy (old_surface );
6600- }
6601- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
6559+ pgtk_cr_destroy_frame_context (f );
66026560 FRAME_CR_SURFACE_DESIRED_WIDTH (f ) = width ;
66036561 FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) = height ;
6562+ SET_FRAME_GARBAGED (f );
66046563 }
66056564}
66066565
@@ -6611,16 +6570,17 @@ pgtk_begin_cr_clip (struct frame *f)
66116570 cairo_t * cr = FRAME_CR_CONTEXT (f );
66126571
66136572 PGTK_TRACE ("pgtk_begin_cr_clip" );
6614- if (! FRAME_CR_SURFACE (f ))
6615- {
6616- FRAME_CR_SURFACE (f ) = gdk_window_create_similar_surface (gtk_widget_get_window (FRAME_GTK_WIDGET (f )),
6617- CAIRO_CONTENT_COLOR_ALPHA ,
6618- FRAME_PIXEL_WIDTH (f ),
6619- FRAME_PIXEL_HEIGHT (f ));
6620- }
6621-
66226573 if (!cr )
66236574 {
6575+ cairo_surface_t * surface =
6576+ gdk_window_create_similar_surface (gtk_widget_get_window (FRAME_GTK_WIDGET (f )),
6577+ CAIRO_CONTENT_COLOR_ALPHA ,
6578+ FRAME_CR_SURFACE_DESIRED_WIDTH (f ),
6579+ FRAME_CR_SURFACE_DESIRED_HEIGHT (f ));
6580+
6581+ cr = FRAME_CR_CONTEXT (f ) = cairo_create (surface );
6582+ cairo_surface_destroy (surface );
6583+
66246584 cr = cairo_create (FRAME_CR_SURFACE (f ));
66256585 FRAME_CR_CONTEXT (f ) = cr ;
66266586 }
@@ -6635,9 +6595,6 @@ pgtk_end_cr_clip (struct frame *f)
66356595{
66366596 PGTK_TRACE ("pgtk_end_cr_clip" );
66376597 cairo_restore (FRAME_CR_CONTEXT (f ));
6638-
6639- GtkWidget * widget = FRAME_GTK_WIDGET (f );
6640- gtk_widget_queue_draw (widget );
66416598}
66426599
66436600void
@@ -6674,18 +6631,13 @@ pgtk_cr_draw_frame (cairo_t *cr, struct frame *f)
66746631}
66756632
66766633void
6677- pgtk_cr_destroy_surface (struct frame * f )
6634+ pgtk_cr_destroy_frame_context (struct frame * f )
66786635{
6679- PGTK_TRACE ("pgtk_cr_destroy_surface " );
6636+ PGTK_TRACE ("pgtk_cr_destroy_frame_context " );
66806637 if (FRAME_CR_CONTEXT (f ) != NULL ) {
66816638 cairo_destroy (FRAME_CR_CONTEXT (f ));
66826639 FRAME_CR_CONTEXT (f ) = NULL ;
66836640 }
6684- if (FRAME_CR_SURFACE (f ) != NULL ) {
6685- cairo_surface_destroy (FRAME_CR_SURFACE (f ));
6686- FRAME_CR_SURFACE (f ) = NULL ;
6687- }
6688- SET_FRAME_GARBAGED (f );
66896641}
66906642
66916643void
0 commit comments