Support clients using wl_data_device without wl_surface 46/117246/2
authorMinJeong Kim <minjjj.kim@samsung.com>
Mon, 27 Feb 2017 09:19:19 +0000 (18:19 +0900)
committerMinJeong Kim <minjjj.kim@samsung.com>
Mon, 6 Mar 2017 04:29:01 +0000 (20:29 -0800)
Change-Id: Ied918cb81598e4b14a4a5f77950e2bf9a1f2c11c
Signed-off-by: MinJeong Kim <minjjj.kim@samsung.com>
src/bin/e_comp_wl.h
src/bin/e_comp_wl_data.c
src/bin/e_comp_wl_data.h
src/bin/e_policy_wl.c

index 3a21a27ee5088e710380fbcc25ca4113453add12..51558516b3b733f26c166f12682eea83f1ab918e 100644 (file)
@@ -286,6 +286,7 @@ struct _E_Comp_Wl_Data
         E_Client *target;
 
         struct wl_resource *cbhm;
+        Eina_List *data_only_list;
      } selection;
 
    struct
index 729a149e66bc1b21aad30667a1444203a36362f1..628c30dcadd5763cb95e647ddcaeb539e53f1079 100644 (file)
@@ -175,6 +175,15 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
           wl_data_device_send_selection(data_device_res, NULL);
      }
 
+   if (e_comp_wl->selection.data_only_list)
+     {
+        struct wl_resource *data_only;
+        Eina_List *l;
+
+        EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
+           wl_data_device_send_selection(data_only, NULL);
+     }
+
    wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
 }
 
@@ -277,19 +286,45 @@ _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Sour
              wl_data_device_send_selection(data_device_res, offer_res);
           }
      }
-   else if (focus)
+   else
      {
-        data_device_res =  e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
-        if ((data_device_res) && (source))
+        /* send wl_data_device@selection to focused client */
+        if (focus)
           {
-             offer_res =
-                _e_comp_wl_data_device_data_offer_create(source,
-                                                         data_device_res);
-             wl_data_device_send_selection(data_device_res, offer_res);
+             data_device_res =  e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
+             if ((data_device_res) && (source))
+               {
+                  offer_res =
+                     _e_comp_wl_data_device_data_offer_create(source,
+                                                              data_device_res);
+                  wl_data_device_send_selection(data_device_res, offer_res);
+
+               }
+             else if (data_device_res)
+               wl_data_device_send_selection(data_device_res, NULL);
+          }
 
+        /* send wl_data_device@selection to data only clients
+         * because they won't be focused at all
+         */
+        if (e_comp_wl->selection.data_only_list)
+          {
+             struct wl_resource *data_only;
+             Eina_List *l;
+
+             EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
+               {
+                  if (source)
+                    {
+                       offer_res =
+                          _e_comp_wl_data_device_data_offer_create(source,
+                                                                   data_only);
+                       wl_data_device_send_selection(data_only, offer_res);
+                    }
+                  else
+                    wl_data_device_send_selection(data_only, NULL);
+               }
           }
-        else if (data_device_res)
-          wl_data_device_send_selection(data_device_res, NULL);
      }
 
    wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
@@ -419,6 +454,9 @@ static void
 _e_comp_wl_data_device_cb_unbind(struct wl_resource *resource)
 {
    struct wl_client *wc = wl_resource_get_client(resource);
+   e_comp_wl->selection.data_only_list =
+      eina_list_remove(e_comp_wl->selection.data_only_list,
+                       resource);
    eina_hash_del_by_key(e_comp_wl->mgr.data_resources, &wc);
 }
 
@@ -749,6 +787,11 @@ e_comp_wl_data_device_keyboard_focus_set(void)
       e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
    if (!data_device_res) return;
 
+   /* to remove from data_only_list if it is on the list */
+   e_comp_wl->selection.data_only_list =
+      eina_list_remove(e_comp_wl->selection.data_only_list,
+                       data_device_res);
+
    if (source)
      {
         offer_res =
@@ -919,3 +962,41 @@ e_comp_wl_clipboard_source_unref(E_Comp_Wl_Clipboard_Source *source)
    return 0;
 }
 
+E_API void
+e_comp_wl_data_device_only_set(struct wl_resource *data_device_res, Eina_Bool set)
+{
+   struct wl_resource *offer_res = NULL, *focus;
+   E_Comp_Wl_Data_Source *source;
+
+   EINA_SAFETY_ON_NULL_RETURN(data_device_res);
+
+   if (set)
+     {
+        if (eina_list_data_find(e_comp_wl->selection.data_only_list, data_device_res))
+          return;
+
+        e_comp_wl->selection.data_only_list =
+           eina_list_append(e_comp_wl->selection.data_only_list, data_device_res);
+
+        source = (E_Comp_Wl_Data_Source *)e_comp_wl->selection.data_source;
+        if (source)
+          {
+             offer_res =
+                _e_comp_wl_data_device_data_offer_create(source, data_device_res);
+          }
+        wl_data_device_send_selection(data_device_res, offer_res);
+     }
+   else
+     {
+        e_comp_wl->selection.data_only_list =
+           eina_list_remove(e_comp_wl->selection.data_only_list, data_device_res);
+
+        focus = e_comp_wl->kbd.focus;
+        if ((!focus) ||
+            (wl_resource_get_client(focus) != wl_resource_get_client(data_device_res)))
+          {
+             wl_data_device_send_selection(data_device_res, NULL);
+          }
+     }
+}
+
index a997d7534e8c9721786191ea3587126e60daeadb..354870252a0d1ab29cf9762345b04c039eed36d2 100644 (file)
@@ -65,5 +65,6 @@ E_API E_Comp_Wl_Data_Source *e_comp_wl_data_manager_source_create(struct wl_clie
 E_API int e_comp_wl_clipboard_source_ref(E_Comp_Wl_Clipboard_Source *source);
 E_API int e_comp_wl_clipboard_source_unref(E_Comp_Wl_Clipboard_Source *source);
 E_API E_Comp_Wl_Clipboard_Source *e_comp_wl_clipboard_source_create(const char *mime_type, uint32_t serial, int *fd);
+E_API void e_comp_wl_data_device_only_set(struct wl_resource *data_device_res, Eina_Bool set);
 # endif
 #endif
index 91bbfafa7108c48eeb0c770c43627403618709da..ede99a323263b90dcfb1479269e6627fd59ad551 100644 (file)
@@ -25,6 +25,7 @@
 #define PRIVILEGE_NOTIFICATION_LEVEL_SET "http://tizen.org/privilege/window.priority.set"
 #define PRIVILEGE_SCREEN_MODE_SET "http://tizen.org/privilege/display"
 #define PRIVILEGE_BRIGHTNESS_SET "http://tizen.org/privilege/display"
+#define PRIVILEGE_DATA_ONLY_SET "http://tizen.org/privilege/force.selection"
 
 #define APP_DEFINE_GROUP_NAME "effect"
 
@@ -6338,11 +6339,89 @@ _tz_clipboard_cb_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *
    e_service_cbhm_hide();
 }
 
+static void
+_tz_clipboard_cb_data_only_set(struct wl_client *wc, struct wl_resource *res_tz_clipboard, uint32_t set)
+{
+   E_Policy_Wl_Tz_Clipboard *tz_clipboard = NULL;
+   struct wl_client *_wc;
+   struct wl_resource *data_res;
+   pid_t pid = 0;
+   Eina_List *clients;
+   E_Client *ec, *found = NULL;
+   int fd;
+
+   tz_clipboard = wl_resource_get_user_data(res_tz_clipboard);
+   EINA_SAFETY_ON_NULL_RETURN(tz_clipboard);
+
+   if (tz_clipboard->ec_list)
+     {
+        ELOGF("TZPOL",
+              "Unable to set data only mode for wl_client(%p) : "
+              "ec_list exists",
+              NULL, NULL, wc);
+        goto send_deny;
+     }
+
+   if (!(data_res = e_comp_wl_data_find_for_client(wc)))
+     {
+        ELOGF("TZPOL",
+              "Unable to set data only mode for wl_client(%p) : "
+              "no wl_data_device resource",
+              NULL, NULL, wc);
+        goto send_deny;
+     }
+
+   clients = _e_policy_wl_e_clients_find_by_pid(pid);
+   if (clients)
+     {
+        EINA_LIST_FREE(clients, ec)
+          {
+             if (found) continue;
+             if (ec->comp_data && ec->comp_data->surface)
+               {
+                  _wc = wl_resource_get_client(ec->comp_data->surface);
+                  if (_wc== wc)
+                    found = ec;
+               }
+          }
+     }
+
+   if (found)
+     {
+        ELOGF("TZPOL",
+              "Unable to set data only mode for wl_client(%p) : "
+              "have ec(%p)",
+              NULL, NULL, wc, ec);
+        goto send_deny;
+     }
+
+   /* Privilege Check */
+   fd = wl_client_get_fd(wc);
+   if (!_e_policy_wl_privilege_check(fd, PRIVILEGE_DATA_ONLY_SET))
+     {
+        ELOGF("TZPOL",
+              "Privilege Check Failed! DENY data_only_set",
+              NULL, NULL);
+        goto send_deny;
+     }
+
+   ELOGF("TZPOL",
+         "Set data only mode :%d for wl_client(%p)",
+         NULL, NULL, set, wc);
+   e_comp_wl_data_device_only_set(data_res, !(set == 0));
+   tizen_clipboard_send_allowed_data_only(res_tz_clipboard, (uint32_t)1);
+   return;
+
+send_deny:
+   tizen_clipboard_send_allowed_data_only(res_tz_clipboard, (uint32_t)0);
+}
+
 static const struct tizen_clipboard_interface _tz_clipboard_iface =
 {
    _tz_clipboard_cb_destroy,
    _tz_clipboard_cb_show,
    _tz_clipboard_cb_hide,
+   _tz_clipboard_cb_data_only_set,
 };
 
 static void
@@ -6639,7 +6718,7 @@ e_policy_wl_init(void)
 
    global = wl_global_create(e_comp_wl->wl.disp,
                              &tizen_clipboard_interface,
-                             1,
+                             2,
                              NULL,
                              _tz_clipboard_cb_bind);
    EINA_SAFETY_ON_NULL_GOTO(global, err);