<p dir="ltr">Andrew,<br>
Thanks for reviewing.  Comments follow.</p>
<p dir="ltr">On Mar 27, 2014 7:02 AM, "Andrew Wedgbury" <<a href="mailto:andrew.wedgbury@realvnc.com">andrew.wedgbury@realvnc.com</a>> wrote:<br>
><br>
> Hi Jason,<br>
><br>
> A few comments I have from trying out your fullscreen-shell changes:<br>
><br>
><br>
> On Tue, 18 Mar 2014, Jason Ekstrand wrote:<br>
><br>
>> +static struct ss_seat *<br>
>> +ss_seat_create(struct shared_output *so, uint32_t id)<br>
>> +{<br>
>> +     struct ss_seat *seat;<br>
>> +<br>
>> +     seat = zalloc(sizeof *seat);<br>
>> +     if (seat == NULL)<br>
>> +             return NULL;<br>
>> +<br>
>> +     weston_seat_init(&seat->base, so->output->compositor, "default");<br>
><br>
><br>
> It would be great if we could transfer the seat name from the parent seat. In the case of VNC or RDP this could identify the remote user.</p>
<p dir="ltr">That's not a bad idea.  I'll look into it.</p>
<p dir="ltr">><br>
><br>
>> +     seat->output = so;<br>
>> +     seat->parent.seat = wl_registry_bind(so->parent.registry, id,<br>
>> +                                          &wl_seat_interface, 1);<br>
>> +     wl_list_insert(so->seat_list.prev, &seat->link);<br>
>> +<br>
>> +     wl_seat_add_listener(seat->parent.seat, &ss_seat_listener, seat);<br>
>> +     wl_seat_set_user_data(seat->parent.seat, seat);<br>
>> +<br>
>> +     return seat;<br>
>> +}<br>
><br>
><br>
>> +static struct shared_output *<br>
>> +shared_output_create(struct weston_output *output, int parent_fd)<br>
>> +{<br>
>> +       struct shared_output *so;<br>
>> +       struct wl_event_loop *loop;<br>
>> +       struct ss_seat *seat;<br>
>> +       int epoll_fd;<br>
>> +<br>
>> +       so = zalloc(sizeof *so);<br>
>> +       if (so == NULL)<br>
>> +               goto err_close;<br>
>> +<br>
>> +       wl_list_init(&so->seat_list);<br>
>> + +     so->parent.display = wl_display_connect_to_fd(parent_fd);<br>
>> +       if (!so->parent.display)<br>
>> +               goto err_alloc;<br>
>> + +     so->parent.registry = wl_display_get_registry(so->parent.display);<br>
>> +       if (!so->parent.registry)<br>
>> +               goto err_display;<br>
>> +       wl_registry_add_listener(so->parent.registry,<br>
>> +                                &registry_listener, so);<br>
>> +       wl_display_roundtrip(so->parent.display);<br>
>> +       if (so->parent.shm == NULL) {<br>
>> +               weston_log("Screen share failed: No wl_shm found\n");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +       if (so->parent.fshell == NULL) {<br>
>> +               weston_log("Screen share failed: "<br>
>> +                          "Parent does not support wl_fullscreen_shell\n");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +       if (so->parent.compositor == NULL) {<br>
>> +               weston_log("Screen share failed: No wl_compositor found\n");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +<br>
>> +       /* Get SHM formats */<br>
>> +       wl_display_roundtrip(so->parent.display);<br>
>> +       if (!(so->parent.shm_formats & (1 << WL_SHM_FORMAT_XRGB8888))) {<br>
>> +               weston_log("Screen share failed: "<br>
>> +                          "WL_SHM_FORMAT_XRGB8888 not available\n");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +<br>
>> +       so->parent.surface =<br>
>> +               wl_compositor_create_surface(so->parent.compositor);<br>
>> +       if (!so->parent.surface) {<br>
>> +               weston_log("Screen share failed: %m");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +<br>
>> +       so->parent.mode_feedback =<br>
>> +               _wl_fullscreen_shell_present_surface_for_mode(so->parent.fshell,<br>
>> +                                                             so->parent.surface,<br>
>> +                                                             so->parent.output,<br>
>> +                                                             output->current_mode->refresh);<br>
>> +       if (!so->parent.mode_feedback) {<br>
>> +               weston_log("Screen share failed: %m");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> +       _wl_fullscreen_shell_mode_feedback_add_listener(so->parent.mode_feedback,<br>
>> +                                                       &mode_feedback_listener,<br>
>> +                                                       so);<br>
>> +<br>
>> +       loop = wl_display_get_event_loop(output->compositor->wl_display);<br>
>> +<br>
>> +       epoll_fd = wl_display_get_fd(so->parent.display);<br>
>> +       so->event_source =<br>
>> +               wl_event_loop_add_fd(loop, epoll_fd, WL_EVENT_READABLE,<br>
>> +                                    shared_output_handle_event, so);<br>
>> +       if (!so->event_source) {<br>
>> +               weston_log("Screen share failed: %m");<br>
>> +               goto err_display;<br>
>> +       }<br>
>> + +     /* Ok, everything's created.  We should be good to go */<br>
>> +       wl_list_init(&so->shm.buffers);<br>
>> +       wl_list_init(&so->shm.free_buffers);<br>
>> +<br>
>> +       so->output = output;<br>
>> +       so->output_destroyed.notify = output_destroyed;<br>
>> +       wl_signal_add(&so->output->destroy_signal, &so->output_destroyed);<br>
>> +<br>
>> +       so->frame_listener.notify = shared_output_repainted;<br>
>> +       wl_signal_add(&output->frame_signal, &so->frame_listener);<br>
>> +       output->disable_planes++;<br>
><br>
><br>
> I think you should only disable planes if the fullscreen_shell doesn't have the cursor_plane capability. In that case, there also needs to be a way to update the pointer surface on the parent seat. Although I think the difficulty may be in detecting when the pointer image changes - at least I remember that being a problem in my previous attempt at doing this.</p>

<p dir="ltr">Actually, it's more subtle than that.  Weston uses more than just the cursor plane.  It can also throw entire windows into planes to avoid unnecisary re-rendering.  In order to do a screen capture, we have to do a full composite.  We could, in theory, only use a plane for the one cursor,  but I'm not sure whether or not that would work with screen sharing.  I should definitely look into it for the case where the compositor is running stand-alone on top of the VNC/RDP server.</p>

<p dir="ltr">><br>
> I guess you also need a corresponding disable_planes-- when screen sharing<br>
> stops?</p>
<p dir="ltr">Yes, I should.  Do I not have one?  I should add one to shared_output_destroy.</p>
<p dir="ltr">Thanks for reviewing,<br>
--Jason Ekstrand</p>
<p dir="ltr">><br>
><br>
>> +       weston_output_damage(output);<br>
>> + +     return so;<br>
>> +<br>
>> +err_display:<br>
>> +       wl_list_for_each(seat, &so->seat_list, link)<br>
>> +               ss_seat_destroy(seat);<br>
>> +       wl_display_disconnect(so->parent.display);<br>
>> +err_alloc:<br>
>> +       free(so);<br>
>> +err_close:<br>
>> +       close(parent_fd);<br>
>> +       return NULL;<br>
>> +}<br>
><br>
><br>
> ---<br>
> Andrew Wedgbury <<a href="mailto:andrew.wedgbury@realvnc.com">andrew.wedgbury@realvnc.com</a>><br>
><br>
></p>