Introduce a remote actions injection mechanism
By executing an application under the player (option --external-injection), actions can be remotely forwarded. The communication is done via Eina Debug channel. Therefore, efl_debugd must be run before the application. An injection tool has been implemented to show how to communicate with the application.
This commit is contained in:
parent
0c30b92bc6
commit
9c3fe1b118
|
@ -1,6 +1,6 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
bin_PROGRAMS = exactness exactness_inspect exactness_play exactness_record
|
||||
bin_PROGRAMS = exactness exactness_inspect exactness_play exactness_record exactness_inject
|
||||
|
||||
exactness_SOURCES = exactness.c ../lib/tsuite_file_data.c ../lib/tsuite_common.c
|
||||
|
||||
|
@ -10,6 +10,8 @@ exactness_play_SOURCES = player.c ../lib/tsuite_file_data.c ../lib/tsuite_common
|
|||
|
||||
exactness_record_SOURCES = recorder.c ../lib/tsuite_file_data.c ../lib/tsuite_common.c ../lib/file.c
|
||||
|
||||
exactness_inject_SOURCES = injector.c ../lib/tsuite_file_data.c ../lib/file.c
|
||||
|
||||
exactness_LDADD = @EFL_LIBS@
|
||||
|
||||
exactness_inspect_LDADD = @EFL_LIBS@
|
||||
|
@ -18,6 +20,8 @@ exactness_play_LDADD = @EFL_LIBS@
|
|||
|
||||
exactness_record_LDADD = @EFL_LIBS@
|
||||
|
||||
exactness_inject_LDADD = @EFL_LIBS@
|
||||
|
||||
exactness_CFLAGS = \
|
||||
@EFL_CFLAGS@ \
|
||||
-I$(top_srcdir)/src/lib \
|
||||
|
@ -29,3 +33,6 @@ exactness_inspect_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
|
|||
exactness_play_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
|
||||
|
||||
exactness_record_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
|
||||
|
||||
exactness_inject_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
|
||||
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
#define _GNU_SOURCE 1
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifndef EFL_EO_API_SUPPORT
|
||||
#define EFL_EO_API_SUPPORT
|
||||
#endif
|
||||
#include <Eina.h>
|
||||
#include <Eet.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Getopt.h>
|
||||
#include <Elementary.h>
|
||||
#include <Exactness.h>
|
||||
|
||||
#include "exactness_private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Eina_Debug_Session *session;
|
||||
int srcid;
|
||||
void *buffer;
|
||||
unsigned int size;
|
||||
} _Main_Loop_Info;
|
||||
|
||||
#define WRAPPER_TO_XFER_MAIN_LOOP(foo) \
|
||||
static void \
|
||||
_intern_main_loop ## foo(void *data) \
|
||||
{ \
|
||||
_Main_Loop_Info *info = data; \
|
||||
_main_loop ## foo(info->session, info->srcid, info->buffer, info->size); \
|
||||
free(info->buffer); \
|
||||
free(info); \
|
||||
} \
|
||||
static Eina_Bool \
|
||||
foo(Eina_Debug_Session *session, int srcid, void *buffer, int size) \
|
||||
{ \
|
||||
_Main_Loop_Info *info = calloc(1, sizeof(*info)); \
|
||||
info->session = session; \
|
||||
info->srcid = srcid; \
|
||||
info->size = size; \
|
||||
if (info->size) \
|
||||
{ \
|
||||
info->buffer = malloc(info->size); \
|
||||
memcpy(info->buffer, buffer, info->size); \
|
||||
} \
|
||||
ecore_main_loop_thread_safe_call_async(_intern_main_loop ## foo, info); \
|
||||
return EINA_TRUE; \
|
||||
}
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define SWAP_64(x) x
|
||||
#define SWAP_32(x) x
|
||||
#define SWAP_16(x) x
|
||||
#define SWAP_DBL(x) x
|
||||
#else
|
||||
#define SWAP_64(x) eina_swap64(x)
|
||||
#define SWAP_32(x) eina_swap32(x)
|
||||
#define SWAP_16(x) eina_swap16(x)
|
||||
#define SWAP_DBL(x) SWAP_64(x)
|
||||
#endif
|
||||
|
||||
#define EXTRACT_INT(_buf) \
|
||||
({ \
|
||||
int __i; \
|
||||
memcpy(&__i, _buf, sizeof(int)); \
|
||||
_buf += sizeof(int); \
|
||||
SWAP_32(__i); \
|
||||
})
|
||||
|
||||
#define STORE_INT(_buf, __i) \
|
||||
{ \
|
||||
int __i2 = SWAP_32(__i); \
|
||||
memcpy(_buf, &__i2, sizeof(int)); \
|
||||
_buf += sizeof(int); \
|
||||
}
|
||||
|
||||
#define STORE_DOUBLE(_buf, __d) \
|
||||
{ \
|
||||
double __d2 = SWAP_DBL(__d); \
|
||||
memcpy(_buf, &__d2, sizeof(double)); \
|
||||
_buf += sizeof(double); \
|
||||
}
|
||||
|
||||
#define STORE_STRING(_buf, __s) \
|
||||
{ \
|
||||
int __len = (__s ? strlen(__s) : 0) + 1; \
|
||||
if (__s) memcpy(_buf, __s, __len); \
|
||||
else *_buf = '\0'; \
|
||||
_buf += __len; \
|
||||
}
|
||||
|
||||
static Eina_Stringshare *_src_filename = NULL;
|
||||
static Exactness_Unit *_src_unit = NULL;
|
||||
static int _verbose = 0;
|
||||
|
||||
static Eina_Debug_Session *_session = NULL;
|
||||
static int _cid = -1, _pid = -1;
|
||||
static Eina_List *_cur_event_list = NULL;
|
||||
static unsigned int _last_event_time = 0;
|
||||
|
||||
static int _all_apps_get_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _mouse_in_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _mouse_out_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _mouse_wheel_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _multi_down_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _multi_up_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _multi_move_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _key_down_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _key_up_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _take_shot_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
static int _finish_op = EINA_DEBUG_OPCODE_INVALID;
|
||||
|
||||
static Eina_Bool _all_apps_get_cb(Eina_Debug_Session *, int , void *, int);
|
||||
|
||||
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
|
||||
{"Daemon/Client/register_observer", &_all_apps_get_op, NULL},
|
||||
{"Daemon/Client/added", NULL, &_all_apps_get_cb},
|
||||
{"Exactness/Actions/Mouse In", &_mouse_in_op, NULL},
|
||||
{"Exactness/Actions/Mouse Out", &_mouse_out_op, NULL},
|
||||
{"Exactness/Actions/Mouse Wheel", &_mouse_wheel_op, NULL},
|
||||
{"Exactness/Actions/Multi Down", &_multi_down_op, NULL},
|
||||
{"Exactness/Actions/Multi Up", &_multi_up_op, NULL},
|
||||
{"Exactness/Actions/Multi Move", &_multi_move_op, NULL},
|
||||
{"Exactness/Actions/Key Down", &_key_down_op, NULL},
|
||||
{"Exactness/Actions/Key Up", &_key_up_op, NULL},
|
||||
{"Exactness/Actions/Take Shot", &_take_shot_op, NULL},
|
||||
{"Exactness/Actions/Finish", &_finish_op, NULL},
|
||||
{NULL, NULL, NULL}
|
||||
);
|
||||
|
||||
static void
|
||||
_printf(int verbose, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (!_verbose || verbose > _verbose) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EXACTNESS_ACTION_MOUSE_IN:
|
||||
{
|
||||
_printf(1, "Mouse in\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_in n_evas=<%d>\n", __func__, n_evas);
|
||||
eina_debug_session_send(_session, _cid, _mouse_in_op, &n_evas, sizeof(int));
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MOUSE_OUT:
|
||||
{
|
||||
_printf(1, "Mouse out\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_out n_evas=<%d>\n", __func__, n_evas);
|
||||
eina_debug_session_send(_session, _cid, _mouse_out_op, &n_evas, sizeof(int));
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MOUSE_WHEEL:
|
||||
{
|
||||
Exactness_Action_Mouse_Wheel *t = data;
|
||||
int len = 3*sizeof(int);
|
||||
char *buf = malloc(len), *tmp = buf;
|
||||
_printf(1, "Mouse wheel\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_wheel n_evas=<%d>\n", __func__, n_evas);
|
||||
STORE_INT(tmp, n_evas);
|
||||
STORE_INT(tmp, t->direction);
|
||||
STORE_INT(tmp, t->z);
|
||||
eina_debug_session_send(_session, _cid, _mouse_wheel_op, buf, len);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MULTI_DOWN:
|
||||
case EXACTNESS_ACTION_MULTI_UP:
|
||||
{
|
||||
Exactness_Action_Multi_Event *t = data;
|
||||
int len = 5*sizeof(int)+7*sizeof(double)+sizeof(int);
|
||||
char *buf = malloc(len), *tmp = buf;
|
||||
_printf(2, "%s %s n_evas=<%d>\n", __func__,
|
||||
type == EXACTNESS_ACTION_MULTI_DOWN ? "evas_event_feed_multi_down" :
|
||||
"evas_event_feed_multi_up", n_evas);
|
||||
STORE_INT(tmp, n_evas);
|
||||
STORE_INT(tmp, t->d);
|
||||
STORE_INT(tmp, t->b);
|
||||
STORE_INT(tmp, t->x);
|
||||
STORE_INT(tmp, t->y);
|
||||
STORE_DOUBLE(tmp, t->rad);
|
||||
STORE_DOUBLE(tmp, t->radx);
|
||||
STORE_DOUBLE(tmp, t->rady);
|
||||
STORE_DOUBLE(tmp, t->pres);
|
||||
STORE_DOUBLE(tmp, t->ang);
|
||||
STORE_DOUBLE(tmp, t->fx);
|
||||
STORE_DOUBLE(tmp, t->fy);
|
||||
STORE_INT(tmp, t->flags);
|
||||
eina_debug_session_send(_session, _cid,
|
||||
type == EXACTNESS_ACTION_MULTI_DOWN ? _multi_down_op : _multi_up_op,
|
||||
buf, len);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MULTI_MOVE:
|
||||
{
|
||||
Exactness_Action_Multi_Move *t = data;
|
||||
int len = 4*sizeof(int)+7*sizeof(double);
|
||||
char *buf = malloc(len), *tmp = buf;
|
||||
_printf(2, "%s evas_event_feed_multi_move n_evas=<%d>\n", __func__, n_evas);
|
||||
STORE_INT(tmp, n_evas);
|
||||
STORE_INT(tmp, t->d);
|
||||
STORE_INT(tmp, t->x);
|
||||
STORE_INT(tmp, t->y);
|
||||
STORE_DOUBLE(tmp, t->rad);
|
||||
STORE_DOUBLE(tmp, t->radx);
|
||||
STORE_DOUBLE(tmp, t->rady);
|
||||
STORE_DOUBLE(tmp, t->pres);
|
||||
STORE_DOUBLE(tmp, t->ang);
|
||||
STORE_DOUBLE(tmp, t->fx);
|
||||
STORE_DOUBLE(tmp, t->fy);
|
||||
eina_debug_session_send(_session, _cid, _multi_move_op, buf, len);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_KEY_DOWN:
|
||||
case EXACTNESS_ACTION_KEY_UP:
|
||||
{
|
||||
Exactness_Action_Key_Down_Up *t = data;
|
||||
int len = 2*sizeof(int) + 4;
|
||||
len += t->keyname ? strlen(t->keyname) : 0;
|
||||
len += t->key ? strlen(t->key) : 0;
|
||||
len += t->string ? strlen(t->string) : 0;
|
||||
len += t->compose ? strlen(t->compose) : 0;
|
||||
char *buf = malloc(len), *tmp = buf;
|
||||
_printf(2, "%s %s n_evas=<%d>\n", __func__,
|
||||
type == EXACTNESS_ACTION_KEY_DOWN ? "evas_event_feed_key_down " :
|
||||
"evas_event_feed_key_up", n_evas);
|
||||
STORE_INT(tmp, n_evas);
|
||||
STORE_STRING(tmp, t->keyname);
|
||||
STORE_STRING(tmp, t->key);
|
||||
STORE_STRING(tmp, t->string);
|
||||
STORE_STRING(tmp, t->compose);
|
||||
STORE_INT(tmp, t->keycode);
|
||||
eina_debug_session_send(_session, _cid,
|
||||
type == EXACTNESS_ACTION_KEY_DOWN ? _key_down_op : _key_up_op,
|
||||
buf, len);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_TAKE_SHOT:
|
||||
{
|
||||
_printf(2, "%s take shot n_evas=<%d>\n", __func__, n_evas);
|
||||
eina_debug_session_send(_session, _cid, _take_shot_op, &n_evas, sizeof(int));
|
||||
break;
|
||||
}
|
||||
default: /* All non-input events are not handeled */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_feed_event_timer_cb(void *data EINA_UNUSED)
|
||||
{
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
_feed_event(act->type, act->n_evas, act->data);
|
||||
time_t evt_time = act->timestamp;
|
||||
|
||||
_cur_event_list = eina_list_next(_cur_event_list);
|
||||
|
||||
if (!_cur_event_list)
|
||||
{ /* Finished reading all events */
|
||||
eina_debug_session_send(_session, _cid, _finish_op, NULL, 0);
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
else
|
||||
{
|
||||
double timer_time;
|
||||
Exactness_Action *cur_act = eina_list_data_get(_cur_event_list);
|
||||
unsigned int current_event_time = cur_act->timestamp;
|
||||
_last_event_time = evt_time;
|
||||
|
||||
if (current_event_time < _last_event_time) /* Could happen with refeed event */
|
||||
current_event_time = _last_event_time;
|
||||
|
||||
_printf(2, " %s _last_event_time=<%u> current_event_time=<%u>\n", __func__, _last_event_time, current_event_time);
|
||||
timer_time = (current_event_time - _last_event_time) / 1000.0;
|
||||
|
||||
if (!_last_event_time) timer_time = 0.0;
|
||||
|
||||
_printf(2, " %s timer_time=<%f>\n", __func__, timer_time);
|
||||
ecore_timer_add(timer_time, _feed_event_timer_cb, NULL);
|
||||
}
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_src_open()
|
||||
{
|
||||
double diff_time = 0; /* Time to wait before feeding the first event */
|
||||
|
||||
_printf(2, "<%s> Source file is <%s>\n", __func__, _src_filename);
|
||||
if (!strcmp(_src_filename + strlen(_src_filename) - 4,".exu"))
|
||||
{
|
||||
_src_unit = exactness_unit_file_read(_src_filename);
|
||||
}
|
||||
else if (!strcmp(_src_filename + strlen(_src_filename) - 4,".rec"))
|
||||
{
|
||||
_src_unit = legacy_rec_file_read(_src_filename);
|
||||
}
|
||||
if (!_src_unit) return EINA_FALSE;
|
||||
_cur_event_list = _src_unit->actions;
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
|
||||
/* Calculate the time to wait before feeding the first event */
|
||||
unsigned int current_event_time = act->timestamp;
|
||||
|
||||
_printf(2, "%s current_event_time=<%u>\n", __func__, current_event_time);
|
||||
|
||||
if (current_event_time)
|
||||
{
|
||||
_printf(2, " Waiting <%f>\n", diff_time);
|
||||
ecore_timer_add(current_event_time / 1000.0, _feed_event_timer_cb, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_feed_event_timer_cb(NULL);
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_all_apps_get_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
int chosen_cid = -1;
|
||||
if (_cid != -1) return;
|
||||
while (size > 0)
|
||||
{
|
||||
int cid, pid, len;
|
||||
cid = EXTRACT_INT(buf);
|
||||
pid = EXTRACT_INT(buf);
|
||||
if (_pid != -1)
|
||||
{
|
||||
if (_pid == pid)
|
||||
{
|
||||
_cid = cid;
|
||||
_src_open();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp(buf, "exactness_play"))
|
||||
{
|
||||
if (chosen_cid != -1)
|
||||
{
|
||||
fprintf(stderr, "Need to specify a PID - too much choice\n");
|
||||
return;
|
||||
}
|
||||
chosen_cid = cid;
|
||||
}
|
||||
}
|
||||
len = strlen(buf) + 1;
|
||||
buf += len;
|
||||
size -= (2 * sizeof(int) + len);
|
||||
}
|
||||
if (chosen_cid != -1)
|
||||
{
|
||||
_cid = chosen_cid;
|
||||
_src_open();
|
||||
}
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_all_apps_get_cb)
|
||||
|
||||
static void
|
||||
_ops_ready_cb(void *data EINA_UNUSED, Eina_Bool status)
|
||||
{
|
||||
static Eina_Bool on = EINA_FALSE;
|
||||
if (status)
|
||||
{
|
||||
if (!on)
|
||||
{
|
||||
eina_debug_session_send(_session, 0, _all_apps_get_op, NULL, 0);
|
||||
}
|
||||
on = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static const Ecore_Getopt optdesc = {
|
||||
"exactness_inject",
|
||||
"%prog [options] <-v|-p|-t|-h> command",
|
||||
PACKAGE_VERSION,
|
||||
"(C) 2018 Enlightenment",
|
||||
"BSD",
|
||||
"A scenario events injector for EFL based applications.",
|
||||
1,
|
||||
{
|
||||
ECORE_GETOPT_STORE_STR('t', "test", "Test to run on the given application"),
|
||||
ECORE_GETOPT_STORE_INT('p', "pid", "PID of the application to connect to"),
|
||||
ECORE_GETOPT_STORE_INT('r', "remote-port", "Port to connect remotely to the daemon. Local connection if not specified"),
|
||||
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
|
||||
|
||||
ECORE_GETOPT_LICENSE('L', "license"),
|
||||
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
|
||||
ECORE_GETOPT_VERSION('V', "version"),
|
||||
ECORE_GETOPT_HELP('h', "help"),
|
||||
ECORE_GETOPT_SENTINEL
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt_args = 0, real__, port = -1;
|
||||
char *src = NULL;
|
||||
Eina_Value *ret__;
|
||||
Eina_Bool want_quit = EINA_FALSE;
|
||||
|
||||
Ecore_Getopt_Value values[] = {
|
||||
ECORE_GETOPT_VALUE_STR(src),
|
||||
ECORE_GETOPT_VALUE_INT(_pid),
|
||||
ECORE_GETOPT_VALUE_INT(port),
|
||||
ECORE_GETOPT_VALUE_INT(_verbose),
|
||||
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
ECORE_GETOPT_VALUE_NONE
|
||||
};
|
||||
|
||||
eina_init();
|
||||
eet_init();
|
||||
ecore_init();
|
||||
|
||||
opt_args = ecore_getopt_parse(&optdesc, values, argc, argv);
|
||||
if (opt_args < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed parsing arguments.\n");
|
||||
goto end;
|
||||
}
|
||||
if (want_quit) goto end;
|
||||
|
||||
if (!src)
|
||||
{
|
||||
fprintf(stderr, "no test file specified\n");
|
||||
goto end;
|
||||
}
|
||||
_src_filename = eina_stringshare_add(src);
|
||||
|
||||
if (port == -1)
|
||||
_session = eina_debug_local_connect(EINA_TRUE);
|
||||
else
|
||||
_session = eina_debug_remote_connect(port);
|
||||
eina_debug_opcodes_register(_session, _debug_ops(), _ops_ready_cb, NULL);
|
||||
|
||||
elm_init(argc, argv);
|
||||
ret__ = efl_loop_begin(efl_main_loop_get());
|
||||
real__ = efl_loop_exit_code_process(ret__);
|
||||
elm_shutdown();
|
||||
end:
|
||||
eet_shutdown();
|
||||
eina_shutdown();
|
||||
return real__;
|
||||
}
|
||||
|
344
src/bin/player.c
344
src/bin/player.c
|
@ -27,12 +27,82 @@
|
|||
#define MAX_PATH 1024
|
||||
#define IMAGE_FILENAME_EXT ".png"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Eina_Debug_Session *session;
|
||||
int srcid;
|
||||
void *buffer;
|
||||
unsigned int size;
|
||||
} _Main_Loop_Info;
|
||||
|
||||
#define WRAPPER_TO_XFER_MAIN_LOOP(foo) \
|
||||
static void \
|
||||
_intern_main_loop ## foo(void *data) \
|
||||
{ \
|
||||
_Main_Loop_Info *info = data; \
|
||||
_main_loop ## foo(info->session, info->srcid, info->buffer, info->size); \
|
||||
free(info->buffer); \
|
||||
free(info); \
|
||||
} \
|
||||
static Eina_Bool \
|
||||
foo(Eina_Debug_Session *session, int srcid, void *buffer, int size) \
|
||||
{ \
|
||||
_Main_Loop_Info *info = calloc(1, sizeof(*info)); \
|
||||
info->session = session; \
|
||||
info->srcid = srcid; \
|
||||
info->size = size; \
|
||||
if (info->size) \
|
||||
{ \
|
||||
info->buffer = malloc(info->size); \
|
||||
memcpy(info->buffer, buffer, info->size); \
|
||||
} \
|
||||
ecore_main_loop_thread_safe_call_async(_intern_main_loop ## foo, info); \
|
||||
return EINA_TRUE; \
|
||||
}
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define SWAP_64(x) x
|
||||
#define SWAP_32(x) x
|
||||
#define SWAP_16(x) x
|
||||
#define SWAP_DBL(x) x
|
||||
#else
|
||||
#define SWAP_64(x) eina_swap64(x)
|
||||
#define SWAP_32(x) eina_swap32(x)
|
||||
#define SWAP_16(x) eina_swap16(x)
|
||||
#define SWAP_DBL(x) SWAP_64(x)
|
||||
#endif
|
||||
|
||||
#define EXTRACT_INT(_buf) \
|
||||
({ \
|
||||
int __i; \
|
||||
memcpy(&__i, _buf, sizeof(int)); \
|
||||
_buf += sizeof(int); \
|
||||
SWAP_32(__i); \
|
||||
})
|
||||
|
||||
#define EXTRACT_DOUBLE(_buf) \
|
||||
({ \
|
||||
double __d; \
|
||||
memcpy(&__d, _buf, sizeof(double)); \
|
||||
_buf += sizeof(double); \
|
||||
SWAP_DBL(__d); \
|
||||
})
|
||||
|
||||
#define EXTRACT_STRING(_buf) \
|
||||
({ \
|
||||
char *__s = _buf ? strdup(_buf) : NULL; \
|
||||
int __len = (__s ? strlen(__s) : 0) + 1; \
|
||||
_buf += __len; \
|
||||
__s; \
|
||||
})
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FTYPE_UNKNOWN,
|
||||
FTYPE_DIR,
|
||||
FTYPE_REC = FTYPE_DIR,
|
||||
FTYPE_EXU
|
||||
FTYPE_EXU,
|
||||
FTYPE_REMOTE
|
||||
} File_Type;
|
||||
|
||||
static File_Type _dest_type = FTYPE_UNKNOWN;
|
||||
|
@ -170,17 +240,15 @@ _shot_do(Evas *e)
|
|||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_feed_event(void *data EINA_UNUSED)
|
||||
static void
|
||||
_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data)
|
||||
{
|
||||
static Evas_Object *rect = NULL;
|
||||
static unsigned int rect_evas;
|
||||
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
Eo *e = eina_list_nth(_evas_list, act->n_evas);
|
||||
time_t evt_time = act->timestamp;
|
||||
Eo *e = eina_list_nth(_evas_list, n_evas);
|
||||
|
||||
if (rect && rect_evas != act->n_evas)
|
||||
if (rect && rect_evas != n_evas)
|
||||
{
|
||||
efl_del(rect);
|
||||
rect = NULL;
|
||||
|
@ -193,38 +261,38 @@ _feed_event(void *data EINA_UNUSED)
|
|||
evas_object_resize(rect, 15, 15);
|
||||
evas_object_layer_set(rect, 100);
|
||||
evas_object_show(rect);
|
||||
rect_evas = act->n_evas;
|
||||
rect_evas = n_evas;
|
||||
}
|
||||
|
||||
switch (act->type)
|
||||
switch (type)
|
||||
{
|
||||
case EXACTNESS_ACTION_MOUSE_IN:
|
||||
{
|
||||
_printf(1, "Mouse in\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_in timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
_printf(2, "%s evas_event_feed_mouse_in n_evas=<%d>\n", __func__, n_evas);
|
||||
if (e) evas_event_feed_mouse_in(e, time(NULL), NULL);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MOUSE_OUT:
|
||||
{
|
||||
_printf(1, "Mouse out\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_out timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp,act->n_evas);
|
||||
_printf(2, "%s evas_event_feed_mouse_out n_evas=<%d>\n", __func__, n_evas);
|
||||
if (e) evas_event_feed_mouse_out(e, time(NULL), NULL);
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MOUSE_WHEEL:
|
||||
{
|
||||
Exactness_Action_Mouse_Wheel *t = act->data;
|
||||
Exactness_Action_Mouse_Wheel *t = data;
|
||||
_printf(1, "Mouse wheel\n");
|
||||
_printf(2, "%s evas_event_feed_mouse_wheel timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
_printf(2, "%s evas_event_feed_mouse_wheel n_evas=<%d>\n", __func__, n_evas);
|
||||
if (e) evas_event_feed_mouse_wheel(e, t->direction, t->z, time(NULL), NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
case EXACTNESS_ACTION_MULTI_DOWN:
|
||||
{
|
||||
Exactness_Action_Multi_Event *t = act->data;
|
||||
_printf(2, "%s evas_event_feed_multi_down timestamp=<%u>, n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
Exactness_Action_Multi_Event *t = data;
|
||||
_printf(2, "%s evas_event_feed_multi_down n_evas=<%d>\n", __func__, n_evas);
|
||||
if (!t->d)
|
||||
{
|
||||
if (e) evas_event_feed_mouse_down(e, t->b, t->flags, time(NULL), NULL);
|
||||
|
@ -242,8 +310,8 @@ _feed_event(void *data EINA_UNUSED)
|
|||
}
|
||||
case EXACTNESS_ACTION_MULTI_UP:
|
||||
{
|
||||
Exactness_Action_Multi_Event *t = act->data;
|
||||
_printf(2, "%s evas_event_feed_multi_up timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp,act->n_evas);
|
||||
Exactness_Action_Multi_Event *t = data;
|
||||
_printf(2, "%s evas_event_feed_multi_up n_evas=<%d>\n", __func__, n_evas);
|
||||
if (!t->d)
|
||||
{
|
||||
if (e) evas_event_feed_mouse_up(e, t->b, t->flags, time(NULL), NULL);
|
||||
|
@ -261,8 +329,8 @@ _feed_event(void *data EINA_UNUSED)
|
|||
}
|
||||
case EXACTNESS_ACTION_MULTI_MOVE:
|
||||
{
|
||||
Exactness_Action_Multi_Move *t = act->data;
|
||||
_printf(2, "%s evas_event_feed_multi_move timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
Exactness_Action_Multi_Move *t = data;
|
||||
_printf(2, "%s evas_event_feed_multi_move n_evas=<%d>\n", __func__, n_evas);
|
||||
if (!t->d)
|
||||
{
|
||||
if (e) evas_event_feed_mouse_move(e, t->x, t->y, time(NULL), NULL);
|
||||
|
@ -284,8 +352,8 @@ _feed_event(void *data EINA_UNUSED)
|
|||
}
|
||||
case EXACTNESS_ACTION_KEY_DOWN:
|
||||
{
|
||||
Exactness_Action_Key_Down_Up *t = act->data;
|
||||
_printf(2, "%s evas_event_feed_key_down timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
Exactness_Action_Key_Down_Up *t = data;
|
||||
_printf(2, "%s evas_event_feed_key_down n_evas=<%d>\n", __func__, n_evas);
|
||||
if (e)
|
||||
evas_event_feed_key_down_with_keycode(e,
|
||||
t->keyname, t->key, t->string,
|
||||
|
@ -294,8 +362,8 @@ _feed_event(void *data EINA_UNUSED)
|
|||
}
|
||||
case EXACTNESS_ACTION_KEY_UP:
|
||||
{
|
||||
Exactness_Action_Key_Down_Up *t = act->data;
|
||||
_printf(2, "%s evas_event_feed_key_up timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
Exactness_Action_Key_Down_Up *t = data;
|
||||
_printf(2, "%s evas_event_feed_key_up n_evas=<%d>\n", __func__, n_evas);
|
||||
if (e) evas_event_feed_key_up_with_keycode(e,
|
||||
t->keyname, t->key, t->string,
|
||||
t->compose, time(NULL), NULL, t->keycode);
|
||||
|
@ -304,7 +372,7 @@ _feed_event(void *data EINA_UNUSED)
|
|||
}
|
||||
case EXACTNESS_ACTION_TAKE_SHOT:
|
||||
{
|
||||
_printf(2, "%s take shot timestamp=<%u> n_evas=<%d>\n", __func__, act->timestamp, act->n_evas);
|
||||
_printf(2, "%s take shot n_evas=<%d>\n", __func__, n_evas);
|
||||
if (rect) evas_object_color_set(rect, 0, 0, 255, 255);
|
||||
_cur_shot_id++;
|
||||
if (_dest_type != FTYPE_UNKNOWN && e) _shot_do(e);
|
||||
|
@ -313,6 +381,14 @@ _feed_event(void *data EINA_UNUSED)
|
|||
default: /* All non-input events are not handeled */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_feed_event_timer_cb(void *data EINA_UNUSED)
|
||||
{
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
_feed_event(act->type, act->n_evas, act->data);
|
||||
time_t evt_time = act->timestamp;
|
||||
|
||||
_cur_event_list = eina_list_next(_cur_event_list);
|
||||
|
||||
|
@ -336,41 +412,203 @@ _feed_event(void *data EINA_UNUSED)
|
|||
if (!_last_event_time) timer_time = 0.0;
|
||||
|
||||
_printf(2, " %s timer_time=<%f>\n", __func__, timer_time);
|
||||
ecore_timer_add(timer_time, _feed_event, NULL);
|
||||
ecore_timer_add(timer_time, _feed_event_timer_cb, NULL);
|
||||
}
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_mouse_in_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MOUSE_IN, n_evas, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_mouse_out_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MOUSE_OUT, n_evas, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_mouse_wheel_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Mouse_Wheel t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.direction = EXTRACT_INT(buf);
|
||||
t.z = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MOUSE_WHEEL, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_multi_down_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Multi_Event t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.d = EXTRACT_INT(buf);
|
||||
t.b = EXTRACT_INT(buf);
|
||||
t.x = EXTRACT_INT(buf);
|
||||
t.y = EXTRACT_INT(buf);
|
||||
t.rad = EXTRACT_DOUBLE(buf);
|
||||
t.radx = EXTRACT_DOUBLE(buf);
|
||||
t.rady = EXTRACT_DOUBLE(buf);
|
||||
t.pres = EXTRACT_DOUBLE(buf);
|
||||
t.ang = EXTRACT_DOUBLE(buf);
|
||||
t.fx = EXTRACT_DOUBLE(buf);
|
||||
t.fy = EXTRACT_DOUBLE(buf);
|
||||
t.flags = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MULTI_DOWN, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_multi_up_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Multi_Event t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.d = EXTRACT_INT(buf);
|
||||
t.b = EXTRACT_INT(buf);
|
||||
t.x = EXTRACT_INT(buf);
|
||||
t.y = EXTRACT_INT(buf);
|
||||
t.rad = EXTRACT_DOUBLE(buf);
|
||||
t.radx = EXTRACT_DOUBLE(buf);
|
||||
t.rady = EXTRACT_DOUBLE(buf);
|
||||
t.pres = EXTRACT_DOUBLE(buf);
|
||||
t.ang = EXTRACT_DOUBLE(buf);
|
||||
t.fx = EXTRACT_DOUBLE(buf);
|
||||
t.fy = EXTRACT_DOUBLE(buf);
|
||||
t.flags = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MULTI_UP, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_multi_move_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Multi_Move t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.d = EXTRACT_INT(buf);
|
||||
t.x = EXTRACT_INT(buf);
|
||||
t.y = EXTRACT_INT(buf);
|
||||
t.rad = EXTRACT_DOUBLE(buf);
|
||||
t.radx = EXTRACT_DOUBLE(buf);
|
||||
t.rady = EXTRACT_DOUBLE(buf);
|
||||
t.pres = EXTRACT_DOUBLE(buf);
|
||||
t.ang = EXTRACT_DOUBLE(buf);
|
||||
t.fx = EXTRACT_DOUBLE(buf);
|
||||
t.fy = EXTRACT_DOUBLE(buf);
|
||||
_feed_event(EXACTNESS_ACTION_MULTI_MOVE, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_key_down_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Key_Down_Up t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.keyname = EXTRACT_STRING(buf);
|
||||
t.key = EXTRACT_STRING(buf);
|
||||
t.string = EXTRACT_STRING(buf);
|
||||
t.compose = EXTRACT_STRING(buf);
|
||||
t.keycode = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_KEY_DOWN, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_key_up_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
Exactness_Action_Key_Down_Up t;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
t.keyname = EXTRACT_STRING(buf);
|
||||
t.key = EXTRACT_STRING(buf);
|
||||
t.string = EXTRACT_STRING(buf);
|
||||
t.compose = EXTRACT_STRING(buf);
|
||||
t.keycode = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_KEY_UP, n_evas, &t);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_take_shot_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
|
||||
{
|
||||
char *buf = buffer;
|
||||
int n_evas = EXTRACT_INT(buf);
|
||||
_feed_event(EXACTNESS_ACTION_TAKE_SHOT, n_evas, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_main_loop_finish_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_mouse_in_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_mouse_out_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_mouse_wheel_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_multi_down_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_multi_up_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_multi_move_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_key_down_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_key_up_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_take_shot_cb)
|
||||
WRAPPER_TO_XFER_MAIN_LOOP(_finish_cb)
|
||||
|
||||
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
|
||||
{"Exactness/Actions/Mouse In", NULL, &_mouse_in_cb},
|
||||
{"Exactness/Actions/Mouse Out", NULL, &_mouse_out_cb},
|
||||
{"Exactness/Actions/Mouse Wheel", NULL, &_mouse_wheel_cb},
|
||||
{"Exactness/Actions/Multi Down", NULL, &_multi_down_cb},
|
||||
{"Exactness/Actions/Multi Up", NULL, &_multi_up_cb},
|
||||
{"Exactness/Actions/Multi Move", NULL, &_multi_move_cb},
|
||||
{"Exactness/Actions/Key Down", NULL, &_key_down_cb},
|
||||
{"Exactness/Actions/Key Up", NULL, &_key_up_cb},
|
||||
{"Exactness/Actions/Take Shot", NULL, &_take_shot_cb},
|
||||
{"Exactness/Actions/Finish", NULL, &_finish_cb},
|
||||
{NULL, NULL, NULL}
|
||||
);
|
||||
|
||||
static Eina_Bool
|
||||
_src_open()
|
||||
{
|
||||
double diff_time = 0; /* Time to wait before feeding the first event */
|
||||
_printf(2, "<%s> Source file is <%s>\n", __func__, _src_filename);
|
||||
if (_src_type == FTYPE_EXU)
|
||||
if (_src_type != FTYPE_REMOTE)
|
||||
{
|
||||
_src_unit = exactness_unit_file_read(_src_filename);
|
||||
}
|
||||
else if (_src_type == FTYPE_REC)
|
||||
{
|
||||
_src_unit = legacy_rec_file_read(_src_filename);
|
||||
}
|
||||
if (!_src_unit) return EINA_FALSE;
|
||||
_cur_event_list = _src_unit->actions;
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
double diff_time = 0; /* Time to wait before feeding the first event */
|
||||
_printf(2, "<%s> Source file is <%s>\n", __func__, _src_filename);
|
||||
if (_src_type == FTYPE_EXU)
|
||||
{
|
||||
_src_unit = exactness_unit_file_read(_src_filename);
|
||||
}
|
||||
else if (_src_type == FTYPE_REC)
|
||||
{
|
||||
_src_unit = legacy_rec_file_read(_src_filename);
|
||||
}
|
||||
if (!_src_unit) return EINA_FALSE;
|
||||
_cur_event_list = _src_unit->actions;
|
||||
Exactness_Action *act = eina_list_data_get(_cur_event_list);
|
||||
|
||||
/* Calculate the time to wait before feeding the first event */
|
||||
unsigned int current_event_time = act->timestamp;
|
||||
/* Calculate the time to wait before feeding the first event */
|
||||
unsigned int current_event_time = act->timestamp;
|
||||
|
||||
_printf(2, "%s current_event_time=<%u>\n", __func__, current_event_time);
|
||||
_printf(2, "%s current_event_time=<%u>\n", __func__, current_event_time);
|
||||
|
||||
if (current_event_time)
|
||||
{
|
||||
_printf(2, " Waiting <%f>\n", diff_time);
|
||||
ecore_timer_add(current_event_time / 1000.0, _feed_event, NULL);
|
||||
if (current_event_time)
|
||||
{
|
||||
_printf(2, " Waiting <%f>\n", diff_time);
|
||||
ecore_timer_add(current_event_time / 1000.0, _feed_event_timer_cb, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_feed_event_timer_cb(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_feed_event(NULL);
|
||||
eina_debug_opcodes_register(NULL, _debug_ops(), NULL, NULL);
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -516,6 +754,7 @@ static const Ecore_Getopt optdesc = {
|
|||
ECORE_GETOPT_STORE_STR('t', "test", "Test to run on the given application"),
|
||||
ECORE_GETOPT_STORE_TRUE('s', "show-on-screen", "Show on screen."),
|
||||
ECORE_GETOPT_STORE_TRUE(0, "scan-objects", "Extract information of all the objects at every shot."),
|
||||
ECORE_GETOPT_STORE_TRUE(0, "external-injection", "Expect events injection via Eina debug channel."),
|
||||
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
|
||||
|
||||
ECORE_GETOPT_LICENSE('L', "license"),
|
||||
|
@ -531,13 +770,14 @@ int main(int argc, char **argv)
|
|||
int pret = 1, opt_args = 0;
|
||||
char *src = NULL, *dest = NULL, *eq;
|
||||
Eina_Bool show_on_screen = EINA_FALSE;
|
||||
Eina_Bool want_quit = EINA_FALSE;
|
||||
Eina_Bool want_quit = EINA_FALSE, external_injection = EINA_FALSE;
|
||||
|
||||
Ecore_Getopt_Value values[] = {
|
||||
ECORE_GETOPT_VALUE_STR(dest),
|
||||
ECORE_GETOPT_VALUE_STR(src),
|
||||
ECORE_GETOPT_VALUE_BOOL(show_on_screen),
|
||||
ECORE_GETOPT_VALUE_BOOL(_scan_objects),
|
||||
ECORE_GETOPT_VALUE_BOOL(external_injection),
|
||||
ECORE_GETOPT_VALUE_INT(_verbose),
|
||||
|
||||
ECORE_GETOPT_VALUE_BOOL(want_quit),
|
||||
|
@ -598,12 +838,18 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!src)
|
||||
if (!src && !external_injection)
|
||||
{
|
||||
fprintf(stderr, "no test file specified\n");
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
if (src && external_injection)
|
||||
{
|
||||
fprintf(stderr, "Cannot inject events from a source file and from outside simultaneously\n");
|
||||
goto end;
|
||||
}
|
||||
if (external_injection) _src_type = FTYPE_REMOTE;
|
||||
if (src)
|
||||
{
|
||||
_src_filename = eina_stringshare_add(src);
|
||||
if (!strcmp(_src_filename + strlen(_src_filename) - 4,".exu"))
|
||||
|
@ -669,7 +915,7 @@ int main(int argc, char **argv)
|
|||
|
||||
if (_dest && _dest_unit)
|
||||
{
|
||||
_dest_unit->actions = _src_unit->actions;
|
||||
if (_src_unit) _dest_unit->actions = _src_unit->actions;
|
||||
exactness_unit_file_write(_dest_unit, _dest);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue