@@ -370,63 +370,47 @@ static void surface_handle_output_precommit(struct wl_listener *listener,
370370 }
371371}
372372
373- static void surface_handle_output_commit_formats (
374- struct wlr_zext_screencopy_surface_v1 * surface ,
375- struct wlr_output_event_commit * event ) {
373+ static bool surface_check_cursor_formats (
374+ struct wlr_zext_screencopy_surface_v1 * surface ) {
376375 struct wlr_output * output = surface_check_output (surface );
377376 if (!output ) {
378- return ;
377+ return false ;
379378 }
380379
381- struct wlr_renderer * renderer = output -> renderer ;
382-
383- struct wlr_buffer * buffer = event -> buffer ;
384- assert (buffer );
385-
386- surface -> wl_shm_format =
387- get_buffer_preferred_read_format (buffer , renderer );
388- surface -> wl_shm_stride = buffer -> width * 4 ; // TODO: This assumes things...
380+ struct wlr_buffer * buffer = output -> cursor_front_buffer ;
381+ if (!buffer ) {
382+ return false;
383+ }
389384
390- surface -> dmabuf_format = get_dmabuf_format (buffer );
385+ uint32_t dmabuf_format = get_dmabuf_format (buffer );
391386
392- if (surface -> wl_shm_format != DRM_FORMAT_INVALID ) {
393- assert (surface -> wl_shm_stride );
387+ return buffer -> width != surface -> cursor_width ||
388+ buffer -> height != surface -> cursor_height ||
389+ surface -> cursor_dmabuf_format != dmabuf_format ;
390+ }
394391
395- zext_screencopy_surface_v1_send_buffer_info (surface -> resource ,
396- ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_WL_SHM ,
397- surface -> wl_shm_format , output -> width ,
398- output -> height , surface -> wl_shm_stride );
392+ static void surface_advertise_cursor_formats (
393+ struct wlr_zext_screencopy_surface_v1 * surface ) {
394+ struct wlr_output * output = surface_check_output (surface );
395+ if (!output ) {
396+ return ;
399397 }
400398
401- if (surface -> dmabuf_format != DRM_FORMAT_INVALID ) {
402- zext_screencopy_surface_v1_send_buffer_info (surface -> resource ,
403- ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_DMABUF ,
404- surface -> dmabuf_format , output -> width ,
405- output -> height , 0 );
399+ struct wlr_buffer * buffer = output -> cursor_front_buffer ;
400+ if (!buffer ) {
401+ return ;
406402 }
407403
408- // TODO: If hardware cursors are not enabled, don't advertise cursor
409- // formats.
410- bool have_dummy_buffer = false;
411- struct wlr_buffer * cursor_buffer = output -> cursor_front_buffer ;
412- if (!cursor_buffer ) {
413- // This is a hack so that we can get a cursor buffer when no
414- // cursor is set.
415- cursor_buffer = wlr_swapchain_acquire (output -> cursor_swapchain ,
416- NULL );
417- have_dummy_buffer = true;
418- }
404+ struct wlr_renderer * renderer = output -> renderer ;
419405
420406 surface -> cursor_wl_shm_format =
421- get_buffer_preferred_read_format (cursor_buffer , renderer );
407+ get_buffer_preferred_read_format (buffer , renderer );
422408 surface -> cursor_wl_shm_stride =
423- cursor_buffer -> width * 4 ; // TODO: This assumes things...
424-
425- surface -> cursor_dmabuf_format = get_dmabuf_format (cursor_buffer );
409+ buffer -> width * 4 ; // TODO: This assumes things...
410+ surface -> cursor_dmabuf_format = get_dmabuf_format (buffer );
426411
427- if (have_dummy_buffer ) {
428- wlr_buffer_unlock (cursor_buffer );
429- }
412+ surface -> cursor_width = buffer -> width ;
413+ surface -> cursor_height = buffer -> height ;
430414
431415 if (surface -> cursor_wl_shm_format != DRM_FORMAT_INVALID ) {
432416 assert (surface -> cursor_wl_shm_stride );
@@ -435,7 +419,7 @@ static void surface_handle_output_commit_formats(
435419 surface -> resource , "default" ,
436420 ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_WL_SHM ,
437421 surface -> cursor_wl_shm_format ,
438- cursor_buffer -> width , cursor_buffer -> height ,
422+ buffer -> width , buffer -> height ,
439423 surface -> cursor_wl_shm_stride );
440424 }
441425
@@ -444,10 +428,57 @@ static void surface_handle_output_commit_formats(
444428 surface -> resource , "default" ,
445429 ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_DMABUF ,
446430 surface -> cursor_dmabuf_format ,
447- cursor_buffer -> width , cursor_buffer -> height , 0 );
431+ buffer -> width , buffer -> height , 0 );
448432 }
449433
450434 zext_screencopy_surface_v1_send_init_done (surface -> resource );
435+
436+ if (output -> cursor_front_buffer ) {
437+ zext_screencopy_surface_v1_send_cursor_enter (surface -> resource ,
438+ "default" );
439+ surface -> have_cursor = true;
440+ }
441+ }
442+
443+ static void surface_advertise_buffer_formats (
444+ struct wlr_zext_screencopy_surface_v1 * surface ,
445+ struct wlr_buffer * buffer ) {
446+ struct wlr_output * output = surface_check_output (surface );
447+ if (!output ) {
448+ return ;
449+ }
450+
451+ struct wlr_renderer * renderer = output -> renderer ;
452+
453+ surface -> wl_shm_format =
454+ get_buffer_preferred_read_format (buffer , renderer );
455+ surface -> wl_shm_stride = buffer -> width * 4 ; // TODO: This assumes things...
456+
457+ surface -> dmabuf_format = get_dmabuf_format (buffer );
458+
459+ if (surface -> wl_shm_format != DRM_FORMAT_INVALID ) {
460+ assert (surface -> wl_shm_stride );
461+
462+ zext_screencopy_surface_v1_send_buffer_info (surface -> resource ,
463+ ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_WL_SHM ,
464+ surface -> wl_shm_format , output -> width ,
465+ output -> height , surface -> wl_shm_stride );
466+ }
467+
468+ if (surface -> dmabuf_format != DRM_FORMAT_INVALID ) {
469+ zext_screencopy_surface_v1_send_buffer_info (surface -> resource ,
470+ ZEXT_SCREENCOPY_SURFACE_V1_BUFFER_TYPE_DMABUF ,
471+ surface -> dmabuf_format , output -> width ,
472+ output -> height , 0 );
473+ }
474+
475+ surface_advertise_cursor_formats (surface );
476+ }
477+
478+ static void surface_handle_output_commit_formats (
479+ struct wlr_zext_screencopy_surface_v1 * surface ,
480+ struct wlr_output_event_commit * event ) {
481+ surface_advertise_buffer_formats (surface , event -> buffer );
451482 surface -> state = WLR_ZEXT_SCREENCOPY_SURFACE_V1_STATE_READY ;
452483}
453484
@@ -656,6 +687,26 @@ static void surface_handle_output_commit_ready(
656687 return ;
657688 }
658689
690+ if (surface_check_cursor_formats (surface )) {
691+ zext_screencopy_surface_v1_send_cursor_leave (surface -> resource ,
692+ "default" );
693+ zext_screencopy_surface_v1_send_reconfig (surface -> resource );
694+ surface_advertise_buffer_formats (surface , event -> buffer );
695+ // TODO: Reset staged buffers?
696+ return ;
697+ }
698+
699+ if (surface -> have_cursor && !output -> cursor_front_buffer ) {
700+ zext_screencopy_surface_v1_send_cursor_leave (surface -> resource ,
701+ "default" );
702+ surface -> have_cursor = false;
703+ } else if (!surface -> have_cursor && output -> cursor_front_buffer ) {
704+ zext_screencopy_surface_v1_send_cursor_enter (surface -> resource ,
705+ "default" );
706+ surface -> have_cursor = true;
707+ }
708+
709+
659710 if (!surface -> current_buffer .resource ) {
660711 return ;
661712 }
0 commit comments