Recording: support new EFL input events
During recording, hooking on Evas functions can't work anymore as they are no more invoked internally. The new way to catch the events is to listen to them on the canvas. Additionally, regular mouse events are now multi events whose tool (device id) is 0, as well as key events with and without keycode are now always considered with a keycode that can be 0. Previous events catching has been kept to support legacy applications.
This commit is contained in:
parent
fefa31d7b2
commit
95327a0f7c
|
@ -76,6 +76,9 @@ _event_specific_info_get(const Variant_st *v, char output[1024])
|
|||
case TSUITE_EVENT_MULTI_DOWN: case TSUITE_EVENT_MULTI_UP:
|
||||
{
|
||||
multi_event *t = v->data;
|
||||
if (!t->d)
|
||||
sprintf(output, "Button %d Flags %d", t->b, t->flags);
|
||||
else
|
||||
sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f Flags %d",
|
||||
t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, t->flags);
|
||||
break;
|
||||
|
@ -83,6 +86,9 @@ _event_specific_info_get(const Variant_st *v, char output[1024])
|
|||
case TSUITE_EVENT_MULTI_MOVE:
|
||||
{
|
||||
multi_move *t = v->data;
|
||||
if (!t->d)
|
||||
sprintf(output, "X %d Y %d", t->x, t->y);
|
||||
else
|
||||
sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f",
|
||||
t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy);
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#define _GNU_SOURCE 1
|
||||
#define EFL_EO_API_SUPPORT
|
||||
#define EFL_BETA_API_SUPPORT
|
||||
#include <Eo.h>
|
||||
#include <Eet.h>
|
||||
#include <Evas.h>
|
||||
#include <Ecore.h>
|
||||
|
@ -43,6 +46,94 @@ static Tsuite_Data ts;
|
|||
static Eina_List *evas_list = NULL; /* List of Evas pointers */
|
||||
static int ignore_evas_new = 0; /* Counter to know if we should ignore evas new or not. */
|
||||
|
||||
static Tsuite_Event_Type
|
||||
tsuite_event_pointer_type_get(Efl_Pointer_Action t)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case EFL_POINTER_ACTION_IN: return TSUITE_EVENT_MOUSE_IN;
|
||||
case EFL_POINTER_ACTION_OUT: return TSUITE_EVENT_MOUSE_OUT;
|
||||
case EFL_POINTER_ACTION_DOWN: return TSUITE_EVENT_MULTI_DOWN;
|
||||
case EFL_POINTER_ACTION_UP: return TSUITE_EVENT_MULTI_UP;
|
||||
case EFL_POINTER_ACTION_MOVE: return TSUITE_EVENT_MULTI_MOVE;
|
||||
case EFL_POINTER_ACTION_WHEEL: return TSUITE_EVENT_MOUSE_WHEEL;
|
||||
default:
|
||||
return TSUITE_EVENT_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TSUITE
|
||||
static const char *
|
||||
_event_name_get(Tsuite_Event_Type type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TSUITE_EVENT_MOUSE_IN: return "Mouse In";
|
||||
case TSUITE_EVENT_MOUSE_OUT: return "Mouse Out";
|
||||
case TSUITE_EVENT_MOUSE_DOWN: return "Mouse Down";
|
||||
case TSUITE_EVENT_MOUSE_UP: return "Mouse Up";
|
||||
case TSUITE_EVENT_MOUSE_MOVE: return "Mouse Move";
|
||||
case TSUITE_EVENT_MOUSE_WHEEL: return "Mouse Wheel";
|
||||
case TSUITE_EVENT_MULTI_DOWN: return "Multi Down";
|
||||
case TSUITE_EVENT_MULTI_UP: return "Multi Up";
|
||||
case TSUITE_EVENT_MULTI_MOVE: return "Multi Move";
|
||||
case TSUITE_EVENT_KEY_DOWN: return "Key Down";
|
||||
case TSUITE_EVENT_KEY_UP: return "Key Up";
|
||||
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: return "Key Down with Keycode";
|
||||
case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return "Key Up with Keycode";
|
||||
case TSUITE_EVENT_TAKE_SHOT: return "Take shot";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static Eina_Bool
|
||||
_is_hook_duplicate(const Variant_st *v, Tsuite_Event_Type ev_type, const void *info, int len)
|
||||
{
|
||||
if (v->t.type == tsuite_event_mapping_type_str_get(ev_type) &&
|
||||
!memcmp(v->data, info, len)) return EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* Adding variant to list, this list is later written to EET file */
|
||||
#define ADD_TO_LIST(EVT_TYPE, EVT_STRUCT_NAME, INFO) \
|
||||
do { /* This macro will add event to EET data list */ \
|
||||
if (vr_list && _hook_setting->recording) \
|
||||
{ \
|
||||
const Variant_st *prev_v = eina_list_last_data_get(vr_list->variant_list); \
|
||||
if (!prev_v || !_is_hook_duplicate(prev_v, EVT_TYPE, &INFO, sizeof(EVT_STRUCT_NAME))) \
|
||||
{ \
|
||||
printf("Recording %s\n", tsuite_event_mapping_type_str_get(EVT_TYPE)); \
|
||||
Variant_st *v = malloc(sizeof(Variant_st)); \
|
||||
v->data = malloc(sizeof(EVT_STRUCT_NAME)); \
|
||||
_variant_type_set(tsuite_event_mapping_type_str_get(EVT_TYPE), \
|
||||
&v->t, EINA_FALSE); \
|
||||
memcpy(v->data, &INFO, sizeof(EVT_STRUCT_NAME)); \
|
||||
vr_list->variant_list = eina_list_append(vr_list->variant_list, v); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
evas_list_find(void *ptr)
|
||||
{ /* We just compare the pointers */
|
||||
Eina_List *l;
|
||||
void *data;
|
||||
int n = 0;
|
||||
|
||||
EINA_LIST_FOREACH(evas_list, l, data)
|
||||
{ /* Get the nuber of Evas Pointer */
|
||||
if (ptr == data)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
_tsuite_verbosef(const char *fmt, ...)
|
||||
{
|
||||
|
@ -326,6 +417,138 @@ ecore_shutdown(void)
|
|||
return _ecore_shutdown();
|
||||
}
|
||||
|
||||
static void
|
||||
_event_pointer_cb(void *data, const Efl_Event *event)
|
||||
{
|
||||
Eo *eo_e = data;
|
||||
Eo *evp = event->info;
|
||||
if (!evp) return;
|
||||
|
||||
int timestamp = efl_input_timestamp_get(evp);
|
||||
int n_evas = evas_list_find(eo_e);
|
||||
Efl_Pointer_Action action = efl_input_pointer_action_get(evp);
|
||||
Tsuite_Event_Type evt = tsuite_event_pointer_type_get(action);
|
||||
|
||||
if (!timestamp) return;
|
||||
|
||||
#ifdef DEBUG_TSUITE
|
||||
printf("Calling \"%s\" timestamp=<%u>\n", _event_name_get(evt), timestamp);
|
||||
#endif
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case EFL_POINTER_ACTION_MOVE:
|
||||
{
|
||||
double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0;
|
||||
int tool = efl_input_pointer_tool_get(evp);
|
||||
int x = 0, y = 0;
|
||||
efl_input_pointer_position_get(evp, &x, &y);
|
||||
multi_move t = { tool, x, y, rad, radx, rady, pres, ang, fx, fy, timestamp, n_evas };
|
||||
if (t.n_evas >= 0) ADD_TO_LIST(evt, multi_move, t);
|
||||
break;
|
||||
}
|
||||
case EFL_POINTER_ACTION_DOWN: case EFL_POINTER_ACTION_UP:
|
||||
{
|
||||
double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0;
|
||||
int b = efl_input_pointer_button_get(evp);
|
||||
int tool = efl_input_pointer_tool_get(evp);
|
||||
int x = 0, y = 0;
|
||||
efl_input_pointer_position_get(evp, &x, &y);
|
||||
Efl_Pointer_Flags flags = efl_input_pointer_button_flags_get(evp);
|
||||
multi_event t = { tool, b, x, y, rad, radx, rady, pres, ang,
|
||||
fx, fy, flags, timestamp, n_evas };
|
||||
if (t.n_evas >= 0) ADD_TO_LIST(evt, multi_event, t);
|
||||
break;
|
||||
}
|
||||
case EFL_POINTER_ACTION_IN: case EFL_POINTER_ACTION_OUT:
|
||||
{
|
||||
mouse_in_mouse_out t = { timestamp, n_evas };
|
||||
if (t.n_evas >= 0) ADD_TO_LIST(evt, mouse_in_mouse_out, t);
|
||||
break;
|
||||
}
|
||||
case EFL_POINTER_ACTION_WHEEL:
|
||||
{
|
||||
int direction = efl_input_pointer_wheel_direction_get(evp);
|
||||
int z = efl_input_pointer_wheel_delta_get(evp);
|
||||
mouse_wheel t = { direction, z, timestamp, n_evas };
|
||||
if (t.n_evas >= 0) ADD_TO_LIST(evt, mouse_wheel, t);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_event_key_cb(void *data, const Efl_Event *event)
|
||||
{
|
||||
Efl_Input_Key *evk = event->info;
|
||||
Eo *eo_e = data;
|
||||
if (!evk) return;
|
||||
const char *key = efl_input_key_name_get(evk);
|
||||
int timestamp = efl_input_timestamp_get(evk);
|
||||
int n_evas = evas_list_find(eo_e);
|
||||
Tsuite_Event_Type evt = TSUITE_EVENT_KEY_UP_WITH_KEYCODE;
|
||||
|
||||
if (efl_input_key_pressed_get(evk))
|
||||
{
|
||||
if (!strcmp(key, shot_key))
|
||||
{
|
||||
#ifdef DEBUG_TSUITE
|
||||
printf("Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp);
|
||||
#endif
|
||||
take_screenshot t = { timestamp, n_evas };
|
||||
if (t.n_evas >= 0)
|
||||
ADD_TO_LIST(TSUITE_EVENT_TAKE_SHOT, take_screenshot, t);
|
||||
return;
|
||||
}
|
||||
if (!strcmp(key, SAVE_KEY_STR))
|
||||
{
|
||||
if (_hook_setting)
|
||||
{
|
||||
if (vr_list && _hook_setting->recording)
|
||||
write_events(_hook_setting->file_name, vr_list);
|
||||
#ifdef DEBUG_TSUITE
|
||||
printf("Save events: %s timestamp=<%u>\n", __func__, timestamp);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
evt = TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp(key, shot_key) || !strcmp(key, SAVE_KEY_STR)) return;
|
||||
}
|
||||
if (vr_list && _hook_setting->recording)
|
||||
{ /* Construct duplicate strings, free them when list if freed */
|
||||
key_down_key_up_with_keycode t;
|
||||
t.timestamp = timestamp;
|
||||
t.keyname = eina_stringshare_add(key);
|
||||
t.key = eina_stringshare_add(efl_input_key_get(evk));
|
||||
t.string = eina_stringshare_add(efl_input_key_string_get(evk));
|
||||
t.compose = eina_stringshare_add(efl_input_key_compose_get(evk));
|
||||
t.keycode = efl_input_key_code_get(evk);
|
||||
t.n_evas = n_evas;
|
||||
if (t.n_evas >= 0) ADD_TO_LIST(evt, key_down_key_up_with_keycode, t);
|
||||
}
|
||||
}
|
||||
|
||||
// note: "hold" event comes from above (elm), not below (ecore)
|
||||
EFL_CALLBACKS_ARRAY_DEFINE(_event_pointer_callbacks,
|
||||
{ EFL_EVENT_POINTER_MOVE, _event_pointer_cb },
|
||||
{ EFL_EVENT_POINTER_DOWN, _event_pointer_cb },
|
||||
{ EFL_EVENT_POINTER_UP, _event_pointer_cb },
|
||||
{ EFL_EVENT_POINTER_IN, _event_pointer_cb },
|
||||
{ EFL_EVENT_POINTER_OUT, _event_pointer_cb },
|
||||
{ EFL_EVENT_POINTER_WHEEL, _event_pointer_cb },
|
||||
{ EFL_EVENT_FINGER_MOVE, _event_pointer_cb },
|
||||
{ EFL_EVENT_FINGER_DOWN, _event_pointer_cb },
|
||||
{ EFL_EVENT_FINGER_UP, _event_pointer_cb },
|
||||
{ EFL_EVENT_KEY_DOWN, _event_key_cb },
|
||||
{ EFL_EVENT_KEY_UP, _event_key_cb }
|
||||
)
|
||||
|
||||
EAPI Evas *
|
||||
evas_new(void)
|
||||
{
|
||||
|
@ -336,6 +559,7 @@ evas_new(void)
|
|||
if (ignore_evas_new == 0)
|
||||
{
|
||||
evas_list = eina_list_append(evas_list, evas);
|
||||
efl_event_callback_array_add(evas, _event_pointer_callbacks(), evas);
|
||||
#ifdef DEBUG_TSUITE
|
||||
printf("Appended EVAS=<%p> list size=<%d>\n", evas, eina_list_count(evas_list));
|
||||
#endif
|
||||
|
@ -475,10 +699,19 @@ tsuite_feed_event(void *data)
|
|||
#ifdef DEBUG_TSUITE
|
||||
printf("%s evas_event_feed_multi_down timestamp=<%u>, t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
|
||||
#endif
|
||||
if (!t->d)
|
||||
{
|
||||
evas_event_feed_mouse_down(eina_list_nth(evas_list, t->n_evas),
|
||||
t->b, t->flags, time(NULL), NULL);
|
||||
if (rect) evas_object_color_set(rect, 255, 255, 0, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_event_feed_multi_down(eina_list_nth(evas_list, t->n_evas),
|
||||
t->d, t->x, t->y, t->rad,
|
||||
t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
|
||||
t->flags, time(NULL), NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -489,10 +722,19 @@ tsuite_feed_event(void *data)
|
|||
#ifdef DEBUG_TSUITE
|
||||
printf("%s evas_event_feed_multi_up timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
|
||||
#endif
|
||||
if (!t->d)
|
||||
{
|
||||
evas_event_feed_mouse_up(eina_list_nth(evas_list, t->n_evas),
|
||||
t->b, t->flags, time(NULL), NULL);
|
||||
if (rect) evas_object_color_set(rect, 255, 0, 0, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_event_feed_multi_up(eina_list_nth(evas_list, t->n_evas),
|
||||
t->d, t->x, t->y, t->rad,
|
||||
t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
|
||||
t->flags, time(NULL), NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -503,10 +745,23 @@ tsuite_feed_event(void *data)
|
|||
#ifdef DEBUG_TSUITE
|
||||
printf("%s evas_event_feed_multi_move timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
|
||||
#endif
|
||||
if (!t->d)
|
||||
{
|
||||
evas_event_feed_mouse_move(eina_list_nth(evas_list, t->n_evas),
|
||||
t->x, t->y, time(NULL), NULL);
|
||||
if (rect)
|
||||
{
|
||||
evas_object_move(rect, t->x, t->y);
|
||||
evas_object_color_set(rect, 255, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_event_feed_multi_move(eina_list_nth(evas_list, t->n_evas),
|
||||
t->d, t->x, t->y, t->rad,
|
||||
t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
|
||||
time(NULL), NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -657,52 +912,6 @@ ecore_main_loop_begin(void)
|
|||
return _ecore_main_loop_begin();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_is_hook_duplicate(const Variant_st *v, Tsuite_Event_Type ev_type, const void *info, int len)
|
||||
{
|
||||
if (v->t.type == tsuite_event_mapping_type_str_get(ev_type) &&
|
||||
!memcmp(v->data, info, len)) return EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* Adding variant to list, this list is later written to EET file */
|
||||
#define ADD_TO_LIST(EVT_TYPE, EVT_STRUCT_NAME, INFO) \
|
||||
do { /* This macro will add event to EET data list */ \
|
||||
if (vr_list && _hook_setting->recording) \
|
||||
{ \
|
||||
const Variant_st *prev_v = eina_list_last_data_get(vr_list->variant_list); \
|
||||
if (!prev_v || !_is_hook_duplicate(prev_v, EVT_TYPE, &INFO, sizeof(EVT_STRUCT_NAME))) \
|
||||
{ \
|
||||
printf("Recording %s\n", tsuite_event_mapping_type_str_get(EVT_TYPE)); \
|
||||
Variant_st *v = malloc(sizeof(Variant_st)); \
|
||||
v->data = malloc(sizeof(EVT_STRUCT_NAME)); \
|
||||
_variant_type_set(tsuite_event_mapping_type_str_get(EVT_TYPE), \
|
||||
&v->t, EINA_FALSE); \
|
||||
memcpy(v->data, &INFO, sizeof(EVT_STRUCT_NAME)); \
|
||||
vr_list->variant_list = eina_list_append(vr_list->variant_list, v); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int evas_list_find(void *ptr)
|
||||
{ /* We just compare the pointers */
|
||||
Eina_List *l;
|
||||
void *data;
|
||||
int n = 0;
|
||||
|
||||
EINA_LIST_FOREACH(evas_list, l, data)
|
||||
{ /* Get the nuber of Evas Pointer */
|
||||
if (ptr == data)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Tsuite_Event_Type
|
||||
tsuite_event_type_get(Evas_Callback_Type t)
|
||||
{
|
||||
|
@ -877,8 +1086,8 @@ evas_event_feed_multi_down(Evas *e, int d, int x, int y,
|
|||
#ifdef DEBUG_TSUITE
|
||||
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
|
||||
#endif
|
||||
multi_event t = { d, x, y, rad, radx, rady, pres, ang,
|
||||
fx, fy, flags, timestamp, evas_list_find(e) };
|
||||
multi_event t = { d, 0, x, y, rad, radx, rady, pres, ang,
|
||||
fx, fy, flags, timestamp, evas_list_find(e)};
|
||||
|
||||
int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_DOWN);
|
||||
if (t.n_evas >= 0)
|
||||
|
@ -902,7 +1111,7 @@ evas_event_feed_multi_up(Evas *e, int d, int x, int y,
|
|||
#ifdef DEBUG_TSUITE
|
||||
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
|
||||
#endif
|
||||
multi_event t = { d, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, evas_list_find(e) };
|
||||
multi_event t = { d, 0, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, evas_list_find(e) };
|
||||
int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_UP);
|
||||
if (t.n_evas >= 0)
|
||||
ADD_TO_LIST(evt, multi_event, t);
|
||||
|
|
|
@ -681,6 +681,7 @@ multi_event_desc_make(void)
|
|||
_d = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "d", d, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "b", b, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "x", x, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "y", y, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "rad", rad, EET_T_DOUBLE);
|
||||
|
|
|
@ -147,6 +147,7 @@ struct _key_down_key_up_with_keycode
|
|||
struct _multi_event
|
||||
{
|
||||
int d;
|
||||
int b; /* In case of simple mouse down/up, corresponds to the button */
|
||||
int x;
|
||||
int y;
|
||||
double rad;
|
||||
|
|
Loading…
Reference in New Issue