From ee044ea5f5009618dc3a43bb40597bfe0273f711 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Thu, 28 Aug 2014 16:15:22 -0700
Subject: [PATCH v2 4/7] Implement EVAS_CALLBACK_AXIS_UPDATE event and friends

Adds a new EVAS_CALLBACK_AXIS_UPDATE callback type that can be
used to recieve information about changes to input device axes.
This is not wired up to anything yet; once the necessary connection
to Ecore is made, these events should start flowing through.

Patch v2:
 * Include data and dev members in struct _Evas_Axis
---
 src/lib/evas/Evas_Common.h           | 39 +++++++++++++++++++++++++
 src/lib/evas/Evas_Eo.h               |  2 ++
 src/lib/evas/Evas_Legacy.h           |  4 +++
 src/lib/evas/canvas/evas_callbacks.c |  6 +++-
 src/lib/evas/canvas/evas_canvas.eo   | 17 +++++++++++
 src/lib/evas/canvas/evas_events.c    | 55 ++++++++++++++++++++++++++++++++++++
 src/lib/evas/include/evas_private.h  |  1 +
 7 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h
index adafbdd..51af493 100644
--- a/src/lib/evas/Evas_Common.h
+++ b/src/lib/evas/Evas_Common.h
@@ -98,6 +98,8 @@ typedef enum _Evas_Callback_Type
 
    EVAS_CALLBACK_IMAGE_RESIZE, /**< Image size is changed @since 1.8 */
    EVAS_CALLBACK_DEVICE_CHANGED, /**< Devices added, removed or changed on canvas @since 1.8 */
+
+   EVAS_CALLBACK_AXIS_UPDATE, /**< Input device changed value on some axis @since 1.9 */
    EVAS_CALLBACK_LAST /**< kept as last element/sentinel -- not really an event */
 } Evas_Callback_Type; /**< The types of events triggering a callback */
 
@@ -771,6 +773,43 @@ struct _Evas_Event_Hold /** Hold change event */
    Evas_Device     *dev;
 };
 
+enum _Evas_Axis_Label
+{
+   EVAS_AXIS_LABEL_UNKNOWN,       /* Axis containing unknown (or not yet representable) data */
+   EVAS_AXIS_LABEL_X,             /* Position along physical X axis; not window relative */
+   EVAS_AXIS_LABEL_Y,             /* Position along physical Y axis; not window relative */
+   EVAS_AXIS_LABEL_PRESSURE,      /* Force applied to tool tip; Range: [0.0, 1.0]. Unit: Unitless */
+   EVAS_AXIS_LABEL_DISTANCE,      /* Relative distance along physical Z axis; Range: [0.0, 1.0] */
+   EVAS_AXIS_LABEL_AZIMUTH,       /* Angle of tool about the Z axis from positive X axis; Range: [-PI, PI] radians */
+   EVAS_AXIS_LABEL_TILT,          /* Angle of tool about plane of sensor from positive Z axis; Range: [0.0, PI] radians */
+   EVAS_AXIS_LABEL_TWIST,         /* Angle of tool about tool's major axis from tool's "natural" position; Range: [-PI, PI] radians */
+   EVAS_AXIS_LABEL_TOUCH_WIDTH_MAJOR,   /* Length of contact ellipse along AZIMUTH */
+   EVAS_AXIS_LABEL_TOUCH_WIDTH_MINOR,   /* Length of contact ellipse perpendicular to AZIMUTH */
+   EVAS_AXIS_LABEL_TOOL_WIDTH_MAJOR,    /* Length of tool ellipse along AZIMUTH */
+   EVAS_AXIS_LABEL_TOOL_WIDTH_MINOR     /* Length of tool ellipse perpendicular to AZIMUTH */
+};
+
+struct _Evas_Axis
+{
+   enum _Evas_Axis_Label label;
+   double value;
+};
+
+struct _Evas_Event_Axis_Update
+{
+   void             *data;
+
+   unsigned int timestamp;
+   int device;
+   int toolid;
+
+   int naxis;
+   struct _Evas_Axis *axis;
+   Evas_Device       *dev;
+};
+
+typedef struct _Evas_Event_Axis_Update Evas_Event_Axis_Update;
+
 /**
  * How the mouse pointer should be handled by Evas.
  *
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index a807e0a..64cd2ae 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -10,6 +10,7 @@ EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_OBJECT_FOCUS_IN;
 EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_OBJECT_FOCUS_OUT;
 EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_RENDER_PRE;
 EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_RENDER_POST;
+EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_AXIS_UPDATE;
 
 // Callbacks events for use with Evas canvases
 #define EVAS_CANVAS_EVENT_FOCUS_IN (&(_EVAS_CANVAS_EVENT_FOCUS_IN))
@@ -20,6 +21,7 @@ EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_RENDER_POST;
 #define EVAS_CANVAS_EVENT_OBJECT_FOCUS_OUT (&(_EVAS_CANVAS_EVENT_OBJECT_FOCUS_OUT))
 #define EVAS_CANVAS_EVENT_RENDER_PRE (&(_EVAS_CANVAS_EVENT_RENDER_PRE))
 #define EVAS_CANVAS_EVENT_RENDER_POST (&(_EVAS_CANVAS_EVENT_RENDER_POST))
+#define EVAS_CANVAS_EVENT_AXIS_UPDATE (&(_EVAS_CANVAS_EVENT_AXIS_UPDATE))
 
 #include "canvas/evas_signal_interface.eo.h"
 #include "canvas/evas_draggable_interface.eo.h"
diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h
index 6c270f1..5357158 100644
--- a/src/lib/evas/Evas_Legacy.h
+++ b/src/lib/evas/Evas_Legacy.h
@@ -613,6 +613,7 @@ EAPI void             evas_object_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
  * #EVAS_CALLBACK_MOUSE_DOWN, #EVAS_CALLBACK_MOUSE_UP,
  * #EVAS_CALLBACK_MOUSE_MOVE, #EVAS_CALLBACK_MOUSE_WHEEL,
  * #EVAS_CALLBACK_MULTI_DOWN, #EVAS_CALLBACK_MULTI_UP,
+ * #EVAS_CALLBACK_AXIS_UPDATE,
  * #EVAS_CALLBACK_MULTI_MOVE, #EVAS_CALLBACK_FREE,
  * #EVAS_CALLBACK_KEY_DOWN, #EVAS_CALLBACK_KEY_UP,
  * #EVAS_CALLBACK_FOCUS_IN, #EVAS_CALLBACK_FOCUS_OUT,
@@ -687,6 +688,9 @@ EAPI void             evas_object_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
  * - #EVAS_CALLBACK_MULTI_MOVE: @p event_info is a pointer to an
  *   #Evas_Event_Multi_Move struct
  *
+ * - #EVAS_CALLBACK_AXIS_UPDATE: @p event_info is a pointer to an
+ *   #Evas_Event_Axis_Update struct
+ *
  * - #EVAS_CALLBACK_FREE: @p event_info is @c NULL \n\n
  *   This event is triggered just before Evas is about to free all
  *   memory used by an object and remove all references to it. This is
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index 4beac93..1a0ee6b 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -12,6 +12,9 @@ EAPI const Eo_Event_Description _EVAS_CANVAS_EVENT_RENDER_PRE =
 EAPI const Eo_Event_Description _EVAS_CANVAS_EVENT_RENDER_POST =
    EO_EVENT_DESCRIPTION("Render Post", "Called just after rendering stops on the canvas target @since 1.2");
 
+EAPI const Eo_Event_Description _EVAS_CANVAS_EVENT_AXIS_UPDATE =
+   EO_EVENT_DESCRIPTION("Axis Update", "Device axis value changed");
+
 EAPI const Eo_Event_Description _EVAS_CANVAS_EVENT_FOCUS_IN =
    EO_HOT_EVENT_DESCRIPTION("Canvas Focus In", "Canvas got focus as a whole");
 EAPI const Eo_Event_Description _EVAS_CANVAS_EVENT_FOCUS_OUT =
@@ -63,7 +66,8 @@ static const Eo_Event_Description *_legacy_evas_callback_table[EVAS_CALLBACK_LAS
    EVAS_CANVAS_EVENT_RENDER_PRE,
    EVAS_CANVAS_EVENT_RENDER_POST,
    EVAS_OBJECT_EVENT_IMAGE_RESIZE,
-   NULL
+   NULL,
+   EVAS_CANVAS_EVENT_AXIS_UPDATE
 };
 
 typedef struct
diff --git a/src/lib/evas/canvas/evas_canvas.eo b/src/lib/evas/canvas/evas_canvas.eo
index 793bd86..51c8a7d 100644
--- a/src/lib/evas/canvas/evas_canvas.eo
+++ b/src/lib/evas/canvas/evas_canvas.eo
@@ -1757,6 +1757,23 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface)
             @in uint keycode; /*@ Key scan code numeric value for canvas. */
          }
       }
+      event_feed_axis_update {
+         /*@
+         Input device axis update event feed.
+
+         This function will set some evas properties that is necessary when
+         an e.g. stylus axis is updated. It prepares information to be treated
+         by the callback function. */
+
+         params {
+            @in uint timestamp;
+            @in int device;
+            @in int toolid;
+            @in int naxes;
+            @in const (struct _Evas_Axis)* axis;
+            @in const(void)* data; /*@ Data for canvas. */
+         }
+      }
    }
    implements {
       Eo.Base.constructor;
diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c
index 6ab1ab3..d0e1f90 100644
--- a/src/lib/evas/canvas/evas_events.c
+++ b/src/lib/evas/canvas/evas_events.c
@@ -2720,6 +2720,55 @@ _evas_canvas_event_feed_hold(Eo *eo_e, Evas_Public_Data *e, int hold, unsigned i
    _evas_object_event_new();
 }
 
+void
+_canvas_event_feed_axis_update_internal(Evas *eo_e, Evas_Public_Data *e, unsigned int timestamp, int device, int toolid, int naxis, const struct _Evas_Axis *axis, const void *data)
+{
+   Eina_List *l, *copy;
+   Evas_Event_Axis_Update ev;
+   Evas_Object *eo_obj;
+   int event_id = 0;
+
+   if (e->is_frozen) return;
+   e->last_timestamp = timestamp;
+
+   _evas_object_event_new();
+
+   event_id = _evas_event_counter;
+   ev.data = (void *)data;
+   ev.timestamp = timestamp;
+   ev.device = device;
+   ev.toolid = toolid;
+   ev.naxis = naxis;
+   ev.axis = axis;
+   ev.dev = _evas_device_top_get(eo_e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+
+   _evas_walk(e);
+   copy = evas_event_list_copy(e->pointer.object.in);
+
+   EINA_LIST_FOREACH(copy, l, eo_obj)
+     {
+        Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+        if (!evas_event_freezes_through(eo_obj, obj))
+          {
+             evas_object_event_callback_call(eo_obj, obj,
+                                             EVAS_CALLBACK_AXIS_UPDATE, &ev,
+                                             event_id);
+             if (e->delete_me || e->is_frozen) break;
+          }
+     }
+   eina_list_free(copy);
+   _evas_post_event_callback_call(eo_e, e);
+
+   _evas_unwalk(e);
+}
+
+EOLIAN void
+_evas_canvas_event_feed_axis_update(Evas *eo_e, Evas_Public_Data *pd, unsigned int timestamp, int device, int toolid, int naxis, const struct _Evas_Axis *axis, const void *data)
+{
+   _canvas_event_feed_axis_update_internal(eo_e, pd, timestamp, device, toolid, naxis, axis, data);
+}
+
 static void
 _feed_mouse_move_eval_internal(Eo *eo_obj, Evas_Object_Protected_Data *obj)
 {
@@ -2885,6 +2934,12 @@ _evas_canvas_event_refeed_event(Eo *eo_e, Evas_Public_Data *e EINA_UNUSED, void
              evas_event_feed_key_up(eo_e, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, ev->data);
              break;
           }
+      case EVAS_CALLBACK_AXIS_UPDATE:
+          {
+             Evas_Event_Axis_Update *ev = event_copy;
+             evas_event_feed_axis_update(eo_e, ev->timestamp, ev->device, ev->toolid, ev->naxis, ev->axis, ev->data);
+             break;
+          }
       default: /* All non-input events are not handeled */
         break;
      }
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index f216221..4e9f5fa 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1422,6 +1422,7 @@ void _canvas_event_feed_key_up(Eo *e, void *_pd, va_list *list);
 void _canvas_event_feed_key_down_with_keycode(Eo *e, void *_pd, va_list *list);
 void _canvas_event_feed_key_up_with_keycode(Eo *e, void *_pd, va_list *list);
 void _canvas_event_feed_hold(Eo *e, void *_pd, va_list *list);
+void _canvas_event_feed_axis_update(Eo *e, void *_pd, va_list *list);
 void _canvas_event_refeed_event(Eo *e, void *_pd, va_list *list);
 void _canvas_event_down_count_get(Eo *e, void *_pd, va_list *list);
 void _canvas_tree_objects_at_xy_get(Eo *e, void *_pd, va_list *list);
-- 
2.1.0

