@@ -61,8 +61,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
61
61
62
62
#define STORE_KEYSYM_FOR_DEBUG (keysym ) ((void)0)
63
63
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)))
66
67
#define FRAME_CR_SURFACE_DESIRED_WIDTH (f ) \
67
68
((f)->output_data.pgtk->cr_surface_desired_width)
68
69
#define FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) \
@@ -95,6 +96,22 @@ static void pgtk_clip_to_row (struct window *w, struct glyph_row *row,
95
96
static struct frame *
96
97
pgtk_any_window_to_frame (GdkWindow * window );
97
98
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
+
98
115
static void evq_enqueue (union buffered_input_event * ev )
99
116
{
100
117
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,
2665
2682
xic_set_preeditarea (w , x , y );
2666
2683
#endif
2667
2684
}
2668
-
2669
- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
2670
2685
}
2671
2686
2672
2687
static void
@@ -2769,24 +2784,6 @@ pgtk_scroll_run (struct window *w, struct run *run)
2769
2784
static void
2770
2785
pgtk_update_begin (struct frame * f )
2771
2786
{
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
-
2790
2787
pgtk_clear_under_internal_border (f );
2791
2788
}
2792
2789
@@ -2949,8 +2946,12 @@ pgtk_update_window_end (struct window *w, bool cursor_on_p,
2949
2946
static void
2950
2947
pgtk_update_end (struct frame * f )
2951
2948
{
2949
+ GtkWidget * widget = FRAME_GTK_WIDGET (f );
2952
2950
/* Mouse highlight may be displayed again. */
2953
2951
MOUSE_HL_INFO (f )-> mouse_face_defer = false;
2952
+
2953
+ gtk_widget_queue_draw (widget );
2954
+ flip_cr_context (f );
2954
2955
}
2955
2956
2956
2957
/* 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,
3123
3124
int src_x , int src_y , int width , int height ,
3124
3125
int dest_x , int dest_y , bool overlay_p )
3125
3126
{
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 );
3130
3128
3131
3129
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
+
3133
3131
if (overlay_p )
3134
3132
cairo_rectangle (cr , dest_x , dest_y , width , height );
3135
3133
else
@@ -3138,42 +3136,24 @@ pgtk_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image,
3138
3136
cairo_rectangle (cr , dest_x , dest_y , width , height );
3139
3137
cairo_fill_preserve (cr );
3140
3138
}
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 ;
3144
3142
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 );
3146
3144
if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1 )
3147
3145
{
3148
- PGTK_TRACE ("other format." );
3149
3146
cairo_set_source (cr , image );
3150
3147
cairo_fill (cr );
3151
3148
}
3152
3149
else
3153
3150
{
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 ??." );
3160
3151
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 );
3173
3153
cairo_mask (cr , image );
3174
3154
}
3155
+
3175
3156
pgtk_end_cr_clip (f );
3176
- PGTK_TRACE ("pgtk_cr_draw_image: 9." );
3177
3157
}
3178
3158
3179
3159
static void
@@ -3358,8 +3338,6 @@ recover_from_visible_bell(struct atimer *timer)
3358
3338
3359
3339
if (FRAME_X_OUTPUT (f )-> atimer_visible_bell != NULL )
3360
3340
FRAME_X_OUTPUT (f )-> atimer_visible_bell = NULL ;
3361
-
3362
- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
3363
3341
}
3364
3342
3365
3343
static void
@@ -3419,8 +3397,6 @@ pgtk_flash (struct frame *f)
3419
3397
width , height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f ));
3420
3398
3421
3399
FRAME_X_OUTPUT (f )-> cr_surface_visible_bell = surface ;
3422
- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f ));
3423
-
3424
3400
{
3425
3401
struct timespec delay = make_timespec (0 , 50 * 1000 * 1000 );
3426
3402
if (FRAME_X_OUTPUT (f )-> atimer_visible_bell != NULL ) {
@@ -4828,12 +4804,12 @@ pgtk_handle_draw(GtkWidget *widget, cairo_t *cr, gpointer *data)
4828
4804
PGTK_TRACE (" f=%p" , f );
4829
4805
if (f != NULL ) {
4830
4806
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 ) );
4833
4809
}
4834
- PGTK_TRACE (" surface=%p" , src );
4810
+ APGTK_TRACE (" surface=%p" , src );
4835
4811
if (src != NULL ) {
4836
- PGTK_TRACE (" resized_p=%d" , f -> resized_p );
4812
+ APGTK_TRACE (" resized_p=%d" , f -> resized_p );
4837
4813
PGTK_TRACE (" garbaged=%d" , f -> garbaged );
4838
4814
PGTK_TRACE (" scroll_bar_width=%f" , (double ) PGTK_SCROLL_BAR_WIDTH (f ));
4839
4815
// 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)
6580
6556
if (FRAME_CR_SURFACE_DESIRED_WIDTH (f ) != width
6581
6557
|| FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) != height )
6582
6558
{
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 );
6602
6560
FRAME_CR_SURFACE_DESIRED_WIDTH (f ) = width ;
6603
6561
FRAME_CR_SURFACE_DESIRED_HEIGHT (f ) = height ;
6562
+ SET_FRAME_GARBAGED (f );
6604
6563
}
6605
6564
}
6606
6565
@@ -6611,16 +6570,17 @@ pgtk_begin_cr_clip (struct frame *f)
6611
6570
cairo_t * cr = FRAME_CR_CONTEXT (f );
6612
6571
6613
6572
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
-
6622
6573
if (!cr )
6623
6574
{
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
+
6624
6584
cr = cairo_create (FRAME_CR_SURFACE (f ));
6625
6585
FRAME_CR_CONTEXT (f ) = cr ;
6626
6586
}
@@ -6635,9 +6595,6 @@ pgtk_end_cr_clip (struct frame *f)
6635
6595
{
6636
6596
PGTK_TRACE ("pgtk_end_cr_clip" );
6637
6597
cairo_restore (FRAME_CR_CONTEXT (f ));
6638
-
6639
- GtkWidget * widget = FRAME_GTK_WIDGET (f );
6640
- gtk_widget_queue_draw (widget );
6641
6598
}
6642
6599
6643
6600
void
@@ -6674,18 +6631,13 @@ pgtk_cr_draw_frame (cairo_t *cr, struct frame *f)
6674
6631
}
6675
6632
6676
6633
void
6677
- pgtk_cr_destroy_surface (struct frame * f )
6634
+ pgtk_cr_destroy_frame_context (struct frame * f )
6678
6635
{
6679
- PGTK_TRACE ("pgtk_cr_destroy_surface " );
6636
+ PGTK_TRACE ("pgtk_cr_destroy_frame_context " );
6680
6637
if (FRAME_CR_CONTEXT (f ) != NULL ) {
6681
6638
cairo_destroy (FRAME_CR_CONTEXT (f ));
6682
6639
FRAME_CR_CONTEXT (f ) = NULL ;
6683
6640
}
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 );
6689
6641
}
6690
6642
6691
6643
void
0 commit comments