e_comp_wl & e_comp_wl_input: added implementation for zwp_relative_pointer_v1_interface 43/294943/1
authorSungjin Park <sj76.park@samsung.com>
Tue, 25 Apr 2023 10:52:09 +0000 (19:52 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Thu, 29 Jun 2023 05:11:38 +0000 (14:11 +0900)
Change-Id: Ic712d83511d7a3f7bcdc61a5e12640d5f5ad4e6e
Signed-off-by: Sungjin Park <sj76.park@samsung.com>
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_input.c
src/bin/e_comp_wl_input.h

index 8cda573a847bbf82b66ff6e766f44d174f9b4e9f..249379b4972b6eeb1f8df711bead460112e58549 100644 (file)
@@ -5609,6 +5609,44 @@ e_comp_wl_mouse_button_send(E_Client *ec, int buttons, Eina_Bool pressed, Ecore_
    return EINA_TRUE;
 }
 
+EINTERN Eina_Bool
+e_comp_wl_mouse_relative_motion_send(E_Client *ec,
+                                     int dx, int dy, int dx_unaccel, int dy_unaccel,
+                                     uint64_t time)
+{
+   struct wl_client *wc;
+   struct wl_resource *res;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data->surface, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
+
+   E_Client *focused = e_client_focused_get();
+   if ((focused) && (ec != focused)) return EINA_FALSE;
+
+   e_comp_wl->relative_ptr.ec = ec;
+   e_comp_wl->relative_ptr.activated = EINA_TRUE;
+
+   wc = wl_resource_get_client(ec->comp_data->surface);
+
+   EINA_LIST_FOREACH(e_comp_wl->relative_ptr.resources, l, res)
+     {
+        if (!e_comp_wl_input_relative_pointer_check(res)) continue;
+        if (wl_resource_get_client(res) != wc) continue;
+        zwp_relative_pointer_v1_send_relative_motion(res,
+                                                     (uint32_t)(time >> 32),
+                                                     (uint32_t)(time),
+                                                     wl_fixed_from_int(dx),
+                                                     wl_fixed_from_int(dy),
+                                                     wl_fixed_from_int(dx_unaccel),
+                                                     wl_fixed_from_int(dy_unaccel));
+     }
+
+   return EINA_TRUE;
+}
+
 EINTERN Eina_Bool
 e_comp_wl_mouse_move_send(E_Client *ec, int x, int y, Ecore_Device *dev, uint32_t time)
 {
index 3c06af25807d97430fe6b17a3e4297d538f159bc..8e9b9137904f9befc47c1aa9c25e797372a5937c 100644 (file)
@@ -14,6 +14,8 @@ typedef struct _E_Comp_Wl_Pid_Hook E_Comp_Wl_Pid_Hook;
 
 #  include <xkbcommon/xkbcommon.h>
 
+#  include <relative-pointer-unstable-v1-server-protocol.h>
+
 #  ifdef __linux__
 #   include <linux/input.h>
 #  else
@@ -239,6 +241,15 @@ struct _E_Comp_Wl_Data
         unsigned int num_devices;
      } ptr;
 
+   struct
+     {
+        Eina_List *resources;
+        Eina_List *manager_resources;
+        E_Client *ec;
+        Eina_Bool activated : 1;
+        struct wl_global *global;
+     } relative_ptr;
+
    struct
      {
         Eina_List *resources;
@@ -604,6 +615,7 @@ EINTERN Eina_Bool e_comp_wl_mouse_move_send(E_Client *ec, int x, int y, Ecore_De
 EINTERN Eina_Bool e_comp_wl_mouse_wheel_send(E_Client *ec, int direction, int z, Ecore_Device *dev, uint32_t time);
 EINTERN Eina_Bool e_comp_wl_mouse_in_send(E_Client *ec, int x, int y, Ecore_Device *dev, uint32_t time);
 EINTERN Eina_Bool e_comp_wl_mouse_out_send(E_Client *ec, Ecore_Device *dev, uint32_t time);
+EINTERN Eina_Bool e_comp_wl_mouse_relative_motion_send(E_Client *ec, int dx, int dy, int dx_unaccel, int dy_unaccel, uint64_t time);
 EINTERN void e_comp_wl_mouse_in_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src);
 EINTERN void e_comp_wl_mouse_out_renew(E_Client *ec, int buttons, int x, int y, void *data, Evas_Modifier *modifiers, Evas_Lock *locks, unsigned int timestamp, Evas_Event_Flags event_flags, Evas_Device *dev, Evas_Object *event_src);
 EINTERN Eina_Bool e_comp_wl_key_process(Ecore_Event_Key *ev, int type);
index fdf479c99742df1d54720ce8170ddb31de8e2002..291f38df0f51c67d0facb94a2d2bab3a45aae7d8 100644 (file)
@@ -423,6 +423,93 @@ _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED,
      wl_seat_send_name(res, e_comp_wl->seat.name);
 }
 
+static void
+_e_comp_wl_input_cb_relative_pointer_destroy(struct wl_client *client,
+                                             struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static const struct zwp_relative_pointer_v1_interface _e_relative_pointer_interface = {
+   _e_comp_wl_input_cb_relative_pointer_destroy
+};
+
+static void
+_e_comp_wl_input_cb_relative_pointer_manager_destroy(struct wl_client *client,
+                                                     struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_comp_wl_input_cb_unbind_relative_pointer(struct wl_resource *resource)
+{
+   e_comp_wl->relative_ptr.resources =
+     eina_list_remove(e_comp_wl->relative_ptr.resources, resource);
+}
+
+static void
+_e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer(struct wl_client *client,
+                                                              struct wl_resource *resource,
+                                                              uint32_t id,
+                                                              struct wl_resource *pointer_resource)
+{
+   struct wl_resource *res = NULL;
+
+   res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
+
+   if (!res)
+     {
+        ERR("Could not create the resource for relative pointer: %m");
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   e_comp_wl->relative_ptr.resources =
+     eina_list_append(e_comp_wl->relative_ptr.resources, res);
+
+   /* FIXME: must consider destroying relative pointer together
+             when the wl_pointer is destroyed */
+   (void) pointer_resource;
+   wl_resource_set_implementation(res, &_e_relative_pointer_interface,
+                                  NULL, _e_comp_wl_input_cb_unbind_relative_pointer);
+}
+
+static const struct zwp_relative_pointer_manager_v1_interface _e_relative_pointer_manager_interface = {
+   _e_comp_wl_input_cb_relative_pointer_manager_destroy,
+   _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer,
+};
+
+static void
+_e_comp_wl_input_cb_unbind_relative_pointer_manager(struct wl_resource *resource)
+{
+   e_comp_wl->relative_ptr.manager_resources =
+     eina_list_remove(e_comp_wl->relative_ptr.manager_resources, resource);
+}
+
+static void
+_e_comp_wl_input_cb_bind_relative_pointer_manager(struct wl_client *client,
+                                                  void *data EINA_UNUSED,
+                                                  uint32_t version,
+                                                  uint32_t id)
+{
+   struct wl_resource *resource = NULL;
+
+   resource = wl_resource_create(client, &zwp_relative_pointer_manager_v1_interface, 1, id);
+
+   if (!resource)
+     {
+        ERR("Could not create resource for relative pointer manager: %m");
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   e_comp_wl->relative_ptr.manager_resources =
+     eina_list_append(e_comp_wl->relative_ptr.manager_resources, resource);
+   wl_resource_set_implementation(resource, &_e_relative_pointer_manager_interface,
+                                  NULL, _e_comp_wl_input_cb_unbind_relative_pointer_manager);
+}
+
 static void
 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
 {
@@ -645,6 +732,18 @@ e_comp_wl_input_init(void)
         return EINA_FALSE;
      }
 
+   /* create the global resource for relative pointer */
+   e_comp_wl->relative_ptr.global =
+     wl_global_create(e_comp_wl->wl.disp,
+                      &zwp_relative_pointer_manager_v1_interface, 1,
+                      e_comp->wl_comp_data,
+                      _e_comp_wl_input_cb_bind_relative_pointer_manager);
+   if (!e_comp_wl->relative_ptr.global)
+     {
+        ERR("Could not create global for relative pointer: %m");
+        return EINA_FALSE;
+     }
+
    wl_array_init(&e_comp_wl->kbd.keys);
    wl_array_init(&e_comp_wl->kbd.routed_keys);
 
@@ -676,6 +775,14 @@ e_comp_wl_input_shutdown(void)
    EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
      wl_resource_destroy(res);
 
+   /* destroy relative pointer resources */
+   EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
+     wl_resource_destroy(res);
+
+   /* destroy relative pointer manager resources */
+   EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
+     wl_resource_destroy(res);
+
    /* destroy keyboard resources */
    EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
      wl_resource_destroy(res);
@@ -706,6 +813,11 @@ e_comp_wl_input_shutdown(void)
    if (e_comp_wl->xkb.context)
      xkb_context_unref(e_comp_wl->xkb.context);
 
+   /* destroy the global relative pointer resource */
+   if (e_comp_wl->relative_ptr.global)
+     wl_global_destroy(e_comp_wl->relative_ptr.global);
+   e_comp_wl->relative_ptr.global = NULL;
+
    /* destroy the global seat resource */
    if (e_comp_wl->seat.global)
      wl_global_destroy(e_comp_wl->seat.global);
@@ -722,6 +834,13 @@ e_comp_wl_input_pointer_check(struct wl_resource *res)
                                   &_e_pointer_interface);
 }
 
+EINTERN Eina_Bool
+e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
+{
+   return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
+                                  &_e_relative_pointer_interface);
+}
+
 EINTERN Eina_Bool
 e_comp_wl_input_keyboard_check(struct wl_resource *res)
 {
index ffde85d8ead4b1a0ceb09be481a38b711bda9605..4a3712be17ecfbaeb691bd21352dd826dfdffc5c 100644 (file)
@@ -15,6 +15,7 @@ struct _E_Event_Text_Input_Panel_Visibility_Change
 EINTERN Eina_Bool e_comp_wl_input_init(void);
 EINTERN void e_comp_wl_input_shutdown(void);
 EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
+EINTERN Eina_Bool e_comp_wl_input_relative_pointer_check(struct wl_resource *res);
 EINTERN Eina_Bool e_comp_wl_input_keyboard_check(struct wl_resource *res);
 EINTERN Eina_Bool e_comp_wl_input_touch_check(struct wl_resource *res);