evas: Add normalized and window coordinates to axis events

This is for Wacom graphics tablets (with a pen).

The raw data sent by ecore to evas (and then to apps) is pretty
useless as it's not normalized, and apps have no way of knowing the
dimensions of the tablet, without themselves opening the device
(we don't know nor expose the path to the device).

This is for Xi2 only for now, as Wayland support hasn't been done
yet.

The intent is to deprecate LABEL_X and LABEL_Y. I'm not sure yet
if the normalized value is useful or not (it would seem we may not
be able to provide this info in Wayland).

The new WINDOW_X, WINDOW_Y labels will be used in the new event
type (Efl.Event.Pointer). Normalized values are not exposed yet,
let's decide if we want them or not first (based on what can be
done in Wayland space).

@feature
This commit is contained in:
Jean-Philippe Andre 2016-08-25 17:54:04 +09:00
parent 443aa91d53
commit 60526528a6
6 changed files with 102 additions and 13 deletions

View File

@ -4525,6 +4525,7 @@ _direct_mouse_out_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info)
static Eina_Bool
_direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
{
Eina_Bool haswinx = 0, haswiny = 0;
Efl_Event_Pointer_Data *ev;
Efl_Event_Pointer *evt;
Evas *e = ee->evas;
@ -4549,14 +4550,40 @@ _direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
const Ecore_Axis *axis = &(info->axis[n]);
switch (axis->label)
{
case EVAS_AXIS_LABEL_X:
case EVAS_AXIS_LABEL_WINDOW_X:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
x = axis->value;
haswinx = EINA_TRUE;
break;
case EVAS_AXIS_LABEL_WINDOW_Y:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
y = axis->value;
haswiny = EINA_TRUE;
break;
case EVAS_AXIS_LABEL_X:
if (!haswinx)
{
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
x = axis->value;
}
break;
case EVAS_AXIS_LABEL_Y:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
y = axis->value;
if (!haswiny)
{
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
y = axis->value;
}
break;
case EVAS_AXIS_LABEL_NORMAL_X:
ev->raw.x = axis->value;
break;
case EVAS_AXIS_LABEL_NORMAL_Y:
ev->raw.y = axis->value;
break;
case EVAS_AXIS_LABEL_PRESSURE:

View File

@ -319,7 +319,11 @@ extern "C" {
ECORE_AXIS_LABEL_TOUCH_WIDTH_MAJOR, /**< Length of contact ellipse along AZIMUTH. Range: Unbounded: Unit: Same as ECORE_AXIS_LABEL_{X,Y}. @since 1.13 */
ECORE_AXIS_LABEL_TOUCH_WIDTH_MINOR, /**< Length of contact ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as ECORE_AXIS_LABEL_{X,Y}. @since 1.13 */
ECORE_AXIS_LABEL_TOOL_WIDTH_MAJOR, /**< Length of tool ellipse along AZIMUTH. Range: Unbounded. Unit: Same as ECORE_AXIS_LABEL_{X,Y}. @since 1.13 */
ECORE_AXIS_LABEL_TOOL_WIDTH_MINOR /**< Length of tool ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as ECORE_AXIS_LABEL_{X,Y}. @since 1.13 */
ECORE_AXIS_LABEL_TOOL_WIDTH_MINOR, /**< Length of tool ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as ECORE_AXIS_LABEL_{X,Y}. @since 1.13 */
ECORE_AXIS_LABEL_WINDOW_X, /**< X coordinate mapped to the window. @since 1.19 */
ECORE_AXIS_LABEL_WINDOW_Y, /**< Y coordinate mapped to the window. @since 1.19 */
ECORE_AXIS_LABEL_NORMAL_X, /**< X normalized to the [0, 1] range. @since 1.19 */
ECORE_AXIS_LABEL_NORMAL_Y, /**< Y normalized to the [0, 1] range. @since 1.19 */
} Ecore_Axis_Label; /**< @since 1.13 */
struct _Ecore_Axis

View File

@ -494,7 +494,7 @@ _ecore_x_input_axis_handler(XEvent *xevent, XIDeviceInfo *dev)
{
if (xevent->type != GenericEvent) return;
XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data);
unsigned int n = _ecore_x_count_bits(*evd->valuators.mask);
unsigned int n = _ecore_x_count_bits(*evd->valuators.mask) + 4;
int i;
int j = 0;
double tiltx = 0, tilty = 0;
@ -514,15 +514,29 @@ _ecore_x_input_axis_handler(XEvent *xevent, XIDeviceInfo *dev)
{
if (inf->label == _ecore_x_input_get_axis_label("Abs X"))
{
int x = evd->valuators.values[j];
axis_ptr->label = ECORE_AXIS_LABEL_X;
axis_ptr->value = evd->valuators.values[j];
axis_ptr->value = x;
axis_ptr++;
if (inf->max > inf->min)
{
axis_ptr->label = ECORE_AXIS_LABEL_NORMAL_X;
axis_ptr->value = (x - inf->min) / (inf->max - inf->min);
axis_ptr++;
}
}
else if (inf->label == _ecore_x_input_get_axis_label("Abs Y"))
{
int y = evd->valuators.values[j];
axis_ptr->label = ECORE_AXIS_LABEL_Y;
axis_ptr->value = evd->valuators.values[j];
axis_ptr->value = y;
axis_ptr++;
if (inf->max > inf->min)
{
axis_ptr->label = ECORE_AXIS_LABEL_NORMAL_Y;
axis_ptr->value = (y - inf->min) / (inf->max - inf->min);
axis_ptr++;
}
}
else if (inf->label == _ecore_x_input_get_axis_label("Abs Pressure"))
{
@ -602,6 +616,15 @@ _ecore_x_input_axis_handler(XEvent *xevent, XIDeviceInfo *dev)
n = (axis_ptr - axis);
if (n > 0)
{
/* event position in the window - most useful */
axis_ptr->label = ECORE_AXIS_LABEL_WINDOW_X;
axis_ptr->value = evd->event_x;
axis_ptr++;
axis_ptr->label = ECORE_AXIS_LABEL_WINDOW_Y;
axis_ptr->value = evd->event_y;
axis_ptr++;
n += 2;
shrunk_axis = realloc(axis, n * sizeof(Ecore_Axis));
if (shrunk_axis != NULL) axis = shrunk_axis;
_ecore_x_axis_update(evd->child ? evd->child : evd->event,

View File

@ -33,7 +33,7 @@ struct _Efl_Event_Pointer_Data
double radius, radius_x, radius_y;
double pressure;
double angle;
Eina_Vector2 cur, prev;
Eina_Vector2 cur, prev, raw;
struct {
Efl_Orient dir;
int z;

View File

@ -607,7 +607,11 @@ typedef enum _Evas_Axis_Label
EVAS_AXIS_LABEL_TOUCH_WIDTH_MAJOR, /**< Length of contact ellipse along AZIMUTH. Range: Unbounded: Unit: Same as EVAS_AXIS_LABEL_{X,Y}. @since 1.13 */
EVAS_AXIS_LABEL_TOUCH_WIDTH_MINOR, /**< Length of contact ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as EVAS_AXIS_LABEL_{X,Y}. @since 1.13 */
EVAS_AXIS_LABEL_TOOL_WIDTH_MAJOR, /**< Length of tool ellipse along AZIMUTH. Range: Unbounded. Unit: Same as EVAS_AXIS_LABEL_{X,Y}. @since 1.13 */
EVAS_AXIS_LABEL_TOOL_WIDTH_MINOR /**< Length of tool ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as EVAS_AXIS_LABEL_{X,Y}. @since 1.13 */
EVAS_AXIS_LABEL_TOOL_WIDTH_MINOR, /**< Length of tool ellipse perpendicular to AZIMUTH. Range: Unbounded. Unit: Same as EVAS_AXIS_LABEL_{X,Y}. @since 1.13 */
EVAS_AXIS_LABEL_WINDOW_X, /**< X coordinate mapped to the window. @since 1.19 */
EVAS_AXIS_LABEL_WINDOW_Y, /**< Y coordinate mapped to the window. @since 1.19 */
EVAS_AXIS_LABEL_NORMAL_X, /**< X normalized to the [0, 1] range. @since 1.19 */
EVAS_AXIS_LABEL_NORMAL_Y, /**< Y normalized to the [0, 1] range. @since 1.19 */
} Evas_Axis_Label; /**< Types of recognized device axes @since 1.13 */
struct _Evas_Axis

View File

@ -2929,7 +2929,9 @@ evas_event_feed_axis_update(Evas *eo_e, unsigned int timestamp, int device, int
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(eo_e, EVAS_CANVAS_CLASS));
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
Efl_Event_Pointer_Data *ev = NULL;
Eina_Bool haswinx = 0, haswiny = 0;
Efl_Event_Pointer *evt;
double x = 0, y = 0;
int n;
evt = efl_event_instance_get(EFL_EVENT_POINTER_CLASS, eo_e, (void **) &ev);
@ -2946,14 +2948,40 @@ evas_event_feed_axis_update(Evas *eo_e, unsigned int timestamp, int device, int
const Evas_Axis *axis = &(axes[n]);
switch (axis->label)
{
case EVAS_AXIS_LABEL_X:
case EVAS_AXIS_LABEL_WINDOW_X:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
ev->cur.x = axis->value;
x = axis->value;
haswinx = EINA_TRUE;
break;
case EVAS_AXIS_LABEL_WINDOW_Y:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
y = axis->value;
haswiny = EINA_TRUE;
break;
case EVAS_AXIS_LABEL_X:
if (!haswinx)
{
_efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
x = axis->value;
}
break;
case EVAS_AXIS_LABEL_Y:
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
ev->cur.y = axis->value;
if (!haswiny)
{
_efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
y = axis->value;
}
break;
case EVAS_AXIS_LABEL_NORMAL_X:
ev->raw.x = axis->value;
break;
case EVAS_AXIS_LABEL_NORMAL_Y:
ev->raw.y = axis->value;
break;
case EVAS_AXIS_LABEL_PRESSURE:
@ -2979,6 +3007,9 @@ evas_event_feed_axis_update(Evas *eo_e, unsigned int timestamp, int device, int
}
}
ev->cur.x = x;
ev->cur.y = y;
/* FIXME: set proper device based on the device id (X or WL specific) */
ev->device = _evas_device_top_get(eo_e); // FIXME
(void) device;