e_comp_wl_screenshooter: support tizen_screenshooter interface version 3 77/277477/1 accepted/tizen/unified/20220711.173828 submit/tizen/20220708.090227
authorJunkyeong Kim <jk0430.kim@samsung.com>
Thu, 23 Jun 2022 12:05:59 +0000 (21:05 +0900)
committerJunseok Kim <juns.kim@samsung.com>
Thu, 7 Jul 2022 09:56:12 +0000 (18:56 +0900)
support tizen_screeenshooter interface shoot request and use done event.

Change-Id: I94141f12bfb5e4af93b853d402c248251c95de2f
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
src/bin/e_comp_wl_screenshooter.c

index 5bce6ca..5c33310 100644 (file)
@@ -15,6 +15,7 @@ typedef struct _E_Mirror
    struct wl_resource *resource;
    struct wl_resource *shooter;
    struct wl_resource *output;
+   struct wl_resource *resource_shoot;
 
    Eina_Bool started;
    enum tizen_screenmirror_stretch stretch;
@@ -64,6 +65,7 @@ static Eina_List *mirror_list;
 static void _e_tz_screenmirror_destroy(E_Mirror *mirror);
 static void _e_tz_screenmirror_buffer_dequeue(E_Mirror_Buffer *buffer);
 static void _e_tz_screenmirror_buffer_cb_free(E_Comp_Wl_Video_Buf *vbuf, void *data);
+static void _e_output_capture_oneshot_cb(E_Output *eout, tbm_surface_h tsurface, void *user_data);
 
 static Eina_Bool
 _e_screenmirror_privilege_check(struct wl_client *client)
@@ -333,6 +335,11 @@ _e_tz_screenmirror_buffer_dequeue(E_Mirror_Buffer *buffer)
         if (!mirror->oneshot_client_destroy)
           screenshooter_send_done(mirror->resource);
      }
+   else if (mirror->resource_shoot == mirror->shooter)
+     {
+        if (!mirror->oneshot_client_destroy)
+          tizen_screenshooter_send_done(mirror->resource_shoot);
+     }
    else
      tizen_screenmirror_send_dequeued(mirror->resource, buffer->vbuf->resource);
 }
@@ -355,7 +362,7 @@ _e_tz_screenmirror_buffer_cb_free(E_Comp_Wl_Video_Buf *vbuf, void *data)
    E_Mirror_Buffer *buffer = data;
    E_Mirror *mirror = buffer->mirror;
 
-   if (mirror->resource == mirror->shooter)
+   if (mirror->resource == mirror->shooter || mirror->resource_shoot == mirror->shooter)
      mirror->oneshot_client_destroy = EINA_TRUE;
 
    _e_tz_screenmirror_buffer_free(buffer);
@@ -402,7 +409,7 @@ _e_tz_screenmirror_cb_client_destroy(struct wl_listener *listener, void *data)
 {
    E_Mirror *mirror = container_of(listener, E_Mirror, client_destroy_listener);
 
-   if (mirror->resource == mirror->shooter)
+   if (mirror->resource == mirror->shooter || mirror->resource_shoot == mirror->shooter)
      {
         mirror->oneshot_client_destroy = EINA_TRUE;
         return;
@@ -468,7 +475,10 @@ _e_tz_screenmirror_destroy(E_Mirror *mirror)
      wl_list_remove(&mirror->client_destroy_listener.link);
    mirror->client_destroy_listener.notify = NULL;
 
-   wl_resource_set_destructor(mirror->resource, NULL);
+   if (mirror->resource)
+     wl_resource_set_destructor(mirror->resource, NULL);
+   if (mirror->resource_shoot)
+     wl_resource_set_destructor(mirror->resource_shoot, NULL);
 
    eina_list_free(mirror->buffer_clear_check);
    mirror->buffer_clear_check = NULL;
@@ -730,6 +740,85 @@ _e_tz_screenshooter_set_oneshot_auto_rotation(struct wl_client *client,
 }
 
 static void
+_e_tz_screenshooter_shoot(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_resource *output_resource,
+                             struct wl_resource *buffer_resource)
+{
+   E_Mirror *mirror;
+   E_Mirror_Buffer *buffer;
+   Eina_Bool ret;
+   E_Comp_Wl_Video_Buf *vbuf = NULL;
+
+   if (!_e_tz_screenmirror_buffer_check(buffer_resource))
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "tizen_screenshooter failed: wrong buffer resource");
+        return;
+     }
+
+   mirror = _e_tz_screenmirror_create(client, resource, output_resource);
+   if (!mirror)
+     {
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+
+   mirror->resource_shoot = mirror->shooter;
+
+   if (_e_screenmirror_privilege_check(client) == EINA_FALSE)
+     {
+        ERR("priv check failed");
+        tizen_screenshooter_send_done(resource);
+        goto privilege_fail;
+     }
+
+   buffer = _e_tz_screenmirror_buffer_get(mirror, buffer_resource);
+   if (!buffer)
+     {
+        wl_resource_post_no_memory(resource);
+        _e_tz_screenmirror_destroy(mirror);
+        return;
+     }
+   e_comp_wl_video_buffer_clear(buffer->vbuf);
+
+   mirror->buffer_queue = eina_list_append(mirror->buffer_queue, buffer);
+
+   if (e_output_dpms_get(mirror->e_output))
+     {
+        ERR("dpms on fail");
+        goto dump_done;
+     }
+
+   if (buffer->vbuf->type == E_COMP_WL_VIDEO_BUF_TYPE_SHM)
+     {
+        if (!_e_tz_screenmirror_tmp_buffer_create(buffer))
+          {
+             ERR("tmp buffer create fail");
+             goto dump_done;
+          }
+
+        vbuf = buffer->tmp;
+     }
+   else
+     vbuf = buffer->vbuf;
+   EINA_SAFETY_ON_NULL_GOTO(vbuf, dump_done);
+
+   ret = e_output_capture(mirror->e_output, vbuf->tbm_surface, screenshot_auto_rotation, EINA_FALSE, _e_output_capture_oneshot_cb, buffer);
+   if (ret) return;
+   else ERR("capture fail");
+
+   if (buffer->vbuf->type == E_COMP_WL_VIDEO_BUF_TYPE_SHM)
+     _e_tz_screenmirror_copy_tmp_buffer(buffer);
+
+dump_done:
+   _e_tz_screenmirror_buffer_free(buffer);
+
+privilege_fail:
+   _e_tz_screenmirror_destroy(mirror);
+}
+
+static void
 _e_tz_screenshooter_destroy(struct wl_client *client, struct wl_resource *resource)
 {
    wl_resource_destroy(resource);
@@ -740,6 +829,7 @@ static const struct tizen_screenshooter_interface _e_tz_screenshooter_interface
    _e_tz_screenshooter_get_screenmirror,
    _e_tz_screenshooter_set_oneshot_auto_rotation,
    _e_tz_screenshooter_destroy,
+   _e_tz_screenshooter_shoot,
 };
 
 static void
@@ -913,7 +1003,7 @@ e_comp_wl_screenshooter_init(void)
      }
 
    /* try to add tizen_screenshooter to wayland globals */
-   if (!wl_global_create(e_comp_wl->wl.disp, &tizen_screenshooter_interface, 2,
+   if (!wl_global_create(e_comp_wl->wl.disp, &tizen_screenshooter_interface, 3,
                          NULL, _e_tz_screenshooter_cb_bind))
      {
         ERR("Could not add tizen_screenshooter to wayland globals");