e_input: support other axis_source (finger/continuous) than mouse wheel 42/289242/1
authorduna.oh <duna.oh@samsung.com>
Thu, 2 Mar 2023 08:45:05 +0000 (17:45 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Fri, 3 Mar 2023 06:46:09 +0000 (15:46 +0900)
Change-Id: I704ef4980832ad6cfa248b4912fbf05c3b6f6068

configure.ac
src/bin/e_input_evdev.c
src/bin/e_input_private.h

index ff5b469..eeabf92 100755 (executable)
@@ -522,6 +522,12 @@ if test "x${have_extra_touch_event}" = "xyes";then
 AC_DEFINE_UNQUOTED([LIBINPUT_SUPPORT_EXTRA_TOUCH_EVENT], [1], [libinput support extra touch event])
 fi
 
+have_scroll_value_v120="no"
+AC_CHECK_LIB(input, libinput_event_pointer_get_scroll_value_v120, [have_scroll_value_v120="yes"])
+if test "x${have_scroll_value_v120}" = "xyes";then
+AC_DEFINE_UNQUOTED([LIBINPUT_HAVE_SCROLL_VALUE_V120], [1], [libinput have get_scroll_value_v120])
+fi
+
 #capi-system-device
 PKG_CHECK_MODULES([CAPI_SYSTEM_DEVICE],
                   [capi-system-device])
index c431dc9..7ef7616 100644 (file)
@@ -1028,6 +1028,48 @@ _device_handle_button(struct libinput_device *device, struct libinput_event_poin
      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, _e_input_event_mouse_button_cb_free, NULL);
 }
 
+static int
+_axis_value_get(struct libinput_event_pointer *pointer_event, enum libinput_pointer_axis axis)
+{
+   enum libinput_pointer_axis_source source;
+   double value = 0.0, value_discrete = 0.0;
+   int ret = 0;
+   E_Comp_Config *comp_conf = NULL;
+
+   comp_conf = e_comp_config_get();
+   source = libinput_event_pointer_get_axis_source(pointer_event);
+   switch (source)
+     {
+      case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
+        value_discrete = libinput_event_pointer_get_axis_value_discrete(pointer_event, axis);
+        value = libinput_event_pointer_get_axis_value(pointer_event, axis);
+        if (comp_conf && comp_conf->input_log_enable)
+          {
+             ELOGF("Axis", "SOURCE_WHEEL discrete: %lf (cf. value: %lf)", NULL, value_discrete, value);
+          }
+        ret = (int)value_discrete;
+        break;
+      case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
+      case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
+        value = libinput_event_pointer_get_axis_value(pointer_event, axis);
+        if (comp_conf && comp_conf->input_log_enable)
+          {
+             ELOGF("Axis", "SOURCE_FINGER/CONTINUOUS value: %lf", NULL, value);
+          }
+        if (value >= E_INPUT_FINGER_SCROLL_THRESHOLD)
+          ret = 1;
+        else if (value <= E_INPUT_FINGER_SCROLL_THRESHOLD * (-1))
+          ret = -1;
+        else
+          ret = 0;
+        break;
+      default:
+        break;
+     }
+
+   return ret;
+}
+
 static void
 _device_handle_axis(struct libinput_device *device, struct libinput_event_pointer *event)
 {
@@ -1084,13 +1126,194 @@ _device_handle_axis(struct libinput_device *device, struct libinput_event_pointe
 
    axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
    if (libinput_event_pointer_has_axis(event, axis))
-     z = libinput_event_pointer_get_axis_value_discrete(event, axis);
+     z = _axis_value_get(event, axis);
+
+   axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
+   if (libinput_event_pointer_has_axis(event, axis))
+     {
+        direction = 1;
+        z = _axis_value_get(event, axis);
+     }
+
+  if (z == 0)
+    {
+       ELOGF("Mouse", "Axis event is ignored since it has zero value", NULL);
+       return;
+    }
+
+   comp_conf = e_comp_config_get();
+   if (comp_conf && comp_conf->e_wheel_click_angle)
+     {
+        z = (int)(z * comp_conf->e_wheel_click_angle);
+     }
+
+   if ((edev->seat->dev->blocked & E_INPUT_SEAT_POINTER) ||
+       (edev->seat->dev->server_blocked & E_INPUT_SEAT_POINTER))
+     {
+        if (detent_data)
+          ELOGF("Mouse", "Detent (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
+                direction, z, edev->seat->dev->blocked_client, edev->seat->dev->server_blocked);
+        else
+          ELOGF("Mouse", "Wheel (direction: %d, value: %d) is blocked by %p, server: 0x%x", NULL,
+                direction, z, edev->seat->dev->blocked_client, edev->seat->dev->server_blocked);
+        return;
+     }
+
+   if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel))))
+     {
+        return;
+     }
+
+   timestamp = libinput_event_pointer_get_time(event);
+
+   ev->window = (Ecore_Window)input->dev->window;
+   ev->event_window = (Ecore_Window)input->dev->window;
+   ev->root_window = (Ecore_Window)input->dev->window;
+   ev->timestamp = timestamp;
+   ev->same_screen = 1;
+
+   _device_modifiers_update(edev);
+   ev->modifiers = edev->xkb.modifiers;
+
+   ev->x = edev->seat->ptr.ix;
+   ev->y = edev->seat->ptr.iy;
+   ev->root.x = ev->x;
+   ev->root.y = ev->y;
+   ev->dev = ecore_device_ref(ecore_dev);
+
+   ev->z = z;
+   ev->direction = direction;
+
+   if (comp_conf && comp_conf->input_log_enable)
+     {
+        if (detent_data)
+          ELOGF("Mouse", "Detent (direction: %d, value: %d)", NULL, ev->direction, ev->z);
+        else
+          ELOGF("Mouse", "Wheel (direction: %d, value: %d)", NULL, ev->direction, ev->z);
+     }
+
+   ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
+}
+
+#if LIBINPUT_HAVE_SCROLL_VALUE_V120
+static int
+_scroll_value_get(struct libinput_event_pointer *pointer_event, enum libinput_pointer_axis axis, E_Input_Axis_Source source)
+{
+   double value = 0.0;
+   double value_v120 = 0.0;
+   int ret;
+   E_Comp_Config *comp_conf = NULL;
+
+   comp_conf = e_comp_config_get();
+   switch (source)
+     {
+      case E_INPUT_AXIS_SOURCE_WHEEL:
+        value_v120 = libinput_event_pointer_get_scroll_value_v120(pointer_event, axis);
+        value = libinput_event_pointer_get_scroll_value(pointer_event, axis);
+        if (comp_conf && comp_conf->input_log_enable)
+          {
+             ELOGF("Scroll", "SOURCE_WHEELL value_v120: %lf (cf. value: %lf)", NULL, value_v120, value);
+          }
+        if (((int)value_v120 % E_INPUT_POINTER_AXIS_DISCRETE_STEP) != 0)
+          {
+             ERR("Wheel movements should be multiples (or fractions) of 120!\n");
+             ret = 0;
+          }
+        else
+          {
+             ret = value_v120 / E_INPUT_POINTER_AXIS_DISCRETE_STEP;
+          }
+        break;
+      case E_INPUT_AXIS_SOURCE_FINGER:
+      case E_INPUT_AXIS_SOURCE_CONTINUOUS:
+        value = libinput_event_pointer_get_scroll_value(pointer_event, axis);
+        if (comp_conf && comp_conf->input_log_enable)
+          {
+             ELOGF("Scroll", "SOURCE_FINGER/CONTINUOUS value: %lf", NULL, value);
+          }
+        if (value >= E_INPUT_FINGER_SCROLL_THRESHOLD)
+          ret = 1;
+        else if (value <= E_INPUT_FINGER_SCROLL_THRESHOLD * (-1))
+          ret = -1;
+        else
+          ret = 0;
+        break;
+      default:
+        break;
+     }
+
+   return ret;
+}
+
+static void
+_device_handle_axis_v120(struct libinput_device *device, struct libinput_event_pointer *event, E_Input_Axis_Source source)
+{
+   E_Input_Evdev *edev;
+   E_Input_Backend *input;
+   Ecore_Event_Mouse_Wheel *ev;
+   uint32_t timestamp;
+   enum libinput_pointer_axis axis;
+   Ecore_Device *ecore_dev = NULL, *detent_data = NULL, *data;
+   Eina_List *l;
+   E_Comp_Config *comp_conf = NULL;
+   int direction = 0, z = 0;
+
+   if (!(edev = libinput_device_get_user_data(device)))
+     {
+        return;
+     }
+   if (!(input = edev->seat->input))
+     {
+        return;
+     }
+
+   if (edev->ecore_dev) ecore_dev = edev->ecore_dev;
+   else if (edev->ecore_dev_list && eina_list_count(edev->ecore_dev_list) > 0)
+     {
+        EINA_LIST_FOREACH(edev->ecore_dev_list, l, data)
+          {
+             if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_MOUSE)
+               {
+                  ecore_dev = data;
+                  break;
+               }
+             else if (ecore_device_class_get(data) == ECORE_DEVICE_CLASS_NONE)
+               {
+                  detent_data = data;
+               }
+          }
+        if (!ecore_dev && e_devicemgr_detent_is_detent(libinput_device_get_name(edev->device)))
+          {
+             ecore_dev = detent_data;
+          }
+     }
+   else
+     {
+        edev->ecore_dev = e_input_evdev_get_ecore_device(edev->path, ECORE_DEVICE_CLASS_MOUSE);
+        ecore_dev = edev->ecore_dev;
+     }
+
+   if (!ecore_dev)
+     {
+        ERR("Failed to get source ecore device from event !\n");
+        return;
+     }
+
+   axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
+   if (libinput_event_pointer_has_axis(event, axis))
+     z = _scroll_value_get(event, axis, source);
 
    axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
    if (libinput_event_pointer_has_axis(event, axis))
      {
         direction = 1;
-        z = libinput_event_pointer_get_axis_value_discrete(event, axis);
+        z = _scroll_value_get(event, axis, source);
+     }
+
+   if (z == 0)
+     {
+        ELOGF("Mouse", "Scroll event is ignored since it has zero value", NULL);
+        return;
      }
 
    comp_conf = e_comp_config_get();
@@ -1146,6 +1369,7 @@ _device_handle_axis(struct libinput_device *device, struct libinput_event_pointe
 
    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _e_input_event_mouse_wheel_cb_free, NULL);
 }
+#endif
 
 static void
 _device_handle_touch_event_send(E_Input_Evdev *edev, struct libinput_event_touch *event, int state)
@@ -1890,8 +2114,21 @@ _e_input_evdev_event_process(struct libinput_event *event)
         _device_handle_button(device, libinput_event_get_pointer_event(event));
         break;
       case LIBINPUT_EVENT_POINTER_AXIS:
+#if !LIBINPUT_HAVE_SCROLL_VALUE_V120
         _device_handle_axis(device, libinput_event_get_pointer_event(event));
+#endif
+        break;
+#if LIBINPUT_HAVE_SCROLL_VALUE_V120
+      case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+        _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_WHEEL);
+        break;
+      case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+        _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_FINGER);
         break;
+      case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+        _device_handle_axis_v120(device, libinput_event_get_pointer_event(event), E_INPUT_AXIS_SOURCE_CONTINUOUS);
+        break;
+#endif
       case LIBINPUT_EVENT_TOUCH_DOWN:
         _device_handle_touch_down(device, libinput_event_get_touch_event(event));
         break;
index f5cf49c..f8952b2 100644 (file)
@@ -15,6 +15,8 @@ extern struct xkb_context *cached_context;
 
 #define E_INPUT_ENV_LIBINPUT_LOG_DISABLE "E_INPUT_LIBINPUT_LOG_DISABLE"
 #define E_INPUT_ENV_LIBINPUT_LOG_EINA_LOG "E_INPUT_LIBINPUT_LOG_EINA_LOG"
+#define E_INPUT_POINTER_AXIS_DISCRETE_STEP 120
+#define E_INPUT_FINGER_SCROLL_THRESHOLD 1
 
 struct _E_Input_Coord
 {
@@ -129,6 +131,12 @@ struct _E_Input_Evdev
    Eina_Bool disable_acceleration;
 };
 
+typedef enum _E_Input_Axis_Source {
+   E_INPUT_AXIS_SOURCE_WHEEL = 1,
+   E_INPUT_AXIS_SOURCE_FINGER,
+   E_INPUT_AXIS_SOURCE_CONTINUOUS,
+} E_Input_Axis_Source;
+
 void _input_events_process(E_Input_Backend *input);
 E_Input_Evdev *_e_input_evdev_device_create(E_Input_Seat *seat, struct libinput_device *device);
 Eina_Bool _e_input_evdev_event_process(struct libinput_event *event);