Compare commits

..

5 Commits

Author SHA1 Message Date
Tom Hacohen aeb6fcb28c Also fail if exit signal is non-zero.
We should fail if we segfault, or exit because of another error that
ecore_exe reports a zero exit code for.
2013-06-10 16:57:07 +01:00
Tom Hacohen bfffc6e17d unsegfault 2013-06-10 16:47:39 +01:00
Daniel Willmann 5aa5fbec06 ecore_init/shutdown: Proper refcounting for wrappers
Signed-off-by: Daniel Willmann <d.willmann@samsung.com>
2013-06-10 16:41:30 +01:00
Tom Hacohen 9b0fb72d66 More output + possible fix 2013-06-10 16:34:54 +01:00
Tom Hacohen 61c3e288c6 more prints 2013-06-10 16:20:29 +01:00
35 changed files with 2707 additions and 7423 deletions

View File

@ -1,4 +0,0 @@
{
"project_id" : "exactness",
"conduit_uri" : "https://phab.enlightenment.org/"
}

4
.gitignore vendored
View File

@ -1,4 +1,5 @@
src/scripts/exactness
src/bin/exactness_raw
*.o
*.lo
*.la
@ -11,20 +12,17 @@ Makefile.in
.*.sw[po]
*.gcov
*.gcno
*.exe
/README
/aclocal.m4
/autom4te.cache/
/config.cache
/config.guess
config.h.in~
/config.h
/config.h.in
/config.log
/config.status
/config.sub
/configure
/compile
/depcomp
/doc/evas.dox
/evas.spec

View File

@ -3,7 +3,6 @@ MAINTAINERCLEANFILES = \
Makefile.in \
aclocal.m4 \
config.guess \
config.h.in~ \
config.h.in \
config.sub \
configure \
@ -16,7 +15,4 @@ EXTRA_DIST = README AUTHORS COPYING
SUBDIRS = src
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = exactness.pc
ACLOCAL_AMFLAGS = -I m4

117
README
View File

@ -1,119 +1,4 @@
Exactness is a pixel perfect regression testing tool for Elementary based applications.
Exactness works by playing back a recording of an interaction with the
application, saving images from that playback, and comparing the images to the
set of "known to be correct" images. Returning a non-zero return value when it
detects images mismatches and creates "error.html", a file that includes the
list of tests failed, including the base images, the new images, and a visual
"diff" of the images. Exactness also fails in case the tests themselves exit
with a non-zero return value, e.g segfault.
= Modes of operation =
Exactness has four modes of operation, three of which are essential for normal
operation, and the fourth is helpful in some cases, and in general, just pretty.
== List of Modes ==
# record (-r, --record): record a test macro.
# init (-i, --init): run the test macro and take images of the state.
# play (-p, --play): run the test macro, take images of the state, and compare against the base images (took with init).
# simulation (-s, --simulation): run the test macro, showing the process on screen.
= The List file =
The list file contains a list of tests to actually run.
The file format is:
<test name> <test command>
<test name> has to be one word (no spaces), there are no restrictions on the command. The command is executed using "system", so you can set environment variables and generally do whatever you'd like.
Empty lines and lines starting with # are ignored.
Example line:
box ./elm_edje_player tests/box.edj
= Using exactness =
For the rest of this section we'll assume the name of the list file is
"tests.txt".
== Recording ==
The first thing to do when running exactness on a new test is generating the
recording file, this is done but running with "-r". New recordings overwrite
old existing recordings so it's always a good idea to backup recordings you are
happy with.
In order to record for a test list run:
exactness -r tests.txt
Just interact with the application in any way you'd like (it's better to have
short interactions as tests run in real time, so running the tests will be as
slow as your recording).
Press F2 to mark an image taking opportunity (as many times you'd like), this
will cause "init" and "play" mode to take images for comparison. Please refer
to the "Limitations" section below to read more about image taking
opportunities.
Running this will create the "base dir" (see command line options for more info
about how to change it) and populate it with one recording file per test.
== Init ==
After having a recording file for a test you can go on with capturing the base
images. Those images are assumed to be "correct". You should update them when
this assumption is no longer valid (e.g fixed a bug, updated a test).
Run:
exactness -i tests.txt
This will look for recording files in the "base dir", run them, take images of
the application, and put them in "dest-dir/orig".
== Play ==
This is the most common mode of execution. This should be run on a regular
basis, for example in a CI system.
Run:
exactness -p tests.txt
This will look for recording files in the "base dir", run them, take images of the application, put them in "dest-dir/current", and compare them against the
images in "dest-dir/orig". This will fail (and return a non-zero return value)
if any of the tests return a non-zero return value, or if any of the images
in the "current" dir don't match the ones in "orig" dir.
Detecting a failure is the most important role of exactness, so the return
value is very important. Additionally, an error.html file will be created in
the "current" dir, listing the issues in a human-readable form.
== Simulation ==
This mode is a show off and a debug mode. Very useful with the "-v" (verbose)
option that shows the mouse cursor on the canvas and outputs information to
console.
Run:
exactness -s tests.txt
or for verbose mode:
exactness -v -s tests.txt
This does nothing other than run the tests to screen. No images are taken,
and no report is generated.
== Command line options ==
* -b, --base-dir: The location of the recording files.
* -d, --dest-dir: The location of the base dir for the images (orig/current will be appended).
* -w, --wrap: Use a custom command to launch the tests with, e.g valgrind.
* -j, --jobs: Number of jobs to run in parallel. Very useful when running in init and play mode.
* -r, --record: record mode.
* -p, --play: play mode.
* -i, --init: init mode.
* -s, --simulation: simulation mode.
* -v, --verbose: Show cursor location and output extra information to console.
* -h, --help: Help, and information about more boring options.
= Limitations =
* Animations are very time-specific, you can't really take snapshots of
applications that have animations.
* Exactness is very susceptible to theme/scale/etc. changes, so make sure to
replicate the full environment.
* Only works with Elementary applications.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
REST IS POSSIBLY OUTDATED
POSSIBLY OUTDATED
exactness is a software package aimed to automate Elementary testing
after updating elm code.

View File

@ -3,28 +3,22 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT([exactness], [0.1.0], [enlightenment-devel@lists.sourceforge.net])
AC_PREREQ([2.52])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AC_USE_SYSTEM_EXTENSIONS
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
case "$host_os" in
mingw*)
have_win32="yes"
;;
esac
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([1.6 dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_CONFIG_HEADERS([config.h])
AC_ISC_POSIX
AC_PROG_CC
AM_PROG_CC_C_O
AC_C_BIGENDIAN
AC_HEADER_STDC
AC_C_CONST
EFL_ENABLE_BETA_API_SUPPORT
AM_PROG_CC_C_O
PKG_PROG_PKG_CONFIG
LT_INIT([win32-dll])
AC_PROG_LIBTOOL
dnl Checking for __attribute__ support
AC_MSG_CHECKING([for __attribute__])
@ -41,30 +35,14 @@ if test "x${_cv_have___attribute__}" = "xyes" ; then
fi
AC_MSG_RESULT([${_cv_have___attribute__}])
requirements_pc="elementary >= 1.14.0 emile >= 1.14.0 ecore-evas >= 1.14.0 evas >= 1.14.0 ecore-con >= 1.14.0 ecore-file >= 1.14.0 ecore >= 1.14.0 eet >= 1.14.0 eo >= 1.14.0 eina >= 1.14.0"
if test "x${have_win32}" = "xyes" ; then
requirements_pc="${requirements_pc} evil"
fi
PKG_CHECK_MODULES([EFL],
[${requirements_pc}],
[ac_elm_themes_dir=`$PKG_CONFIG --variable=themes elementary`]
)
if test "x$ac_elm_themes_dir" = x ; then
AC_MSG_ERROR([couldn't find Elementary themes path])
fi
AC_CHECK_HEADERS([sys/sysinfo.h])
AC_SUBST([requirements_pc])
AC_SUBST(ELM_THEMES_DIR, $ac_elm_themes_dir)
[
elementary >= 0.7.0
])
AC_OUTPUT([
Makefile
src/Makefile
src/bin/Makefile
src/lib/Makefile
exactness.pc
])

View File

@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Exactness
Description: A Library to read and write Exactness units
Version: @VERSION@
Requires.private: @requirements_pc@
Libs: -L${libdir} -lexactness
Cflags: -I${includedir}/exactness

View File

@ -1,5 +0,0 @@
dnl use: EFL_ENABLE_BETA_API_SUPPORT
AC_DEFUN([EFL_ENABLE_BETA_API_SUPPORT],
[
AC_DEFINE([EFL_BETA_API_SUPPORT], [1], [Enable access to unstable EFL API that are still in beta])
])

7
src/bin/.gitignore vendored
View File

@ -1,7 +0,0 @@
/exactness
/exactness_helper
/exactness_play
/exactness_record
/exactness_inspect
/exactness_inject
/*.edj

View File

@ -1,42 +1,19 @@
MAINTAINERCLEANFILES = Makefile.in
bin_PROGRAMS = exactness exactness_inspect exactness_play exactness_record exactness_inject
bin_PROGRAMS = exactness
sharedir = $(datadir)/exactness
share_DATA = exactness_play.edj
exactness_SOURCES = \
exactness.c \
list_file.c \
exactness_config.c \
scheduler.c \
run_test.c \
md5/md5.c
exactness_SOURCES = exactness.c
exactness_LDADD = \
@EFL_LIBS@
exactness_inspect_SOURCES = inspect.c
exactness_play.edj: player_entry.edc player_fonts.edc
edje_decc $(ELM_THEMES_DIR)/default.edj -output /tmp/theme_default
edje_cc -id /tmp/theme_default -sd /tmp/theme_default $< $@
exactness_play_SOURCES = player.c
exactness_record_SOURCES = recorder.c
exactness_inject_SOURCES = injector.c
exactness_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libexactness.la
exactness_inspect_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libexactness.la
exactness_play_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libexactness.la
exactness_record_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libexactness.la
exactness_inject_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libexactness.la
exactness_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
exactness_inspect_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
exactness_play_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib -DDATA_DIR=\"$(datadir)/exactness\"
exactness_record_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
exactness_inject_CFLAGS = @EFL_CFLAGS@ -I$(top_srcdir)/src/lib
CLEANFILES = $(share_DATA)
exactness_CFLAGS = \
@EFL_CFLAGS@ \
-DPACKAGE_LIBDIR=\"$(libdir)\" \
-DPACKAGE_DATADIR=\"$(datadir)\"

View File

@ -1,426 +1,12 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_File.h>
#include <Ecore_Getopt.h>
#include <Emile.h>
#include "exactness_private.h"
#include "list_file.h"
#include "exactness_config.h"
#include "run_test.h"
#include "scheduler.h"
#define SCHEDULER_CMD_SIZE 1024
#define ORIG_SUBDIR "orig"
#define CURRENT_SUBDIR "current"
#define EXACTNESS_PATH_MAX 1024
#define BUF_SIZE 1024
typedef struct
{
EINA_INLIST;
char *name;
const char *command;
} List_Entry;
typedef enum
{
RUN_SIMULATION,
RUN_PLAY,
RUN_INIT
} Run_Mode;
static unsigned short _running_jobs = 0, _max_jobs = 1;
static Eina_List *_base_dirs = NULL;
static char *_dest_dir;
static char *_wrap_command = NULL, *_fonts_dir = NULL;
static int _verbose = 0;
static Eina_Bool _scan_objs = EINA_FALSE, _disable_screenshots = EINA_FALSE, _stabilize_shots = EINA_FALSE;
static Run_Mode _mode;
static List_Entry *_next_test_to_run = NULL;
static unsigned int _tests_executed = 0;
static Eina_List *_errors;
static Eina_List *_compare_errors;
static Eina_Bool _job_consume();
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 Exactness_Image *
_image_load(const char *filename)
{
int w, h;
Evas_Load_Error err;
Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
Eo *e = ecore_evas_get(ee);
Eo *img = evas_object_image_add(e);
evas_object_image_file_set(img, filename, NULL);
err = evas_object_image_load_error_get(img);
if (err != EVAS_LOAD_ERROR_NONE)
{
fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n",
filename, evas_load_error_str(err));
return NULL;
}
Exactness_Image *ex_img = malloc(sizeof(*ex_img));
int len;
evas_object_image_size_get(img, &w, &h);
ex_img->w = w;
ex_img->h = h;
len = w * h * 4;
ex_img->pixels = malloc(len);
memcpy(ex_img->pixels, evas_object_image_data_get(img, EINA_FALSE), len);
ecore_evas_free(ee);
return ex_img;
}
static void
_image_save(Exactness_Image *ex_img, const char *output)
{
Ecore_Evas *ee;
Eo *e, *img;
ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
e = ecore_evas_get(ee);
img = evas_object_image_add(e);
evas_object_image_size_set(img, ex_img->w, ex_img->h);
evas_object_image_data_set(img, ex_img->pixels);
evas_object_image_save(img, output, NULL, NULL);
ecore_evas_free(ee);
}
static Eina_Bool
_file_compare(const char *orig_dir, const char *ent_name)
{
Eina_Bool result = EINA_FALSE;
Exactness_Image *img1, *img2, *imgO = NULL;
char *filename1 = alloca(strlen(orig_dir) + strlen(ent_name) + 20);
char *filename2 = alloca(strlen(_dest_dir) + strlen(ent_name) + 20);
sprintf(filename1, "%s/%s", orig_dir, ent_name);
sprintf(filename2, "%s/%s/%s", _dest_dir, CURRENT_SUBDIR, ent_name);
img1 = _image_load(filename1);
img2 = _image_load(filename2);
if (exactness_image_compare(img1, img2, &imgO))
{
char *buf = alloca(strlen(_dest_dir) + strlen(ent_name));
sprintf(buf, "%s/%s/comp_%s", _dest_dir, CURRENT_SUBDIR, ent_name);
_image_save(imgO, buf);
_compare_errors = eina_list_append(_compare_errors, strdup(ent_name));
result = EINA_TRUE;
}
exactness_image_free(img1);
exactness_image_free(img2);
exactness_image_free(imgO);
return result;
}
static void
_exu_imgs_unpack(const char *exu_path, const char *dir, const char *ent_name)
{
Exactness_Unit *unit = exactness_unit_file_read(exu_path);
Exactness_Image *img;
Eina_List *itr;
Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
Eo *e = ecore_evas_get(ee);
int n = 1;
if (!unit) return;
EINA_LIST_FOREACH(unit->imgs, itr, img)
{
Eo *o = evas_object_image_add(e);
char *filename = alloca(strlen(dir) + strlen(ent_name) + 20);
snprintf(filename, EXACTNESS_PATH_MAX, "%s/%s%c%.3d.png",
dir, ent_name, SHOT_DELIMITER, n++);
evas_object_image_size_set(o, img->w, img->h);
evas_object_image_data_set(o, img->pixels);
if (!evas_object_image_save(o, filename, NULL, NULL))
{
printf("Cannot save widget to <%s>\n", filename);
}
efl_del(o);
}
efl_del(e);
ecore_evas_free(ee);
}
static void
_run_test_compare(const List_Entry *ent)
{
char *path = alloca(EXACTNESS_PATH_MAX);
char *origdir = alloca(strlen(_dest_dir) + 20);
const char *base_dir;
Eina_List *itr;
int n = 1, nb_fails = 0;
printf("STATUS %s: COMPARE\n", ent->name);
EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
{
sprintf(path, "%s/%s.exu", base_dir, ent->name);
if (ecore_file_exists(path))
{
char *currentdir;
sprintf(origdir, "%s/%s/%s", _dest_dir, CURRENT_SUBDIR, ORIG_SUBDIR);
mkdir(origdir, 0744);
_exu_imgs_unpack(path, origdir, ent->name);
sprintf(path, "%s/%s/%s.exu", _dest_dir, CURRENT_SUBDIR, ent->name);
currentdir = alloca(strlen(_dest_dir) + 20);
sprintf(currentdir, "%s/%s", _dest_dir, CURRENT_SUBDIR);
_exu_imgs_unpack(path, currentdir, ent->name);
goto found;
}
else
{
sprintf(path, "%s/%s.rec", base_dir, ent->name);
if (ecore_file_exists(path))
{
sprintf(origdir, "%s/%s", _dest_dir, ORIG_SUBDIR);
goto found;
}
}
}
found:
do
{
sprintf(path, "%s/%s%c%.3d.png", origdir, ent->name, SHOT_DELIMITER, n);
if (ecore_file_exists(path))
{
sprintf(path, "%s%c%.3d.png", ent->name, SHOT_DELIMITER, n);
if (_file_compare(origdir, path)) nb_fails++;
}
else break;
n++;
} while (EINA_TRUE);
if (!nb_fails)
printf("STATUS %s: END - SUCCESS\n", ent->name);
else
printf("STATUS %s: END - FAIL (%d/%d)\n", ent->name, nb_fails, n - 1);
}
#define CONFIG "ELM_SCALE=1 ELM_FINGER_SIZE=10 "
static Eina_Bool
_run_command_prepare(const List_Entry *ent, char *buf)
{
char scn_path[EXACTNESS_PATH_MAX];
Eina_Strbuf *sbuf;
const char *base_dir;
Eina_List *itr;
Eina_Bool is_exu;
EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
{
is_exu = EINA_TRUE;
sprintf(scn_path, "%s/%s.exu", base_dir, ent->name);
if (ecore_file_exists(scn_path)) goto ok;
else
{
is_exu = EINA_FALSE;
sprintf(scn_path, "%s/%s.rec", base_dir, ent->name);
if (ecore_file_exists(scn_path)) goto ok;
}
}
fprintf(stderr, "Test %s not found in the provided base directories\n", ent->name);
return EINA_FALSE;
ok:
sbuf = eina_strbuf_new();
printf("STATUS %s: START\n", ent->name);
eina_strbuf_append_printf(sbuf,
"%s exactness_play %s %s%s %s%.*s %s%s%s-t '%s' ",
_wrap_command ? _wrap_command : "",
_mode == RUN_SIMULATION ? "-s" : "",
_fonts_dir ? "-f " : "", _fonts_dir ? _fonts_dir : "",
_verbose ? "-" : "", _verbose, "vvvvvvvvvv",
_scan_objs ? "--scan-objects " : "",
_disable_screenshots ? "--disable-screenshots " : "",
_stabilize_shots ? "--stabilize-shots " : "",
scn_path
);
if (is_exu)
{
if (_mode == RUN_PLAY)
eina_strbuf_append_printf(sbuf, "-o '%s/%s/%s.exu' ", _dest_dir, CURRENT_SUBDIR, ent->name);
if (_mode == RUN_INIT)
eina_strbuf_append_printf(sbuf, "-o '%s' ", scn_path);
}
else
{
if (_mode == RUN_PLAY)
eina_strbuf_append_printf(sbuf, "-o '%s/%s' ", _dest_dir, CURRENT_SUBDIR);
if (_mode == RUN_INIT)
eina_strbuf_append_printf(sbuf, "-o '%s/%s' ", _dest_dir, ORIG_SUBDIR);
}
if (ent->command)
{
eina_strbuf_append(sbuf, "-- ");
eina_strbuf_append(sbuf, CONFIG);
eina_strbuf_append(sbuf, ent->command);
}
strncpy(buf, eina_strbuf_string_get(sbuf), SCHEDULER_CMD_SIZE-1);
eina_strbuf_free(sbuf);
_printf(1, "Command: %s\n", buf);
return EINA_TRUE;
}
static void
_job_compare(void *data)
{
_run_test_compare(data);
_running_jobs--;
_job_consume();
/* If all jobs are done. */
if (!_running_jobs) ecore_main_loop_quit();
}
static Eina_Bool
_job_deleted_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event;
List_Entry *ent = ecore_exe_data_get(msg->exe);
if ((msg->exit_code != 0) || (msg->exit_signal != 0))
{
_errors = eina_list_append(_errors, ent);
}
if (_mode == RUN_PLAY)
{
ecore_job_add(_job_compare, ent);
}
else
{
_running_jobs--;
_job_consume();
if (!_running_jobs) ecore_main_loop_quit();
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_job_consume()
{
static Ecore_Event_Handler *job_del_callback_handler = NULL;
char buf[SCHEDULER_CMD_SIZE];
List_Entry *ent = _next_test_to_run;
if (_running_jobs == _max_jobs) return EINA_FALSE;
if (!ent) return EINA_FALSE;
if (_run_command_prepare(ent, buf))
{
_running_jobs++;
_tests_executed++;
if (!job_del_callback_handler)
{
job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
_job_deleted_cb, NULL);
}
if (!ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent))
{
fprintf(stderr, "Failed executing test '%s'\n", ent->name);
}
}
_next_test_to_run = EINA_INLIST_CONTAINER_GET(
EINA_INLIST_GET(ent)->next, List_Entry);
return EINA_TRUE;
}
static void
_scheduler_run()
{
while (_job_consume());
}
static List_Entry *
_list_file_load(const char *filename)
{
List_Entry *ret = NULL;
char buf[BUF_SIZE] = "";
FILE *file;
file = fopen(filename, "r");
if (!file)
{
perror("Failed opening list file");
return NULL;
}
while (fgets(buf, BUF_SIZE, file))
{
/* Skip comment/empty lines. */
if ((*buf == '#') || (*buf == '\n') || (!*buf))
continue;
char *tmp;
List_Entry *cur = calloc(1, sizeof(*cur));
cur->name = strdup(buf);
/* Set the command to the second half and put a \0 in between. */
tmp = strchr(cur->name, ' ');
if (tmp)
{
*tmp = '\0';
cur->command = tmp + 1;
}
else
{
/* FIXME: error. */
cur->command = "";
}
/* Replace the newline char with a \0. */
tmp = strchr(cur->command, '\n');
if (tmp)
{
*tmp = '\0';
}
ret = EINA_INLIST_CONTAINER_GET(
eina_inlist_append(EINA_INLIST_GET(ret), EINA_INLIST_GET(cur)),
List_Entry);
}
return ret;
}
static void
_list_file_free(List_Entry *list)
{
while (list)
{
List_Entry *ent = list;
list = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(list)->next,
List_Entry);
free(ent->name);
free(ent);
/* we don't free ent->command because it's allocated together. */
}
}
static int
_errors_sort_cb(List_Entry *a, List_Entry *b)
{
return strcmp(a->name, b->name);
}
#include "config.h"
static const Ecore_Getopt optdesc = {
"exactness",
@ -431,18 +17,15 @@ static const Ecore_Getopt optdesc = {
"A pixel perfect test suite for EFL based applications.",
0,
{
ECORE_GETOPT_APPEND('b', "base-dir", "The location of the exu/rec files.", ECORE_GETOPT_TYPE_STR),
ECORE_GETOPT_STORE_STR('o', "output", "The location of the images."),
ECORE_GETOPT_STORE_STR('b', "base-dir", "The location of the rec files."),
ECORE_GETOPT_STORE_STR('d', "dest-dir", "The location of the images."),
ECORE_GETOPT_STORE_STR('w', "wrap", "Use a custom command to launch the tests (e.g valgrind)."),
ECORE_GETOPT_STORE_USHORT('j', "jobs", "The number of jobs to run in parallel."),
ECORE_GETOPT_STORE_TRUE('r', "record", "Run in record mode."),
ECORE_GETOPT_STORE_TRUE('p', "play", "Run in play mode."),
ECORE_GETOPT_STORE_TRUE('i', "init", "Run in init mode."),
ECORE_GETOPT_STORE_TRUE('s', "simulation", "Run in simulation mode."),
ECORE_GETOPT_STORE_TRUE(0, "scan-objects", "Extract information of all the objects at every shot."),
ECORE_GETOPT_STORE_TRUE(0, "disable-screenshots", "Disable screenshots."),
ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
ECORE_GETOPT_STORE_TRUE(0, "stabilize-shots", "Wait for the frames to be stable before taking the shots."),
ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
ECORE_GETOPT_STORE_TRUE('v', "verbose", "Turn verbose messages on."),
ECORE_GETOPT_LICENSE('L', "license"),
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
@ -458,25 +41,20 @@ main(int argc, char *argv[])
int ret = 0;
List_Entry *test_list;
int args = 0;
const char *list_file;
Eina_List *itr;
const char *base_dir;
const char *list_file = "";
char tmp[EXACTNESS_PATH_MAX];
Eina_Bool mode_play = EINA_FALSE, mode_init = EINA_FALSE, mode_simulation = EINA_FALSE;
Eina_Bool want_quit = EINA_FALSE, scan_objs = EINA_FALSE;
Eina_Bool mode_record, mode_play, mode_init, mode_simulation;
Eina_Bool want_quit;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_LIST(_base_dirs),
ECORE_GETOPT_VALUE_STR(_dest_dir),
ECORE_GETOPT_VALUE_STR(_wrap_command),
ECORE_GETOPT_VALUE_USHORT(_max_jobs),
ECORE_GETOPT_VALUE_STR(exactness_config.base_dir),
ECORE_GETOPT_VALUE_STR(exactness_config.dest_dir),
ECORE_GETOPT_VALUE_STR(exactness_config.wrap_command),
ECORE_GETOPT_VALUE_USHORT(exactness_config.jobs),
ECORE_GETOPT_VALUE_BOOL(mode_record),
ECORE_GETOPT_VALUE_BOOL(mode_play),
ECORE_GETOPT_VALUE_BOOL(mode_init),
ECORE_GETOPT_VALUE_BOOL(mode_simulation),
ECORE_GETOPT_VALUE_BOOL(scan_objs),
ECORE_GETOPT_VALUE_BOOL(_disable_screenshots),
ECORE_GETOPT_VALUE_STR(_fonts_dir),
ECORE_GETOPT_VALUE_BOOL(_stabilize_shots),
ECORE_GETOPT_VALUE_INT(_verbose),
ECORE_GETOPT_VALUE_BOOL(exactness_config.verbose),
ECORE_GETOPT_VALUE_BOOL(want_quit),
ECORE_GETOPT_VALUE_BOOL(want_quit),
@ -486,12 +64,13 @@ main(int argc, char *argv[])
};
ecore_init();
ecore_evas_init();
evas_init();
mode_play = mode_init = mode_simulation = EINA_FALSE;
mode_record = mode_play = mode_init = mode_simulation = EINA_FALSE;
want_quit = EINA_FALSE;
_dest_dir = "./";
_scan_objs = scan_objs;
exactness_config.base_dir = "./recordings";
exactness_config.dest_dir = "./";
exactness_config.wrap_command = "";
exactness_config.jobs = 1;
exactness_config.verbose = EINA_FALSE;
args = ecore_getopt_parse(&optdesc, values, argc, argv);
if (args < 0)
@ -512,7 +91,7 @@ main(int argc, char *argv[])
ret = 1;
goto end;
}
else if (mode_play + mode_init + mode_simulation != 1)
else if (mode_record + mode_play + mode_init + mode_simulation != 1)
{
fprintf(stderr, "At least and only one of the running modes can be set.\n");
ecore_getopt_help(stderr, &optdesc);
@ -520,13 +99,11 @@ main(int argc, char *argv[])
goto end;
}
if (!_base_dirs) _base_dirs = eina_list_append(NULL, "./recordings");
list_file = argv[args];
/* Load the list file and start iterating over the records. */
test_list = _list_file_load(list_file);
_next_test_to_run = test_list;
test_list = list_file_load(list_file);
if (!test_list)
{
@ -537,17 +114,18 @@ main(int argc, char *argv[])
/* Pre-run summary */
fprintf(stderr, "Running with settings:\n");
fprintf(stderr, "\tConcurrent jobs: %d\n", _max_jobs);
fprintf(stderr, "\tConcurrent jobs: %d\n", exactness_config.jobs);
fprintf(stderr, "\tTest list: %s\n", list_file);
fprintf(stderr, "\tBase dirs:\n");
EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
fprintf(stderr, "\t\t%s\n", base_dir);
fprintf(stderr, "\tDest dir: %s\n", _dest_dir);
fprintf(stderr, "\tBase dir: %s\n", exactness_config.base_dir);
fprintf(stderr, "\tDest dir: %s\n", exactness_config.dest_dir);
if (mode_play)
if (mode_record)
{
_mode = RUN_PLAY;
if (snprintf(tmp, EXACTNESS_PATH_MAX, "%s/%s", _dest_dir, CURRENT_SUBDIR)
scheduler_run(run_test_record, test_list);
}
else if (mode_play)
{
if (snprintf(tmp, EXACTNESS_PATH_MAX, "%s/%s", exactness_config.dest_dir, CURRENT_SUBDIR)
>= EXACTNESS_PATH_MAX)
{
fprintf(stderr, "Path too long: %s", tmp);
@ -555,11 +133,11 @@ main(int argc, char *argv[])
goto end;
}
mkdir(tmp, 0744);
scheduler_run(run_test_play, test_list);
}
else if (mode_init)
{
_mode = RUN_INIT;
if (snprintf(tmp, EXACTNESS_PATH_MAX, "%s/%s", _dest_dir, ORIG_SUBDIR)
if (snprintf(tmp, EXACTNESS_PATH_MAX, "%s/%s", exactness_config.dest_dir, ORIG_SUBDIR)
>= EXACTNESS_PATH_MAX)
{
fprintf(stderr, "Path too long: %s", tmp);
@ -567,105 +145,86 @@ main(int argc, char *argv[])
goto end;
}
mkdir(tmp, 0744);
scheduler_run(run_test_init, test_list);
}
else if (mode_simulation)
{
_mode = RUN_SIMULATION;
scheduler_run(run_test_simulation, test_list);
}
_scheduler_run();
ecore_main_loop_begin();
/* Results */
printf("*******************************************************\n");
if (mode_play && EINA_FALSE)
if (mode_play)
{
List_Entry *list_itr;
EINA_INLIST_FOREACH(test_list, list_itr)
{
_run_test_compare(list_itr);
run_test_compare(list_itr);
}
}
printf("Finished executing %u out of %u tests.\n",
_tests_executed,
exactness_ctx.tests_executed,
eina_inlist_count(EINA_INLIST_GET(test_list)));
/* Sort the errors and the compare_errors. */
_errors = eina_list_sort(_errors, 0, (Eina_Compare_Cb) _errors_sort_cb);
_compare_errors = eina_list_sort(_compare_errors, 0, (Eina_Compare_Cb) strcmp);
if (_errors || _compare_errors)
if (exactness_ctx.errors || exactness_ctx.compare_errors)
{
FILE *report_file;
char report_filename[EXACTNESS_PATH_MAX] = "";
/* Generate the filename. */
snprintf(report_filename, EXACTNESS_PATH_MAX,
"%s/%s/errors.html",
_dest_dir, mode_init ? ORIG_SUBDIR : CURRENT_SUBDIR);
exactness_config.dest_dir, CURRENT_SUBDIR);
report_file = fopen(report_filename, "w+");
if (report_file)
printf("%s %p\n", report_filename, report_file);
fprintf(report_file,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Exactness report</title></head><body>");
if (exactness_ctx.errors)
{
printf("%s %p\n", report_filename, report_file);
fprintf(report_file,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Exactness report</title></head><body>");
if (_errors)
"<h1>Tests that failed execution:</h1><ul>");
Eina_List *itr;
List_Entry *ent;
printf("List of tests that failed execution:\n");
EINA_LIST_FOREACH(exactness_ctx.errors, itr, ent)
{
fprintf(report_file,
"<h1>Tests that failed execution:</h1><ul>");
List_Entry *ent;
printf("List of tests that failed execution:\n");
EINA_LIST_FOREACH(_errors, itr, ent)
{
printf("\t* %s\n", ent->name);
printf("\t* %s\n", ent->name);
fprintf(report_file, "<li>%s</li>", ent->name);
}
fprintf(report_file, "</ul>");
fprintf(report_file, "<li>%s</li>", ent->name);
}
if (_compare_errors)
{
fprintf(report_file,
"<h1>Images that failed comparison: (Original, Current, Diff)</h1><ul>");
char *test_name;
printf("List of images that failed comparison:\n");
EINA_LIST_FREE(_compare_errors, test_name)
{
Eina_Bool is_from_exu;
char origpath[EXACTNESS_PATH_MAX];
snprintf(origpath, EXACTNESS_PATH_MAX, "%s/%s/orig/%s",
_dest_dir, CURRENT_SUBDIR, test_name);
is_from_exu = ecore_file_exists(origpath);
printf("\t* %s\n", test_name);
fprintf(report_file, "<li><h2>%s</h2> <img src='%sorig/%s' alt='Original' /> <img src='%s' alt='Current' /> <img src='comp_%s' alt='Diff' /></li>",
test_name, is_from_exu ? "" : "../",
test_name, test_name, test_name);
free(test_name);
}
fprintf(report_file, "</ul>");
}
fprintf(report_file,
"</body></html>");
printf("Report html: %s\n", report_filename);
ret = 1;
fprintf(report_file, "</ul>");
}
else
if (exactness_ctx.compare_errors)
{
perror("Failed opening report file");
fprintf(report_file,
"<h1>Images that failed comparison: (Original, Current, Diff)</h1><ul>");
char *test_name;
printf("List of images that failed comparison:\n");
EINA_LIST_FREE(exactness_ctx.compare_errors, test_name)
{
printf("\t* %s\n", test_name);
fprintf(report_file, "<li><h2>%s</h2> <img src='../orig/%s' alt='Original' /> <img src='%s' alt='Current' /> <img src='comp_%s' alt='Diff' /></li>", test_name, test_name, test_name, test_name);
free(test_name);
}
fprintf(report_file, "</ul>");
}
fprintf(report_file,
"</body></html>");
printf("Report html: %s\n", report_filename);
ret = 1;
}
_list_file_free(test_list);
list_file_free(test_list);
end:
evas_shutdown();
ecore_evas_shutdown();
ecore_shutdown();
return ret;

View File

@ -0,0 +1,4 @@
#include "exactness_config.h"
Exactness_Config exactness_config;
Exactness_Ctx exactness_ctx;

View File

@ -0,0 +1,35 @@
#ifndef EXACTNESS_CONFIG_H
#define EXACTNESS_CONFIG_H
#include <Eina.h>
typedef struct _Exactness_Config Exactness_Config;
struct _Exactness_Config
{
unsigned short jobs;
char *base_dir;
char *dest_dir;
char *wrap_command;
Eina_Bool verbose;
};
extern Exactness_Config exactness_config;
typedef struct _Exactness_Ctx Exactness_Ctx;
struct _Exactness_Ctx
{
unsigned int tests_executed;
Eina_List *errors;
Eina_List *compare_errors;
};
extern Exactness_Ctx exactness_ctx;
#define ORIG_SUBDIR "orig"
#define CURRENT_SUBDIR "current"
#define EXACTNESS_PATH_MAX 1024
#endif

View File

@ -1,483 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.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; \
}
#ifndef WORDS_BIGENDIAN
#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 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 _efl_event_op = EINA_DEBUG_OPCODE_INVALID;
static int _click_on_op = EINA_DEBUG_OPCODE_INVALID;
static int _stabilize_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/EFL Event", &_efl_event_op, NULL},
{"Exactness/Actions/Click On", &_click_on_op, NULL},
{"Exactness/Actions/Stabilize", &_stabilize_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;
}
case EXACTNESS_ACTION_EFL_EVENT:
{
Exactness_Action_Efl_Event *t = data;
int len = 0;
len += t->wdg_name ? strlen(t->wdg_name) : 0;
len += t->event_name ? strlen(t->event_name) : 0;
char *buf = malloc(len), *tmp = buf;
_printf(2, "%s %s\n", __func__, "EFL event");
STORE_STRING(tmp, t->wdg_name);
STORE_STRING(tmp, t->event_name);
eina_debug_session_send(_session, _cid, _efl_event_op, buf, len);
break;
}
case EXACTNESS_ACTION_CLICK_ON:
{
Exactness_Action_Click_On *t = data;
int len = 0;
len += t->wdg_name ? strlen(t->wdg_name) : 0;
char *buf = malloc(len), *tmp = buf;
_printf(2, "%s %s\n", __func__, "Click On");
STORE_STRING(tmp, t->wdg_name);
eina_debug_session_send(_session, _cid, _click_on_op, buf, len);
break;
}
case EXACTNESS_ACTION_STABILIZE:
{
_printf(2, "%s stabilize\n", __func__);
eina_debug_session_send(_session, _cid, _stabilize_op, NULL, 0);
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);
_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
{
Exactness_Action *cur_act = eina_list_data_get(_cur_event_list);
ecore_timer_add(cur_act->delay_ms / 1000.0, _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);
if (act->delay_ms)
{
_printf(2, " Waiting <%f>\n", diff_time);
ecore_timer_add(act->delay_ms / 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__ = 1, 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__;
}

File diff suppressed because it is too large Load Diff

72
src/bin/list_file.c Normal file
View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include "list_file.h"
#define BUF_SIZE 1024
List_Entry *
list_file_load(const char *filename)
{
List_Entry *ret = NULL;
char buf[BUF_SIZE] = "";
FILE *file;
file = fopen(filename, "r");
if (!file)
{
perror("Failed opening list file");
return NULL;
}
while (fgets(buf, BUF_SIZE, file))
{
/* Skip comment/empty lines. */
if ((*buf == '#') || (*buf == '\n') || (!*buf))
continue;
char *tmp;
List_Entry *cur = calloc(1, sizeof(*cur));
cur->name = strdup(buf);
/* Set the command to the second half and put a \0 in between. */
tmp = strchr(cur->name, ' ');
if (tmp)
{
*tmp = '\0';
cur->command = tmp + 1;
}
else
{
/* FIXME: error. */
cur->command = "";
}
/* Replace the newline char with a \0. */
tmp = strchr(cur->command, '\n');
if (tmp)
{
*tmp = '\0';
}
ret = EINA_INLIST_CONTAINER_GET(
eina_inlist_append(EINA_INLIST_GET(ret), EINA_INLIST_GET(cur)),
List_Entry);
}
return ret;
}
void
list_file_free(List_Entry *list)
{
while (list)
{
List_Entry *ent = list;
list = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(list)->next,
List_Entry);
free(ent->name);
free(ent);
/* we don't free ent->command because it's allocated together. */
}
}

17
src/bin/list_file.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef LIST_FILE_H
#define LIST_FILE_H
#include <Eina.h>
typedef struct _List_Entry List_Entry;
struct _List_Entry
{
EINA_INLIST;
char *name;
const char *command;
};
List_Entry *list_file_load(const char *filename);
void list_file_free(List_Entry *list);
#endif

295
src/bin/md5/md5.c Normal file
View File

@ -0,0 +1,295 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* (This is a heavily cut-down "BSD license".)
*
* This differs from Colin Plumb's older public domain implementation in that
* no exactly 32-bit integer data type is required (any 32-bit or wider
* unsigned integer data type will do), there's no compile-time endianness
* configuration, and the function prototypes match OpenSSL's. No code from
* Colin Plumb's implementation has been reused; this comment merely compares
* the properties of the two independent implementations.
*
* The primary goals of this implementation are portability and ease of use.
* It is meant to be fast, but not as fast as possible. Some known
* optimizations are not included to reduce source code size and avoid
* compile-time configuration.
*/
#ifndef HAVE_OPENSSL
#include <string.h>
#include "md5.h"
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them
* in a properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned
* memory accesses is just an optimization. Nothing will break if it
* doesn't work.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define GET(n) \
SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
static void *body(MD5_CTX *ctx, void *data, unsigned long size)
{
unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, free;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
free = 64 - used;
if (size < free) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, free);
data = (unsigned char *)data + free;
size -= free;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, free;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
free = 64 - used;
if (free < 8) {
memset(&ctx->buffer[used], 0, free);
body(ctx, ctx->buffer, 64);
used = 0;
free = 64;
}
memset(&ctx->buffer[used], 0, free - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
memset(ctx, 0, sizeof(*ctx));
}
#endif

45
src/bin/md5/md5.h Normal file
View File

@ -0,0 +1,45 @@
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
*
* Homepage:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
* See md5.c for more information.
*/
#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#elif !defined(_MD5_H)
#define _MD5_H
/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
extern void MD5_Init(MD5_CTX *ctx);
extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,932 +0,0 @@
collections {
#include "player_fonts.edc"
group { name: "elm/entry/cursor/default";
min: 1 0;
images.image: "white_bar_vert_glow.png" COMP;
parts {
part { name: "cursor"; mouse_events: 0;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.offset: -4 -4;
rel2.offset: 3 3;
image.normal: "white_bar_vert_glow.png";
image.border: 4 4 4 4;
fill.smooth: 0;
color: 255 255 255 0;
color_class: "entry_cursor";
min: 9 10;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
color: 255 255 255 255;
}
}
part { name: "clipper"; type: RECT;
description { state: "default" 0.0;
rel1.to: "cursor";
rel2.to: "cursor";
fixed: 1 1;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program {
signal: "selection,changed"; source: "elm.text";
action: STATE_SET "hidden" 0.0;
target: "clipper";
}
program {
signal: "selection,cleared"; source: "elm.text";
action: STATE_SET "default" 0.0;
target: "clipper";
}
program {
signal: "selection,reset"; source: "elm.text";
action: STATE_SET "default" 0.0;
target: "clipper";
}
program {
signal: "elm,action,focus"; source: "elm";
action: ACTION_STOP;
target: "cursor_show";
target: "cursor_hide";
target: "cursor_show_timer";
target: "cursor_hide_timer";
after: "cursor_show";
}
program {
signal: "elm,action,unfocus"; source: "elm";
action: ACTION_STOP;
target: "cursor_show";
target: "cursor_hide";
target: "cursor_show_timer";
target: "cursor_hide_timer";
after: "cursor_hide_stop";
}
program {
signal: "elm,action,show,cursor"; source: "elm";
action: ACTION_STOP;
target: "cursor_show";
target: "cursor_hide";
target: "cursor_show_timer";
target: "cursor_hide_timer";
after: "cursor_show";
}
program { name: "cursor_hide_stop";
action: STATE_SET "default" 0.0;
target: "cursor";
}
program { name: "cursor_show";
action: STATE_SET "default" 0.0;
target: "cursor";
after: "cursor_show_timer";
}
program { name: "cursor_hide";
action: STATE_SET "default" 0.0;
target: "cursor";
transition: SINUSOIDAL 0.2;
after: "cursor_hide_timer";
}
program { name: "cursor_show_timer";
in: 0.5 0.0;
after: "cursor_hide";
}
program { name: "cursor_hide_timer";
in: 0.2 0.0;
after: "cursor_show";
}
}
}
group { name: "elm/entry/selection/default";
parts {
part { name: "base"; type: RECT;
description { state: "default" 0.0;
color: 51 153 255 255;
}
}
}
}
group { name: "elm/entry/anchor/default";
images.image: "horizontal_separated_bar_small_glow.png" COMP;
parts {
part { name: "bar";
description { state: "default" 0.0;
image.normal: "horizontal_separated_bar_small_glow.png";
image.border: 4 4 4 4;
fill.smooth: 0;
fixed: 0 1;
rel1.relative: 0.0 1.0;
rel1.offset: -3 -5;
rel2.offset: 2 4;
}
}
}
}
group { name: "elm/entry/base/default";
sounds {
sample { name: "key-tap1" LOSSY 64;
source: "kbd-tap.wav";
}
sample { name: "key-tap2" LOSSY 64;
source: "kbd-tap2.wav";
}
sample { name: "key-tap3" LOSSY 64;
source: "kbd-tap3.wav";
}
sample { name: "key-tap4" LOSSY 64;
source: "kbd-tap4.wav";
}
sample { name: "key-tap5" LOSSY 64;
source: "kbd-tap5.wav";
}
}
styles {
style { name: "entry_style";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=word text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
style { name: "entry_nowrap_style";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
style { name: "entry_disabled_style";
base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=word text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
DISABLED_TEXTBLOCK_TAGS
}
style { name: "entry_nowrap_disabled_style";
base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
DISABLED_TEXTBLOCK_TAGS
}
style { name: "entry_guide_style";
base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=word text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
DISABLED_TEXTBLOCK_TAGS
}
}
// data.item: "context_menu_orientation" "horizontal";
parts {
part { name: "elm.swallow.background"; type: SWALLOW;
description { state: "default" 0.0;
rel1.offset: 1 1;
rel2.offset: -2 -2;
}
}
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_guide_style";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text"; type: TEXTBLOCK;
scale: 1;
entry_mode: EDITABLE;
select_mode: DEFAULT;
// select_mode: EXPLICIT;
cursor_mode: BEFORE;
multiline: 1;
source: "elm/entry/selection/default"; // selection under
// source2: "X"; // selection over
// source3: "X"; // cursor under
source4: "elm/entry/cursor/default"; // cursorover
// source5: "elm/entry/anchor/default"; // anchor under
source6: "elm/entry/anchor/default"; // anchor over
description { state: "default" 0.0;
/* we gotta use 0 0 here, because of scrolled entries */
fixed: 0 0;
rel1.offset: 2 2;
rel2.offset: -3 -3;
text { style: "entry_style";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style";
min: 0 1;
}
}
}
}
programs {
program {
signal: "load"; source: "";
action: FOCUS_SET;
target: "elm.text";
}
program {
signal: "elm,state,disabled"; source: "elm";
action: STATE_SET "disabled" 0.0;
target: "elm.text";
}
program {
signal: "elm,state,enabled"; source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.text";
}
program {
signal: "elm,guide,disabled"; source: "elm";
action: STATE_SET "hidden" 0.0;
target: "elm.guide";
}
program {
signal: "elm,guide,enabled"; source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.guide";
}
program { name: "key-down";
signal: "entry,keydown"; source: "elm.text";
script {
new buf[32];
snprintf(buf, 31, "key-down%i", (rand() % 5) + 1);
run_program(get_program_id(buf));
}
}
program { name: "key-down1";
action: PLAY_SAMPLE "key-tap1" 1.0 INPUT;
}
program { name: "key-down2";
action: PLAY_SAMPLE "key-tap2" 1.0 INPUT;
}
program { name: "key-down3";
action: PLAY_SAMPLE "key-tap3" 1.0 INPUT;
}
program { name: "key-down4";
action: PLAY_SAMPLE "key-tap4" 1.0 INPUT;
}
program { name: "key-down5";
action: PLAY_SAMPLE "key-tap5" 1.0 INPUT;
}
}
}
group { name: "elm/entry/base-mixedwrap/default";
inherit: "elm/entry/base/default";
styles {
style { name: "entry_style_mixedwrap";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=mixed text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
style { name: "entry_disabled_style_mixedwrap";
base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=mixed text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
DISABLED_TEXTBLOCK_TAGS
}
style { name: "entry_guide_style_mixedwrap";
base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=mixed text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
DISABLED_TEXTBLOCK_TAGS
}
}
parts {
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_guide_style_mixedwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text";
description { state: "default" 0.0;
fixed: 1 0;
text { style: "entry_style_mixedwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style_mixedwrap";
min: 0 1;
}
}
}
}
}
group { name: "elm/entry/base-charwrap/default";
inherit: "elm/entry/base/default";
styles {
style { name: "entry_style_charwrap";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=char text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
style { name: "entry_disabled_style_charwrap";
base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=char text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
DISABLED_TEXTBLOCK_TAGS
}
style { name: "entry_guide_style_charwrap";
base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=char text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
DISABLED_TEXTBLOCK_TAGS
}
}
parts {
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_guide_style_charwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text";
description { state: "default" 0.0;
fixed: 1 1;
text { style: "entry_style_charwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style_charwrap";
min: 0 1;
}
}
}
}
}
group { name: "elm/entry/base-nowrap/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_guide_style";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text";
description { state: "default" 0.0;
text { style: "entry_nowrap_style";
min: 1 1;
ellipsis: -1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_nowrap_disabled_style";
min: 0 1;
}
}
}
}
}
group { name: "elm/entry/base-single/default";
inherit: "elm/entry/base/default";
styles {
style { name: "entry_single_style";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=none text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
style { name: "entry_single_disabled_style";
base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=none text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
DISABLED_TEXTBLOCK_TAGS
}
style { name: "entry_single_guide_style";
base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=none text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
DISABLED_TEXTBLOCK_TAGS
}
}
parts {
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_single_guide_style";
min: 0 1;
align: 0.0 0.5;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text";
multiline: 0;
description { state: "default" 0.0;
text { style: "entry_single_style";
min: 1 1;
ellipsis: -1;
max: 0 0;
align: 0.0 0.5;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_single_disabled_style";
}
}
}
}
}
group { name: "elm/entry/base-single/spinner/default";
alias: "elm/entry/base-single/spinner/vertical";
inherit: "elm/entry/base-single/default";
styles {
style { name: "entry_single_spinner_style";
base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 align=center wrap=none text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
ENABLED_TEXTBLOCK_TAGS
}
}
parts {
part { name: "elm.text";
description { state: "default" 0.0;
text.style: "entry_single_spinner_style";
}
}
}
}
group { name: "elm/entry/base-single-noedit/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.text";
entry_mode: PLAIN;
multiline: 0;
source: "elm/entry/selection/default"; // selection under
source4: ""; // cursorover
source6: "elm/entry/anchor/default"; // anchor over
description { state: "default" 0.0;
text { style: "entry_single_style";
min: 1 1;
ellipsis: -1;
max: 0 0;
align: 0.0 0.5;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_single_disabled_style";
}
}
}
}
}
group { name: "elm/entry/base-noedit/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.text";
entry_mode: PLAIN;
source: "elm/entry/selection/default"; // selection under
source4: ""; // cursorover
source6: "elm/entry/anchor/default"; // anchor over
description { state: "default" 0.0;
fixed: 1 0;
text { style: "entry_style";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style";
}
}
}
}
}
group { name: "elm/entry/base-noedit-mixedwrap/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.text";
entry_mode: PLAIN;
source: "elm/entry/selection/default"; // selection under
source4: ""; // cursorover
source6: "elm/entry/anchor/default"; // anchor over
description { state: "default" 0.0;
fixed: 1 0;
text { style: "entry_style_mixedwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style_mixedwrap";
}
}
}
}
}
group { name: "elm/entry/base-noedit-charwrap/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.text";
entry_mode: PLAIN;
source: "elm/entry/selection/default"; // selection under
source4: ""; // cursorover
source6: "elm/entry/anchor/default"; // anchor under
description { state: "default" 0.0;
fixed: 1 0;
text { style: "entry_style_charwrap";
min: 0 1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style_charwrap";
}
}
}
}
}
group { name: "elm/entry/base-nowrap-noedit/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.text";
entry_mode: PLAIN;
source: "elm/entry/selection/default"; // selection under
source4: ""; // cursorover
source6: "elm/entry/anchor/default"; // anchor under
description { state: "default" 0.0;
text { style: "entry_style";
min: 1 1;
ellipsis: -1;
align: 0.0 0.0;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_disabled_style";
}
}
}
}
}
group { name: "elm/entry/base-password/default";
inherit: "elm/entry/base/default";
parts {
part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.text";
rel2.to: "elm.text";
text { style: "entry_single_guide_style";
min: 0 1;
align: 0.0 0.5;
}
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.text";
entry_mode: PASSWORD;
multiline: 0;
source: "elm/entry/selection/default"; // selection under
source4: "elm/entry/cursor/default"; // cursorover
source6: "elm/entry/anchor/default"; // anchor under
description { state: "default" 0.0;
text { style: "entry_single_style";
repch: "*";
min: 1 1;
ellipsis: -1;
max: 0 0;
align: 0.0 0.5;
}
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
text { style: "entry_single_disabled_style";
}
}
}
}
}
group { name: "elm/entry/magnifier/default";
images.image: "frame_rounded.png" COMP;
parts {
part { name: "bg"; type: RECT; mouse_events: 0;
description { state: "default" 0.0;
rel1.offset: 10 10;
rel1.to: "over";
rel2.offset: -11 -11;
rel2.to: "over";
color: 48 48 48 255;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "elm.swallow.content"; type: SWALLOW; mouse_events: 0;
description { state: "default" 0.0;
rel1.offset: 10 10;
rel1.to: "over";
rel2.offset: -11 -11;
rel2.to: "over";
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
part { name: "over"; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
min: 128 64;
align: 0 0;
image.normal: "frame_rounded.png";
image.border: 14 14 14 14;
image.middle: 0;
fill.smooth: 0;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program { name: "magnifier_show";
signal: "elm,action,show,magnifier"; source: "elm";
action: STATE_SET "default" 0.0;
target: "elm.swallow.content";
target: "bg";
target: "over";
}
program { name: "magnifier_hide";
signal: "elm,action,hide,magnifier"; source: "elm";
action: STATE_SET "hidden" 0.0;
target: "elm.swallow.content";
target: "bg";
target: "over";
}
}
}
group { name: "elm/entry/handler/start/default";
images.image: "handle_pick_up_left.png" COMP;
parts {
part { name: "base"; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
min: 21 27; // 42 54
image.normal: "handle_pick_up_left.png";
align: (29/42) (11/54);
color_class: "entry_selection_handler";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "event"; type: RECT;
scale: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "base";
rel2.to: "base";
min: 32 32;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program {
signal: "elm,handler,show"; source: "elm";
action: STATE_SET "visible" 0.0;
target: "base";
target: "event";
}
program {
signal: "elm,handler,hide"; source: "elm";
action: STATE_SET "default" 0.0;
target: "base";
target: "event";
}
}
}
group { name: "elm/entry/handler/end/default";
images.image: "handle_pick_up_right.png" COMP;
parts {
part { name: "base"; mouse_events: 0;
scale: 1;
description { state: "default" 0.0;
min: 21 27; // 42 54
image.normal: "handle_pick_up_right.png";
align: (12/42) (11/54);
color_class: "entry_selection_handler";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "event"; type: RECT;
scale: 1;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "base";
rel2.to: "base";
min: 32 32;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program {
signal: "elm,handler,show"; source: "elm";
action: STATE_SET "visible" 0.0;
target: "base";
target: "event";
}
program {
signal: "elm,handler,hide"; source: "elm";
action: STATE_SET "default" 0.0;
target: "base";
target: "event";
}
}
}
///////////////////////////////////////////////////////////////////////////////
// emoticon images from:
// Tanya - Latvia
// http://lazycrazy.deviantart.com/
// http://lazycrazy.deviantart.com/art/Very-Emotional-Emoticons-144461621
group { name: "elm/entry/emoticon/angry/default"; images.image:
"emo-angry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-angry.png"; } } } }
group { name: "elm/entry/emoticon/angry-shout/default"; images.image:
"emo-angry-shout.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-angry-shout.png"; } } } }
group { name: "elm/entry/emoticon/crazy-laugh/default"; images.image:
"emo-crazy-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-crazy-laugh.png"; } } } }
group { name: "elm/entry/emoticon/evil-laugh/default"; images.image:
"emo-evil-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-evil-laugh.png"; } } } }
group { name: "elm/entry/emoticon/evil/default"; images.image:
"emo-evil.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-evil.png"; } } } }
group { name: "elm/entry/emoticon/goggle-smile/default"; images.image:
"emo-goggle-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-goggle-smile.png"; } } } }
group { name: "elm/entry/emoticon/grumpy/default"; images.image:
"emo-grumpy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-grumpy.png"; } } } }
group { name: "elm/entry/emoticon/grumpy-smile/default"; images.image:
"emo-grumpy-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-grumpy-smile.png"; } } } }
group { name: "elm/entry/emoticon/guilty/default"; images.image:
"emo-guilty.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-guilty.png"; } } } }
group { name: "elm/entry/emoticon/guilty-smile/default"; images.image:
"emo-guilty-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-guilty-smile.png"; } } } }
group { name: "elm/entry/emoticon/haha/default"; images.image:
"emo-haha.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-haha.png"; } } } }
group { name: "elm/entry/emoticon/half-smile/default"; images.image:
"emo-half-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-half-smile.png"; } } } }
group { name: "elm/entry/emoticon/happy-panting/default"; images.image:
"emo-happy-panting.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-happy-panting.png"; } } } }
group { name: "elm/entry/emoticon/happy/default"; images.image:
"emo-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-happy.png"; } } } }
group { name: "elm/entry/emoticon/indifferent/default"; images.image:
"emo-indifferent.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-indifferent.png"; } } } }
group { name: "elm/entry/emoticon/kiss/default"; images.image:
"emo-kiss.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-kiss.png"; } } } }
group { name: "elm/entry/emoticon/knowing-grin/default"; images.image:
"emo-knowing-grin.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-knowing-grin.png"; } } } }
group { name: "elm/entry/emoticon/laugh/default"; images.image:
"emo-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-laugh.png"; } } } }
group { name: "elm/entry/emoticon/little-bit-sorry/default"; images.image:
"emo-little-bit-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-little-bit-sorry.png"; } } } }
group { name: "elm/entry/emoticon/love-lots/default"; images.image:
"emo-love-lots.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-love-lots.png"; } } } }
group { name: "elm/entry/emoticon/love/default"; images.image:
"emo-love.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-love.png"; } } } }
group { name: "elm/entry/emoticon/minimal-smile/default"; images.image:
"emo-minimal-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-minimal-smile.png"; } } } }
group { name: "elm/entry/emoticon/not-happy/default"; images.image:
"emo-not-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-not-happy.png"; } } } }
group { name: "elm/entry/emoticon/not-impressed/default"; images.image:
"emo-not-impressed.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-not-impressed.png"; } } } }
group { name: "elm/entry/emoticon/omg/default"; images.image:
"emo-omg.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-omg.png"; } } } }
group { name: "elm/entry/emoticon/opensmile/default"; images.image:
"emo-opensmile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-opensmile.png"; } } } }
group { name: "elm/entry/emoticon/smile/default"; images.image:
"emo-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-smile.png"; } } } }
group { name: "elm/entry/emoticon/sorry/default"; images.image:
"emo-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-sorry.png"; } } } }
group { name: "elm/entry/emoticon/squint-laugh/default"; images.image:
"emo-squint-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-squint-laugh.png"; } } } }
group { name: "elm/entry/emoticon/surprised/default"; images.image:
"emo-surprised.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-surprised.png"; } } } }
group { name: "elm/entry/emoticon/suspicious/default"; images.image:
"emo-suspicious.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-suspicious.png"; } } } }
group { name: "elm/entry/emoticon/tongue-dangling/default"; images.image:
"emo-tongue-dangling.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-tongue-dangling.png"; } } } }
group { name: "elm/entry/emoticon/tongue-poke/default"; images.image:
"emo-tongue-poke.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-tongue-poke.png"; } } } }
group { name: "elm/entry/emoticon/uh/default"; images.image:
"emo-uh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-uh.png"; } } } }
group { name: "elm/entry/emoticon/unhappy/default"; images.image:
"emo-unhappy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-unhappy.png"; } } } }
group { name: "elm/entry/emoticon/very-sorry/default"; images.image:
"emo-very-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-very-sorry.png"; } } } }
group { name: "elm/entry/emoticon/what/default"; images.image:
"emo-what.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-what.png"; } } } }
group { name: "elm/entry/emoticon/wink/default"; images.image:
"emo-wink.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-wink.png"; } } } }
group { name: "elm/entry/emoticon/worried/default"; images.image:
"emo-worried.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-worried.png"; } } } }
group { name: "elm/entry/emoticon/wtf/default"; images.image:
"emo-wtf.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
"emo-wtf.png"; } } } }
//------------------------------------------------------------
}

View File

@ -1,114 +0,0 @@
/*fonts {
font: "PT_Sans-Web-Regular.ttf" "PTSans";
font: "PT_Sans-Web-Bold.ttf" "PTSans-Bold";
font: "PT_Sans-Web-Italic.ttf" "PTSans-Italic";
font: "PT_Sans-Web-BoldItalic.ttf" "PTSans-BoldItalic";
}
#define FN "PTSans"
#define FNBD "PTSans-Bold"
#define FNIT "PTSans-Italic"
#define FNBDIT "PTSans-BoldItalic"
*/
#define FN "Sans"
#define FNBD "Sans:style=Bold"
#define FNIT "Sans:style=Oblique"
#define FNBDIT "Sans:style=Bold Italic"
#define FN_COL_DEFAULT_BASIC 255 255 255 255
/* fonts.edc not sure if this one is neccesary */
#define FN_COL_DEFAULT 255 255 255 255; color3: 0 0 0 128
#define FN_COL_DEFAULT_SOFT_SHADOW 255 255 255 255; color3: 0 0 0 18
#define FN_COL_HIGHLIGHT 51 153 255 255; color2: 51 153 255 24; color3: 51 153 255 18
#define FN_COL_HIGHLIGHT_CLICKED 255 255 255 255; color2: 51 153 255 64; color3: 51 153 255 32
#define FN_COL_HIGHLIGHT_DISABLE 51 153 255 64; color2: 51 153 255 16; color3: 51 153 255 8
#define FN_COL_MID_GREY 128 128 128 255
#define FN_COL_DISABLE 21 21 21 255; color3: 255 255 255 25;
#define FN_COL_DISABLE_SHADOW 21 21 21 255; color3: 255 255 255 192
#define FN_COL_TRANSPARENT 255 255 255 0; color3: 0 0 0 0
#define FN_COL_WHITE_GLOW 255 255 255 255; color2: 255 255 255 24; color3: 255 255 255 18
/* e/module/conf_colors/preview/text */
#define FN_COL_SHADOW 255 255 255 32
#define FN_COL_OUTLINE_SHADOW 255 255 255 255; color2: 255 255 255 255; color3: 255 255 255 255
/* temperature.edc */
#define FN_COL_SHADOW_BOTTOM 255 255 255 0; color2: 0 0 0 255; color3: 0 0 0 0
/* elm/diskselector */
#define FN_COL_WHITE 255 255 255 255
#define FN_COL_GREY_152 152 152 152 255
#define FN_COL_GREY_172 172 172 172 255
/* elm/flipselector */
#define FN_COL_GREY_192 192 192 192 255; color3: 0 0 0 128
/* TBD: This could probably just be disabled */
#define FN_COL_GREY_16 16 16 16 255; color3: 255 255 255 25
/* elm/various */
/* TBD: should this just be the normal disabled */
#define FN_COL_DISABLE_LIGHTER_SHADOW 21 21 21 255; color3: 255 255 255 15
/* xkbswitch.edc */
#define FN_COL_OUTLINE_TRANSPARENT 255 255 255 0; color2: 0 0 0 0; color3: 0 0 0 0;
#define FN_COL_OUTLINE_DEFAULT 255 255 255 255; color2: 0 0 0 128; color3: 0 0 0 24;
#define ENABLED_TEXTBLOCK_TAGS \
tag: "em" "+ font_style=Oblique"; \
tag: "hilight" "+ font_weight=Bold style=glow glow_color=#3399ff80"; \
tag: "link" "+ color=#3399ff underline=on underline_color=#3399ff"; \
tag: "preedit" "+ underline=on underline_color=#3399ff"; \
tag: "preedit_sel" "+ backing=on backing_color=#000000 color=#ffffff"; \
tag: "title" "+ font_size=26"; \
tag: "subtitle" "+ font_size=18"; \
tag: "bigger" "+ font_size=12"; \
tag: "big" "+ font_size=11"; \
tag: "small" "+ font_size=8"; \
tag: "smaller" "+ font_size=7"; \
tag: "name" "+ color=#888888 font_weight=Bold"; \
tag: "val" "+ color=#ffffff"; \
tag: "info" "+ color=#3399ff style=glow glow_color=#3399ff30"; \
tag: "success" "+ color=#00ff00 style=glow glow_color=#00ff0030"; \
tag: "warning" "+ color=#ff7c00 style=glow glow_color=#ff7c0030"; \
tag: "failure" "+ color=#ff0000 style=glow glow_color=#ff000030"; \
tag: "code" "+ font=Mono style=plain color=#ffffff"; \
tag: "comment" "+ color=#00B000"; \
tag: "string" "+ color=#ff3a35"; \
tag: "number" "+ color=#D4D42A font_weight=Bold"; \
tag: "brace" "+ color=#656565"; \
tag: "type" "+ color=#3399ff"; \
tag: "class" "+ color=#72AAD4 font_weight=Bold"; \
tag: "function" "+ color=#72AAD4 font_weight=Bold"; \
tag: "param" "+ color=#ffffff"; \
tag: "keyword" "+ color=#ff9900 font_weight=Bold"; \
tag: "preprocessor" "+ color=#3399ff font_weight=Bold"; \
tag: "line_added" "+ color=#00B000"; \
tag: "line_removed" "+ color=#ff3a35"; \
tag: "line_changed" "+ color=#ff9900";
#define DISABLED_TEXTBLOCK_TAGS \
tag: "em" "+ font_style=Oblique"; \
tag: "hilight" "+ font_weight=Bold style=glow glow_color=#3399ff20"; \
tag: "link" "+ color=#101820 shadow_color=#66aaff28 underline=on underline_color=#101820"; \
tag: "preedit" "+ underline=on underline_color=#3399ff88"; \
tag: "preedit_sel" "+ backing=on backing_color=#000000 color=#888888"; \
tag: "title" "+ font_size=26"; \
tag: "subtitle" "+ font_size=18"; \
tag: "bigger" "+ font_size=12"; \
tag: "big" "+ font_size=11"; \
tag: "small" "+ font_size=8"; \
tag: "smaller" "+ font_size=7"; \
tag: "name" "+ color=#151515 font_weight=Bold"; \
tag: "val" "+ color=#151515"; \
tag: "info" "+ color=#3399ff60 style=glow glow_color=#3399ff18"; \
tag: "success" "+ color=#00ff0060 style=glow glow_color=#00ff0018"; \
tag: "warning" "+ color=#ff7c0060 style=glow glow_color=#ff7c0018"; \
tag: "failure" "+ color=#ff000060 style=glow glow_color=#ff000018"; \
tag: "code" "+ style=shadow,bottom shadow_color=#ffffff19 font=Mono color=#151515"; \
tag: "comment" "+ color=#002800"; \
tag: "string" "+ color=#300504"; \
tag: "number" "+ color=#202008 font_weight=Bold"; \
tag: "brace" "+ color=#000000"; \
tag: "type" "+ color=#101820"; \
tag: "class" "+ color=#121c20 font_weight=Bold"; \
tag: "function" "+ color=#121c20 font_weight=Bold"; \
tag: "param" "+ color=#151515"; \
tag: "keyword" "+ color=#201200 font_weight=Bold"; \
tag: "preprocessor" "+ color=#101820 font_weight=Bold"; \
tag: "line_added" "+ color=#002800"; \
tag: "line_removed" "+ color=#300504"; \
tag: "line_changed" "+ color=#201200";

View File

@ -1,529 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SYSINFO_H
# include <sys/sysinfo.h>
#endif
#ifndef EFL_EO_API_SUPPORT
#define EFL_EO_API_SUPPORT
#endif
#include <Eina.h>
#include <Eo.h>
#include <Evas.h>
#include <Ecore.h>
#include <Ecore_File.h>
#include <Ecore_Getopt.h>
#include <Ecore_Con.h>
#include <Elementary.h>
#include <Exactness.h>
#include <exactness_private.h>
#define MAX_PATH 1024
#define STABILIZE_KEY_STR "F1"
#define SHOT_KEY_STR "F2"
#define SAVE_KEY_STR "F3"
static Evas *(*_evas_new)(void) = NULL;
static const char *_out_filename = NULL;
static const char *_test_name = NULL;
static int _verbose = 0;
static Eina_List *_evas_list = NULL;
static unsigned int _last_evas_id = 0;
static Exactness_Unit *_unit = NULL;
static char *_shot_key = NULL;
static unsigned int _last_timestamp = 0.0;
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 Exactness_Action_Type
_event_pointer_type_get(Efl_Pointer_Action t)
{
switch(t)
{
case EFL_POINTER_ACTION_IN: return EXACTNESS_ACTION_MOUSE_IN;
case EFL_POINTER_ACTION_OUT: return EXACTNESS_ACTION_MOUSE_OUT;
case EFL_POINTER_ACTION_DOWN: return EXACTNESS_ACTION_MULTI_DOWN;
case EFL_POINTER_ACTION_UP: return EXACTNESS_ACTION_MULTI_UP;
case EFL_POINTER_ACTION_MOVE: return EXACTNESS_ACTION_MULTI_MOVE;
case EFL_POINTER_ACTION_WHEEL: return EXACTNESS_ACTION_MOUSE_WHEEL;
default: return EXACTNESS_ACTION_UNKNOWN;
}
}
static void
_output_write()
{
if (_unit) exactness_unit_file_write(_unit, _out_filename);
}
static void
_add_to_list(Exactness_Action_Type type, unsigned int n_evas, unsigned int timestamp, void *data, int len)
{
if (_unit)
{
const Exactness_Action *prev_v = eina_list_last_data_get(_unit->actions);
if (prev_v)
{
if (prev_v->type == type &&
timestamp == _last_timestamp &&
prev_v->n_evas == n_evas &&
(!len || !memcmp(prev_v->data, data, len))) return;
}
_printf(1, "Recording %s\n", _exactness_action_type_to_string_get(type));
Exactness_Action *act = malloc(sizeof(*act));
act->type = type;
act->n_evas = n_evas;
act->delay_ms = timestamp - _last_timestamp;
_last_timestamp = timestamp;
if (len)
{
act->data = malloc(len);
memcpy(act->data, data, len);
}
_unit->actions = eina_list_append(_unit->actions, act);
}
}
static int
_evas_id_get(Evas *e)
{
return (intptr_t)efl_key_data_get(e, "__evas_id");
}
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_id_get(eo_e);
Efl_Pointer_Action action = efl_input_pointer_action_get(evp);
Exactness_Action_Type evt = _event_pointer_type_get(action);
if (!timestamp) return;
_printf(2, "Calling \"%s\" timestamp=<%u>\n", _exactness_action_type_to_string_get(evt), timestamp);
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_touch_id_get(evp);
Eina_Position2D pos = efl_input_pointer_position_get(evp);
Exactness_Action_Multi_Move t = { tool, pos.x, pos.y, rad, radx, rady, pres, ang, fx, fy };
if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(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_touch_id_get(evp);
Eina_Position2D pos = efl_input_pointer_position_get(evp);
Efl_Pointer_Flags flags = efl_input_pointer_button_flags_get(evp);
Exactness_Action_Multi_Event t = { tool, b, pos.x, pos.y, rad, radx, rady, pres, ang,
fx, fy, flags };
if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(t));
break;
}
case EFL_POINTER_ACTION_IN: case EFL_POINTER_ACTION_OUT:
{
if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, NULL, 0);
break;
}
case EFL_POINTER_ACTION_WHEEL:
{
Eina_Bool horiz = efl_input_pointer_wheel_horizontal_get(evp);
int z = efl_input_pointer_wheel_delta_get(evp);
Exactness_Action_Mouse_Wheel t = { horiz, z };
if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(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);
unsigned int n_evas = _evas_id_get(eo_e);
Exactness_Action_Type evt = EXACTNESS_ACTION_KEY_UP;
if (efl_input_key_pressed_get(evk))
{
if (!strcmp(key, _shot_key))
{
_printf(2, "Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp);
_add_to_list(EXACTNESS_ACTION_TAKE_SHOT, n_evas, timestamp, NULL, 0);
return;
}
if (!strcmp(key, STABILIZE_KEY_STR))
{
_printf(2, "Stabilize: %s timestamp=<%u>\n", __func__, timestamp);
_add_to_list(EXACTNESS_ACTION_STABILIZE, n_evas, timestamp, NULL, 0);
return;
}
if (!strcmp(key, SAVE_KEY_STR))
{
_output_write();
_printf(2, "Save events: %s timestamp=<%u>\n", __func__, timestamp);
return;
}
evt = EXACTNESS_ACTION_KEY_DOWN;
}
else
{
if (!strcmp(key, _shot_key) || !strcmp(key, SAVE_KEY_STR) || !strcmp(key, STABILIZE_KEY_STR)) return;
}
if (_unit)
{ /* Construct duplicate strings, free them when list if freed */
Exactness_Action_Key_Down_Up t;
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_string_get(evk));
t.keycode = efl_input_key_code_get(evk);
_add_to_list(evt, n_evas, timestamp, &t, sizeof(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 }
)
static Evas *
_my_evas_new(int w EINA_UNUSED, int h EINA_UNUSED)
{
Evas *e;
if (!_evas_new) return NULL;
e = _evas_new();
if (e)
{
_printf(1, "New Evas\n");
_evas_list = eina_list_append(_evas_list, e);
efl_key_data_set(e, "__evas_id", (void *)(intptr_t)_last_evas_id++);
efl_event_callback_array_add(e, _event_pointer_callbacks(), e);
}
return e;
}
static int
_prg_invoke(const char *full_path, int argc, char **argv)
{
Eina_Value *ret__;
int real__;
void (*efl_main)(void *data, const Efl_Event *ev);
int (*elm_main)(int argc, char **argv);
int (*c_main)(int argc, char **argv);
Eina_Module *h = eina_module_new(full_path);
if (!h || !eina_module_load(h))
{
fprintf(stderr, "Failed loading %s.\n", full_path);
if (h) eina_module_free(h);
return EINA_FALSE;
}
efl_main = eina_module_symbol_get(h, "efl_main");
elm_main = eina_module_symbol_get(h, "elm_main");
c_main = eina_module_symbol_get(h, "main");
_evas_new = eina_module_symbol_get(h, "evas_new");
if (!_evas_new)
{
fprintf(stderr, "Failed loading symbol 'evas_new' from %s.\n", full_path);
eina_module_free(h);
return 1;
}
if (efl_main)
{
elm_init(argc, argv);
efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
ret__ = efl_loop_begin(efl_main_loop_get());
real__ = efl_loop_exit_code_process(ret__);
elm_shutdown();
}
else if (elm_main)
{
elm_init(argc, argv);
real__ = elm_main(argc, argv);
elm_shutdown();
}
else if (c_main)
{
real__ = c_main(argc, argv);
}
else
{
fprintf(stderr, "Failed loading symbol 'efl_main', 'elm_main' or 'main' from %s.\n", full_path);
eina_module_free(h);
real__ = 1;
}
return real__;
}
static Eina_Stringshare *
_prg_full_path_guess(const char *prg)
{
char full_path[MAX_PATH];
if (strchr(prg, '/')) return eina_stringshare_add(prg);
char *paths = strdup(getenv("PATH"));
Eina_Stringshare *ret = NULL;
while (paths && *paths && !ret)
{
char *real_path;
char *colon = strchr(paths, ':');
if (colon) *colon = '\0';
sprintf(full_path, "%s/%s", paths, prg);
real_path = ecore_file_realpath(full_path);
if (*real_path)
{
ret = eina_stringshare_add(real_path);
// check if executable
}
free(real_path);
paths += strlen(paths);
if (colon) paths++;
}
return ret;
}
static Eina_Bool
_mkdir(const char *dir)
{
if (!ecore_file_exists(dir))
{
const char *cur = dir + 1;
do
{
char *slash = strchr(cur, '/');
if (slash) *slash = '\0';
if (!ecore_file_exists(dir) && !ecore_file_mkdir(dir)) return EINA_FALSE;
if (slash) *slash = '/';
if (slash) cur = slash + 1;
else cur = NULL;
}
while (cur);
}
return EINA_TRUE;
}
static const Ecore_Getopt optdesc = {
"exactness_record",
"%prog [options] <-v|-t|-h> [--] command [arg1 arg2 ...]",
PACKAGE_VERSION,
"(C) 2017 Enlightenment",
"BSD",
"A scenario recorder for EFL based applications.\n"
"\tF1 - Request stabilization\n"
"\tF2 - Request shot\n"
"\tF3 - Request to save the scenario\n",
1,
{
ECORE_GETOPT_STORE_STR('t', "test", "Name of the filename where to store the test."),
ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
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)
{
char *dest = NULL, *eq;
char *fonts_dir = NULL;
int pret = 1, opt_args = 0;
Eina_Bool want_quit = EINA_FALSE;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_STR(dest),
ECORE_GETOPT_VALUE_STR(fonts_dir),
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();
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;
/* Check for a sentinel */
if (argv[opt_args] && !strcmp(argv[opt_args], "--")) opt_args++;
/* Check for env variables */
do
{
eq = argv[opt_args] ? strchr(argv[opt_args], '=') : NULL;
if (eq)
{
char *var = malloc(eq - argv[opt_args] + 1);
memcpy(var, argv[opt_args], eq - argv[opt_args]);
var[eq - argv[opt_args]] = '\0';
setenv(var, eq + 1, 1);
opt_args++;
}
} while (eq);
_out_filename = eina_stringshare_add(dest);
if (!_out_filename)
{
fprintf(stderr, "no test file specified\n");
goto end;
}
else
{
char *slash = strrchr(_out_filename, '/');
if (slash) _test_name = strdup(slash + 1);
else _test_name = strdup(_out_filename);
char *dot = strrchr(_test_name, '.');
if (dot) *dot = '\0';
if (slash)
{
*slash = '\0';
if (!_mkdir(_out_filename))
{
fprintf(stderr, "Can't create %s\n", _out_filename);
goto end;
}
*slash = '/';
}
}
if (strcmp(_out_filename + strlen(_out_filename) - 4,".exu"))
{
fprintf(stderr, "A file with a exu extension is required - %s invalid\n", _out_filename);
goto end;
}
if (strcmp(_out_filename + strlen(_out_filename) - 4,".exu"))
{
fprintf(stderr, "A file with a exu extension is required - %s invalid\n", _out_filename);
goto end;
}
if (!argv[opt_args])
{
fprintf(stderr, "no program specified\nUse -h for more information\n");
goto end;
}
efl_object_init();
evas_init();
if (!_unit)
{
_unit = calloc(1, sizeof(*_unit));
}
if (fonts_dir)
{
Eina_Tmpstr *fonts_conf_name = NULL;
if (!ecore_file_exists(fonts_dir))
{
fprintf(stderr, "Unable to find fonts directory %s\n", fonts_dir);
goto end;
}
Eina_List *dated_fonts = ecore_file_ls(fonts_dir);
char *date_dir;
_unit->fonts_path = strdup(eina_list_last_data_get(dated_fonts));
EINA_LIST_FREE(dated_fonts, date_dir) free(date_dir);
if (_unit->fonts_path)
{
int tmp_fd = eina_file_mkstemp("/tmp/fonts_XXXXXX.conf", &fonts_conf_name);
dprintf(tmp_fd,
"<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig>\n"
"<dir prefix=\"default\">%s/%s</dir>\n</fontconfig>\n",
fonts_dir, _unit->fonts_path);
close(tmp_fd);
setenv("FONTCONFIG_FILE", fonts_conf_name, 1);
}
}
/* Replace the current command line to hide the Exactness part */
int len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[opt_args];
memcpy(argv[0], argv[opt_args], len);
memset(argv[0] + len, 0, MAX_PATH - len);
int i;
for (i = opt_args; i < argc; i++)
{
if (i != opt_args)
{
argv[i - opt_args] = argv[0] + (argv[i] - argv[opt_args]);
}
_printf(1, "%s ", argv[i - opt_args]);
}
_printf(1, "\n");
if (!_shot_key) _shot_key = getenv("SHOT_KEY");
if (!_shot_key) _shot_key = SHOT_KEY_STR;
ecore_evas_callback_new_set(_my_evas_new);
_last_timestamp = ecore_time_get() * 1000;
pret = _prg_invoke(_prg_full_path_guess(argv[0]), argc - opt_args, argv);
_output_write();
//free_events(_events_list, EINA_TRUE);
//_events_list = NULL;
pret = 0;
end:
eina_shutdown();
return pret;
}

160
src/bin/run_test.c Normal file
View File

@ -0,0 +1,160 @@
#include <stdio.h>
#include <unistd.h>
#include "config.h"
#include "scheduler.h"
#include "run_test.h"
#include "list_file.h"
#include "exactness_config.h"
#include "md5/md5.h"
#define LIBEXACTNESS_PATH PACKAGE_LIBDIR "/exactness/libexactness.so"
void
run_test_simulation(const List_Entry *ent, char *buf)
{
snprintf(buf, SCHEDULER_CMD_SIZE, "TSUITE_VERBOSE=%d TSUITE_DEST_DIR='%s' TSUITE_FILE_NAME='%s/%s.rec' TSUITE_TEST_NAME='%s' LD_PRELOAD='%s' %s %s",
exactness_config.verbose,
exactness_config.dest_dir,
exactness_config.base_dir, ent->name,
ent->name, LIBEXACTNESS_PATH,
exactness_config.wrap_command,
ent->command);
}
void
run_test_play(const List_Entry *ent, char *buf)
{
snprintf(buf, SCHEDULER_CMD_SIZE, "TSUITE_VERBOSE=%d ELM_ENGINE='buffer' TSUITE_DEST_DIR='%s/" CURRENT_SUBDIR "' TSUITE_FILE_NAME='%s/%s.rec' TSUITE_TEST_NAME='%s' LD_PRELOAD='%s' %s %s",
exactness_config.verbose,
exactness_config.dest_dir,
exactness_config.base_dir, ent->name,
ent->name, LIBEXACTNESS_PATH,
exactness_config.wrap_command,
ent->command);
run_test_prefix_rm(CURRENT_SUBDIR, ent->name);
if (exactness_config.verbose)
{
printf("Running %s\n", ent->name);
}
}
void
run_test_record(const List_Entry *ent, char *buf)
{
snprintf(buf, SCHEDULER_CMD_SIZE, "TSUITE_VERBOSE=%d TSUITE_RECORDING='rec' TSUITE_DEST_DIR='%s' TSUITE_FILE_NAME='%s/%s.rec' TSUITE_TEST_NAME='%s' LD_PRELOAD='%s' %s %s",
exactness_config.verbose,
exactness_config.dest_dir,
exactness_config.base_dir, ent->name,
ent->name, LIBEXACTNESS_PATH,
exactness_config.wrap_command,
ent->command);
}
void
run_test_init(const List_Entry *ent, char *buf)
{
snprintf(buf, SCHEDULER_CMD_SIZE, "TSUITE_VERBOSE=%d ELM_ENGINE='buffer' TSUITE_DEST_DIR='%s/" ORIG_SUBDIR "' TSUITE_FILE_NAME='%s/%s.rec' TSUITE_TEST_NAME='%s' LD_PRELOAD='%s' %s %s",
exactness_config.verbose,
exactness_config.dest_dir,
exactness_config.base_dir, ent->name,
ent->name, LIBEXACTNESS_PATH,
exactness_config.wrap_command,
ent->command);
run_test_prefix_rm(ORIG_SUBDIR, ent->name);
}
static Eina_Bool
_file_md5_get(const char *filename, unsigned char *result)
{
MD5_CTX ctx;
Eina_File *file;
file = eina_file_open(filename, 0);
if (!file)
return EINA_FALSE;
MD5_Init(&ctx);
MD5_Update(&ctx, eina_file_map_all(file, EINA_FILE_SEQUENTIAL), eina_file_size_get(file));
MD5_Final(result, &ctx);
eina_file_close(file);
return EINA_TRUE;
}
#define _MD5_SIZE 16
static Eina_Bool
_md5_is_equal(const char *filename1, const char *filename2)
{
unsigned char res1[_MD5_SIZE], res2[_MD5_SIZE];
if (!_file_md5_get(filename1, res1))
return EINA_FALSE;
if (!_file_md5_get(filename2, res2))
return EINA_FALSE;
return !memcmp(res1, res2, _MD5_SIZE);
}
static void
_compare_list_cb(const char *name, const char *path EINA_UNUSED, void *data)
{
const char *prefix = data;
if (!strncmp(name, prefix, strlen(prefix)))
{
char filename1[EXACTNESS_PATH_MAX], filename2[EXACTNESS_PATH_MAX];
snprintf(filename1, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, CURRENT_SUBDIR, name);
snprintf(filename2, EXACTNESS_PATH_MAX, "%s/%s/%s", exactness_config.dest_dir, ORIG_SUBDIR, name);
if (!_md5_is_equal(filename1, filename2))
{
char buf[EXACTNESS_PATH_MAX];
exactness_ctx.compare_errors =
eina_list_append(exactness_ctx.compare_errors,
strdup(name));
/* FIXME: Clean up. */
snprintf(buf, EXACTNESS_PATH_MAX,
"compare '%s' '%s' '%s/%s/comp_%s'",
filename1, filename2,
exactness_config.dest_dir,
CURRENT_SUBDIR, name);
if (system(buf))
{
fprintf(stderr, "Failed image comparing '%s'\n", name);
}
}
}
}
void
run_test_compare(const List_Entry *ent)
{
char origdir[EXACTNESS_PATH_MAX];
snprintf(origdir, EXACTNESS_PATH_MAX, "%s/%s", exactness_config.dest_dir, ORIG_SUBDIR);
eina_file_dir_list(origdir, 0, _compare_list_cb, ent->name);
}
static void
_prefix_rm_cb(const char *name, const char *path, void *data)
{
const char *prefix = data;
if (!strncmp(name, prefix, strlen(prefix)))
{
char buf[EXACTNESS_PATH_MAX];
snprintf(buf, EXACTNESS_PATH_MAX, "%s/%s", path, name);
if (unlink(buf))
{
printf("Failed deleting '%s/%s': ", path, name);
perror("");
}
}
}
void
run_test_prefix_rm(const char *dir, const char *prefix)
{
eina_file_dir_list(dir, 0, _prefix_rm_cb, (void *) prefix);
}

14
src/bin/run_test.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef RUN_TEST_H
#define RUN_TEST_H
#include "list_file.h"
void run_test_simulation(const List_Entry *ent, char *buf);
void run_test_play(const List_Entry *ent, char *buf);
void run_test_record(const List_Entry *ent, char *buf);
void run_test_init(const List_Entry *ent, char *buf);
void run_test_compare(const List_Entry *ent);
void run_test_prefix_rm(const char *dir, const char *prefix);
#endif

97
src/bin/scheduler.c Normal file
View File

@ -0,0 +1,97 @@
#include <Ecore.h>
#include "scheduler.h"
#include "exactness_config.h"
typedef struct
{
Scheduler_Cb prepare_func;
List_Entry *last;
unsigned short jobs;
} Scheduler_Ctx;
static Ecore_Event_Handler *_job_del_callback_handler = NULL;
static Eina_Bool _job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx);
static Eina_Bool
_job_deleted_cb(void *data, int type EINA_UNUSED, void *event)
{
Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event;
Scheduler_Ctx *ctx = data;
if ((msg->exit_code != 0) || (msg->exit_signal != 0))
{
List_Entry *ent = ecore_exe_data_get(msg->exe);
exactness_ctx.errors = eina_list_append(exactness_ctx.errors, ent);
}
List_Entry *ent2 = ecore_exe_data_get(msg->exe);
fprintf(stderr, "Finished '%s' exit code: '%d'\n", ent2->name, msg->exit_code);
ctx->jobs++;
exactness_ctx.tests_executed++;
if (ctx->last && EINA_INLIST_GET(ctx->last)->next)
{
ctx->last = EINA_INLIST_CONTAINER_GET(
EINA_INLIST_GET(ctx->last)->next, List_Entry);
_job_dispatch(ctx->last, ctx);
}
/* If all jobs are done. */
if (ctx->jobs == exactness_config.jobs)
{
free(ctx);
ecore_main_loop_quit();
return ECORE_CALLBACK_DONE;
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_job_dispatch(List_Entry *ent, Scheduler_Ctx *ctx)
{
char buf[SCHEDULER_CMD_SIZE];
Ecore_Exe *exe;
if (ctx->jobs == 0)
return EINA_FALSE;
ctx->jobs--;
ctx->prepare_func(ent, buf);
if (!_job_del_callback_handler)
{
_job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
_job_deleted_cb, ctx);
}
fprintf(stderr, "Executing '%s'\n", buf);
exe = ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent);
if (!exe)
{
fprintf(stderr, "Failed executing test '%s'\n", ent->name);
}
return EINA_TRUE;
}
void
scheduler_run(Scheduler_Cb prepare_func, List_Entry *list)
{
Scheduler_Ctx *ctx = calloc(1, sizeof(*ctx));
List_Entry *list_itr;
ctx->jobs = exactness_config.jobs;
ctx->prepare_func = prepare_func;
EINA_INLIST_FOREACH(list, list_itr)
{
if (!_job_dispatch(list_itr, ctx))
break;
ctx->last = list_itr;
}
}

12
src/bin/scheduler.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include "list_file.h"
#define SCHEDULER_CMD_SIZE 1024
typedef void (*Scheduler_Cb)(const List_Entry *, char *);
void scheduler_run(Scheduler_Cb prepare_func, List_Entry *list);
#endif

View File

@ -1,268 +0,0 @@
#ifndef _EXACTNESS_H
#define _EXACTNESS_H
#include <Evas.h>
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef EXACTNESS_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! EXACTNESS_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
/**
* @page exactness_main Exactness
*
* @date 2018 (created)
*
* This page describes the public structures and APIs available for Exactness.
*
* @addtogroup Exactness
* @{
*/
/**
* @typedef Exactness_Action_Type
* The type values for an Exactness action.
*/
typedef enum
{
EXACTNESS_ACTION_UNKNOWN = 0,
EXACTNESS_ACTION_MOUSE_IN,
EXACTNESS_ACTION_MOUSE_OUT,
EXACTNESS_ACTION_MOUSE_WHEEL,
EXACTNESS_ACTION_MULTI_DOWN,
EXACTNESS_ACTION_MULTI_UP,
EXACTNESS_ACTION_MULTI_MOVE,
EXACTNESS_ACTION_KEY_DOWN,
EXACTNESS_ACTION_KEY_UP,
EXACTNESS_ACTION_TAKE_SHOT,
EXACTNESS_ACTION_EFL_EVENT,
EXACTNESS_ACTION_CLICK_ON,
EXACTNESS_ACTION_STABILIZE,
EXACTNESS_ACTION_LAST = EXACTNESS_ACTION_STABILIZE
/* Add any supported actions here and update _LAST */
} Exactness_Action_Type;
/**
* @typedef Exactness_Action_Mouse_Wheel
* The type for the Exactness Mouse Wheel action.
*/
typedef struct
{
int direction;
int z;
} Exactness_Action_Mouse_Wheel;
/**
* @typedef Exactness_Action_Key_Down_Up
* The type for the Exactness Key Down Up action.
*/
typedef struct
{
const char *keyname;
const char *key;
const char *string;
const char *compose;
unsigned int keycode;
} Exactness_Action_Key_Down_Up;
/**
* @typedef Exactness_Action_Multi_Event
* The type for the Exactness Multi Event action.
*/
typedef struct
{
int d;
int b; /* In case of simple mouse down/up, corresponds to the button */
int x;
int y;
double rad;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
Evas_Button_Flags flags;
} Exactness_Action_Multi_Event;
/**
* @typedef Exactness_Action_Multi_Move
* The type for the Exactness Multi Move action.
*/
typedef struct
{
int d;
int x;
int y;
double rad;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
} Exactness_Action_Multi_Move;
/**
* @typedef Exactness_Action_Efl_Event
* The type for the Exactness EFL Event action.
*/
typedef struct
{
char *wdg_name;
char *event_name;
} Exactness_Action_Efl_Event;
/**
* @typedef Exactness_Action_Click_On
* The type for the Exactness Click on (widget) action.
*/
typedef struct
{
char *wdg_name;
} Exactness_Action_Click_On;
/**
* @typedef Exactness_Action
* The type for the Exactness action.
*/
typedef struct
{
Exactness_Action_Type type; /**< The action type */
unsigned int n_evas; /**< The evas number on which the action has to be applied */
unsigned int delay_ms; /**< The delay (in ms) to wait for this action */
void *data; /**< The specific action data */
} Exactness_Action;
/**
* @typedef Exactness_Object
* The type for the Exactness object.
*/
typedef struct
{
long long id; /**< The Eo pointer */
long long parent_id; /**< The Eo parent pointer */
const char *kl_name; /**< The class name */
Eina_List *children; /* NOT EET */
/* Evas stuff */
int x; /**< The X coordinate */
int y; /**< The Y coordinate */
int w; /**< The object width */
int h; /**< The object height */
} Exactness_Object;
/**
* @typedef Exactness_Objects
* The type for the Exactness objects list.
*/
typedef struct
{
Eina_List *objs; /**< List of all the objects */
/* main_objs not in EET */
Eina_List *main_objs; /**< List of the main objects */
} Exactness_Objects;
/**
* @typedef Exactness_Image
* The type for the Exactness Image.
*/
typedef struct
{
unsigned int w; /**< Width of the image */
unsigned int h; /**< Height of the image */
void *pixels; /**< Pixels of the image */
} Exactness_Image;
typedef struct
{
char *language; /**< String describing the language of the content e.g "C"...*/
char *content; /**< Content used as source */
char *command; /**< Command needed to generate the application from the content */
} Exactness_Source_Code;
typedef struct
{
Eina_List *actions; /**< List of Exactness_Action */
/* imgs not in EET */
Eina_List *imgs; /**< List of Exactness_Image */
Eina_List *objs; /**< List of Exactness_Objects */
Eina_List *codes; /**< List of Exactness_Source_Code */
const char *fonts_path; /**< Path to the fonts to use, relative to the fonts dir given in parameter to the player/recorder */
int nb_shots; /**< The number of shots present in the unit */
} Exactness_Unit;
/**
* @brief Read an unit from a given file
*
* @param filename Name of the file containing the unit
*
* @return the unit
*/
EAPI Exactness_Unit *exactness_unit_file_read(const char *filename);
/**
* @brief Write an unit into the given file
*
* @param unit Unit to store
* @param filename Name of the file containing the unit
*
* @return EINA_TRUE on success, EINA_FALSE otherwise
*/
EAPI Eina_Bool exactness_unit_file_write(Exactness_Unit *unit, const char *filename);
/**
* @brief Compare two images
*
* @param img1 first image
* @param img2 second image
* @param imgO pointer for the diff image. Can be NULL
*
* @return EINA_TRUE if the images are different, EINA_FALSE otherwise
*/
EAPI Eina_Bool exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **imgO);
/**
* @brief Free the given image
*
* @param img the image
*
*/
EAPI void exactness_image_free(Exactness_Image *img);
/**
* @brief Read a legacy file and convert it to an unit
*
* @param filename Name of the legacy file
*
* @return the unit
*/
EAPI Exactness_Unit *legacy_rec_file_read(const char *filename);
/**
* @}
*/
#endif /* _EXACTNESS_H */

View File

@ -1,20 +1,23 @@
MAINTAINERCLEANFILES = Makefile.in
other_includedir = $(includedir)/exactness
other_include_HEADERS = Exactness.h
AM_CPPFLAGS = \
-I$(top_srcdir)/src/bin \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EFL_CFLAGS@ \
-DEXACTNESS_BUILD
@EFL_CFLAGS@
pkgdir = $(libdir)
EXTRA_DIST = \
tsuite_file_data.h
pkgdir = $(libdir)/exactness
pkg_LTLIBRARIES = libexactness.la
libexactness_la_SOURCES = unit.c legacy_file.c exactness_private.h
libexactness_la_LDFLAGS = -fPIC -rdynamic -no-undefined
libexactness_la_SOURCES = \
tsuite_evas_hook.c \
tsuite_file_data.c
libexactness_la_LDFLAGS = -module -avoid-version -rdynamic
libexactness_la_DEPENDENCIES = $(top_builddir)/config.h
libexactness_la_LIBADD = @EFL_LIBS@
libexactness_la_CFLAGS = @EFL_CFLAGS@

View File

@ -1,10 +0,0 @@
#ifndef _EXACTNESS_PRIVATE_H
#define _EXACTNESS_PRIVATE_H
#include <Exactness.h>
/* private header */
EAPI const char *_exactness_action_type_to_string_get(Exactness_Action_Type type);
#define SHOT_DELIMITER '+'
#endif

View File

@ -1,880 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <Eina.h>
#include <Eet.h>
#include <Evas.h>
#include "Exactness.h"
#define CACHE_FILE_ENTRY "cache"
enum _Tsuite_Event_Type
{ /* Add any supported events here */
TSUITE_EVENT_NOT_SUPPORTED = 0,
TSUITE_EVENT_MOUSE_IN,
TSUITE_EVENT_MOUSE_OUT,
TSUITE_EVENT_MOUSE_DOWN,
TSUITE_EVENT_MOUSE_UP,
TSUITE_EVENT_MOUSE_MOVE,
TSUITE_EVENT_MOUSE_WHEEL,
TSUITE_EVENT_MULTI_DOWN,
TSUITE_EVENT_MULTI_UP,
TSUITE_EVENT_MULTI_MOVE,
TSUITE_EVENT_KEY_DOWN,
TSUITE_EVENT_KEY_UP,
TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE,
TSUITE_EVENT_KEY_UP_WITH_KEYCODE,
TSUITE_EVENT_TAKE_SHOT
};
typedef enum _Tsuite_Event_Type Tsuite_Event_Type;
struct _eet_event_type_mapping
{
Tsuite_Event_Type t;
const char *name;
};
typedef struct _eet_event_type_mapping eet_event_type_mapping;
struct _Variant_Type_st
{
const char *type;
Eina_Bool unknow : 1;
};
typedef struct _Variant_Type_st Variant_Type_st;
struct _Variant_st
{
Variant_Type_st t;
void *data; /* differently than the union type, we
* don't need to pre-allocate the memory
* for the field*/
};
typedef struct _Variant_st Variant_st;
struct _Timer_Data
{
unsigned int recent_event_time;
Eina_List *current_event;
};
typedef struct _Timer_Data Timer_Data;
struct _Tsuite_Data
{
int serial; /**< Serial number of current-file */
Timer_Data *td;
};
typedef struct _Tsuite_Data Tsuite_Data;
struct _mouse_in_mouse_out
{
unsigned int timestamp;
int n_evas;
};
struct _mouse_down_mouse_up
{
int b;
Evas_Button_Flags flags;
unsigned int timestamp;
int n_evas;
};
struct _mouse_move
{
int x;
int y;
unsigned int timestamp;
int n_evas;
};
struct _mouse_wheel
{
int direction;
int z;
unsigned int timestamp;
int n_evas;
};
struct _key_down_key_up
{
unsigned int timestamp;
const char *keyname;
const char *key;
const char *string;
const char *compose;
int n_evas;
};
struct _key_down_key_up_with_keycode
{
unsigned int timestamp;
const char *keyname;
const char *key;
const char *string;
const char *compose;
int n_evas;
unsigned int 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;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
Evas_Button_Flags flags;
unsigned int timestamp;
int n_evas;
};
struct _multi_move
{
int d;
int x;
int y;
double rad;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
unsigned int timestamp;
int n_evas;
};
typedef struct _mouse_in_mouse_out mouse_in_mouse_out;
typedef struct _mouse_down_mouse_up mouse_down_mouse_up;
typedef struct _mouse_move mouse_move;
typedef struct _mouse_wheel mouse_wheel;
typedef struct _multi_event multi_event;
typedef struct _multi_move multi_move;
typedef struct _key_down_key_up key_down_key_up;
typedef struct _key_down_key_up_with_keycode key_down_key_up_with_keycode;
typedef struct _mouse_in_mouse_out take_screenshot;
/* START - EET support typedefs */
#define TSUITE_EVENT_MOUSE_IN_STR "tsuite_event_mouse_in"
#define TSUITE_EVENT_MOUSE_OUT_STR "tsuite_event_mouse_out"
#define TSUITE_EVENT_MOUSE_DOWN_STR "tsuite_event_mouse_down"
#define TSUITE_EVENT_MOUSE_UP_STR "tsuite_event_mouse_up"
#define TSUITE_EVENT_MOUSE_MOVE_STR "tsuite_event_mouse_move"
#define TSUITE_EVENT_MOUSE_WHEEL_STR "tsuite_event_mouse_wheel"
#define TSUITE_EVENT_MULTI_DOWN_STR "tsuite_event_multi_down"
#define TSUITE_EVENT_MULTI_UP_STR "tsuite_event_multi_up"
#define TSUITE_EVENT_MULTI_MOVE_STR "tsuite_event_multi_move"
#define TSUITE_EVENT_KEY_DOWN_STR "tsuite_event_key_down"
#define TSUITE_EVENT_KEY_UP_STR "tsuite_event_key_up"
#define TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE_STR "tsuite_event_key_down_with_keycode"
#define TSUITE_EVENT_KEY_UP_WITH_KEYCODE_STR "tsuite_event_key_up_with_keycode"
#define TSUITE_EVENT_TAKE_SHOT_STR "tsuite_event_take_shot"
struct _Lists_st
{
Eina_List *variant_list;
unsigned int first_timestamp;
};
typedef struct _Lists_st Lists_st;
struct _data_desc
{
Eet_Data_Descriptor *take_screenshot;
Eet_Data_Descriptor *mouse_in_mouse_out;
Eet_Data_Descriptor *mouse_down_mouse_up;
Eet_Data_Descriptor *mouse_move;
Eet_Data_Descriptor *mouse_wheel;
Eet_Data_Descriptor *multi_event;
Eet_Data_Descriptor *multi_move;
Eet_Data_Descriptor *key_down_key_up;
Eet_Data_Descriptor *key_down_key_up_with_keycode;
/* list, variant EET desc support */
Eet_Data_Descriptor *lists_descriptor;
Eet_Data_Descriptor *variant_descriptor;
Eet_Data_Descriptor *variant_unified_descriptor;
};
typedef struct _data_desc data_desc;
/* END - EET support typedefs */
static data_desc *_desc = NULL; /* this struct holds descs (alloc on init) */
static eet_event_type_mapping eet_mapping[] = {
{ TSUITE_EVENT_MOUSE_IN, TSUITE_EVENT_MOUSE_IN_STR },
{ TSUITE_EVENT_MOUSE_OUT, TSUITE_EVENT_MOUSE_OUT_STR },
{ TSUITE_EVENT_MOUSE_DOWN, TSUITE_EVENT_MOUSE_DOWN_STR },
{ TSUITE_EVENT_MOUSE_UP, TSUITE_EVENT_MOUSE_UP_STR },
{ TSUITE_EVENT_MOUSE_MOVE, TSUITE_EVENT_MOUSE_MOVE_STR },
{ TSUITE_EVENT_MOUSE_WHEEL, TSUITE_EVENT_MOUSE_WHEEL_STR },
{ TSUITE_EVENT_MULTI_DOWN, TSUITE_EVENT_MULTI_DOWN_STR },
{ TSUITE_EVENT_MULTI_UP, TSUITE_EVENT_MULTI_UP_STR },
{ TSUITE_EVENT_MULTI_MOVE, TSUITE_EVENT_MULTI_MOVE_STR },
{ TSUITE_EVENT_KEY_DOWN, TSUITE_EVENT_KEY_DOWN_STR },
{ TSUITE_EVENT_KEY_UP, TSUITE_EVENT_KEY_UP_STR },
{ TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE, TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE_STR },
{ TSUITE_EVENT_KEY_UP_WITH_KEYCODE, TSUITE_EVENT_KEY_UP_WITH_KEYCODE_STR },
{ TSUITE_EVENT_TAKE_SHOT, TSUITE_EVENT_TAKE_SHOT_STR },
{ TSUITE_EVENT_NOT_SUPPORTED, NULL }
};
static Tsuite_Event_Type
_event_mapping_type_get(const char *name)
{
int i;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(name, eet_mapping[i].name) == 0)
return eet_mapping[i].t;
return TSUITE_EVENT_NOT_SUPPORTED;
}
static unsigned int
_evt_time_get(unsigned int tm, Variant_st *v)
{
if (!v) return tm;
switch(_event_mapping_type_get(v->t.type))
{
case TSUITE_EVENT_MOUSE_IN:
{
mouse_in_mouse_out *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_OUT:
{
mouse_in_mouse_out *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_DOWN:
{
mouse_down_mouse_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_UP:
{
mouse_down_mouse_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_MOVE:
{
mouse_move *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_WHEEL:
{
mouse_wheel *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_DOWN:
{
multi_event *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_UP:
{
multi_event *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_MOVE:
{
multi_move *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_DOWN:
{
key_down_key_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_UP:
{
key_down_key_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE:
{
key_down_key_up_with_keycode *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_UP_WITH_KEYCODE:
{
key_down_key_up_with_keycode *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_TAKE_SHOT:
{
take_screenshot *t = v->data;
return t->timestamp;
}
default: /* All non-input events are not handeled */
return tm;
break;
}
}
static Lists_st *
_free_events(Lists_st *st)
{
Variant_st *v;
if (!st) goto end;
EINA_LIST_FREE(st->variant_list, v)
{
free(v->data);
free(v);
}
free(st); /* Allocated when reading data from EET file */
end:
return NULL;
}
static const char *
_variant_type_get(const void *data, Eina_Bool *unknow)
{
const Variant_Type_st *type = data;
int i;
if (unknow)
*unknow = type->unknow;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(type->type, eet_mapping[i].name) == 0)
return eet_mapping[i].name;
if (unknow)
*unknow = EINA_FALSE;
return type->type;
} /* _variant_type_get */
static Eina_Bool
_variant_type_set(const char *type,
void *data,
Eina_Bool unknow)
{
Variant_Type_st *vt = data;
vt->type = type;
vt->unknow = unknow;
return EINA_TRUE;
} /* _variant_type_set */
/* START Event struct descriptors */
static Eet_Data_Descriptor *
_take_screenshot_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, take_screenshot);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, take_screenshot, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, take_screenshot, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_mouse_in_mouse_out_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_in_mouse_out);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_in_mouse_out, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_in_mouse_out, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_mouse_down_mouse_up_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_down_mouse_up);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "b", b, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "flags",
flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_mouse_move_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_move);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "x", x, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "y", y, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_mouse_wheel_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_wheel);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "direction",
direction, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "z", z, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_key_down_key_up_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, key_down_key_up);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "keyname",
keyname, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "key",
key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "string",
string, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "compose",
compose, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_key_down_key_up_with_keycode_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, key_down_key_up_with_keycode);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "keyname",
keyname, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "key",
key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "string",
string, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "compose",
compose, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "n_evas",
n_evas, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up_with_keycode, "keycode",
keycode, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_multi_event_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, multi_event);
_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);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "fy", fy, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "flags", flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "n_evas",
n_evas, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_multi_move_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, multi_move);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "d", d, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "x", x, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "y", y, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "rad", rad, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "fy", fy, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "n_evas",
n_evas, EET_T_INT);
return _d;
}
/* declaring types */
static data_desc *
_data_descriptors_init(void)
{
if (_desc) /* Was allocated */
return _desc;
_desc = calloc(1, sizeof(data_desc));
Eet_Data_Descriptor_Class eddc;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Lists_st);
_desc->lists_descriptor = eet_data_descriptor_file_new(&eddc);
_desc->take_screenshot = _take_screenshot_desc_make();
_desc->mouse_in_mouse_out = _mouse_in_mouse_out_desc_make();
_desc->mouse_down_mouse_up = _mouse_down_mouse_up_desc_make();
_desc->mouse_move = _mouse_move_desc_make();
_desc->mouse_wheel = _mouse_wheel_desc_make();
_desc->multi_event = _multi_event_desc_make();
_desc->multi_move = _multi_move_desc_make();
_desc->key_down_key_up = _key_down_key_up_desc_make();
_desc->key_down_key_up_with_keycode = _key_down_key_up_with_keycode_desc_make();
/* for variant */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Variant_st);
_desc->variant_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _variant_type_get;
eddc.func.type_set = _variant_type_set;
_desc->variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_IN_STR, _desc->mouse_in_mouse_out);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_OUT_STR, _desc->mouse_in_mouse_out);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_DOWN_STR, _desc->mouse_down_mouse_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_UP_STR, _desc->mouse_down_mouse_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_MOVE_STR, _desc->mouse_move);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MOUSE_WHEEL_STR, _desc->mouse_wheel);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MULTI_DOWN_STR, _desc->multi_event);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MULTI_UP_STR, _desc->multi_event);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_MULTI_MOVE_STR, _desc->multi_move);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_KEY_DOWN_STR, _desc->key_down_key_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_KEY_UP_STR, _desc->key_down_key_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE_STR, _desc->key_down_key_up_with_keycode);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_KEY_UP_WITH_KEYCODE_STR, _desc->key_down_key_up_with_keycode);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_desc->variant_unified_descriptor,
TSUITE_EVENT_TAKE_SHOT_STR, _desc->take_screenshot);
EET_DATA_DESCRIPTOR_ADD_VARIANT(_desc->variant_descriptor,
Variant_st, "data", data, t, _desc->variant_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_BASIC(_desc->lists_descriptor,
Lists_st, "first_timestamp", first_timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_LIST(_desc->lists_descriptor,
Lists_st, "variant_list", variant_list, _desc->variant_descriptor);
return _desc;
}
static void
_data_descriptors_shutdown(void)
{
if (_desc)
{
eet_data_descriptor_free(_desc->mouse_in_mouse_out);
eet_data_descriptor_free(_desc->mouse_down_mouse_up);
eet_data_descriptor_free(_desc->mouse_move);
eet_data_descriptor_free(_desc->mouse_wheel);
eet_data_descriptor_free(_desc->multi_event);
eet_data_descriptor_free(_desc->multi_move);
eet_data_descriptor_free(_desc->key_down_key_up);
eet_data_descriptor_free(_desc->key_down_key_up_with_keycode);
eet_data_descriptor_free(_desc->take_screenshot);
eet_data_descriptor_free(_desc->lists_descriptor);
eet_data_descriptor_free(_desc->variant_descriptor);
eet_data_descriptor_free(_desc->variant_unified_descriptor);
free(_desc);
_desc = NULL;
/* FIXME: Should probably only init and shutdown once */
}
}
EAPI Exactness_Unit *
legacy_rec_file_read(const char *filename)
{
Lists_st *vr_list;
Eina_List *itr;
Variant_st *v, *prev_v = NULL;
Exactness_Unit *unit = NULL;
Eet_File *fp = eet_open(filename, EET_FILE_MODE_READ);
if (!fp)
{
printf("Failed to open input file <%s>.\n", filename);
return NULL;
}
/* Read events list */
_data_descriptors_init();
vr_list = eet_data_read(fp, _desc->lists_descriptor, CACHE_FILE_ENTRY);
eet_close(fp);
_data_descriptors_shutdown();
unit = calloc(1, sizeof(*unit));
EINA_LIST_FOREACH(vr_list->variant_list, itr, v)
{
Exactness_Action *act = calloc(1, sizeof(*act));
Tsuite_Event_Type old_type = _event_mapping_type_get(v->t.type);
unsigned int vtm = _evt_time_get(0, v);
if (!vtm) continue;
switch (old_type)
{
case TSUITE_EVENT_MOUSE_IN:
{
mouse_in_mouse_out *d_i = v->data;
act->type = EXACTNESS_ACTION_MOUSE_IN;
act->n_evas = d_i->n_evas;
break;
}
case TSUITE_EVENT_MOUSE_OUT:
{
mouse_in_mouse_out *d_i = v->data;
act->type = EXACTNESS_ACTION_MOUSE_OUT;
act->n_evas = d_i->n_evas;
break;
}
case TSUITE_EVENT_MOUSE_DOWN:
case TSUITE_EVENT_MOUSE_UP:
{
mouse_down_mouse_up *d_i = v->data;
Exactness_Action_Multi_Event *d_o = calloc(1, sizeof(*d_o));
d_o->b = d_i->b;
d_o->flags = d_i->flags;
if (old_type == TSUITE_EVENT_MOUSE_DOWN)
act->type = EXACTNESS_ACTION_MULTI_DOWN;
else
act->type = EXACTNESS_ACTION_MULTI_UP;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_MOUSE_MOVE:
{
mouse_move *d_i = v->data;
Exactness_Action_Multi_Move *d_o = calloc(1, sizeof(*d_o));
d_o->x = d_i->x;
d_o->y = d_i->y;
act->type = EXACTNESS_ACTION_MULTI_MOVE;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_MOUSE_WHEEL:
{
mouse_wheel *d_i = v->data;
Exactness_Action_Mouse_Wheel *d_o = calloc(1, sizeof(*d_o));
d_o->direction = d_i->direction;
d_o->z = d_i->z;
act->type = EXACTNESS_ACTION_MOUSE_WHEEL;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_MULTI_DOWN:
case TSUITE_EVENT_MULTI_UP:
{
multi_event *d_i = v->data;
Exactness_Action_Multi_Event *d_o = calloc(1, sizeof(*d_o));
d_o->d = d_i->d;
d_o->b = d_i->b;
d_o->x = d_i->x;
d_o->y = d_i->y;
d_o->rad = d_i->rad;
d_o->radx = d_i->radx;
d_o->rady = d_i->rady;
d_o->pres = d_i->pres;
d_o->ang = d_i->ang;
d_o->fx = d_i->fx;
d_o->fy = d_i->fy;
d_o->flags = d_i->flags;
if (old_type == TSUITE_EVENT_MULTI_DOWN)
act->type = EXACTNESS_ACTION_MULTI_DOWN;
else
act->type = EXACTNESS_ACTION_MULTI_UP;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_MULTI_MOVE:
{
multi_move *d_i = v->data;
Exactness_Action_Multi_Move *d_o = calloc(1, sizeof(*d_o));
d_o->d = d_i->d;
d_o->x = d_i->x;
d_o->y = d_i->y;
d_o->rad = d_i->rad;
d_o->radx = d_i->radx;
d_o->rady = d_i->rady;
d_o->pres = d_i->pres;
d_o->ang = d_i->ang;
d_o->fx = d_i->fx;
d_o->fy = d_i->fy;
act->type = EXACTNESS_ACTION_MULTI_MOVE;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_KEY_DOWN:
case TSUITE_EVENT_KEY_UP:
{
key_down_key_up *d_i = v->data;
Exactness_Action_Key_Down_Up *d_o = calloc(1, sizeof(*d_o));
d_o->keyname = d_i->keyname;
d_o->key = d_i->key;
d_o->string = d_i->string;
d_o->compose = d_i->compose;
if (old_type == TSUITE_EVENT_KEY_DOWN)
act->type = EXACTNESS_ACTION_KEY_DOWN;
else
act->type = EXACTNESS_ACTION_KEY_UP;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE:
case TSUITE_EVENT_KEY_UP_WITH_KEYCODE:
{
key_down_key_up_with_keycode *d_i = v->data;
Exactness_Action_Key_Down_Up *d_o = calloc(1, sizeof(*d_o));
d_o->keyname = d_i->keyname;
d_o->key = d_i->key;
d_o->string = d_i->string;
d_o->compose = d_i->compose;
d_o->keycode = d_i->keycode;
if (old_type == TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE)
act->type = EXACTNESS_ACTION_KEY_DOWN;
else
act->type = EXACTNESS_ACTION_KEY_UP;
act->n_evas = d_i->n_evas;
act->data = d_o;
break;
}
case TSUITE_EVENT_TAKE_SHOT:
{
take_screenshot *d_i = v->data;
act->type = EXACTNESS_ACTION_TAKE_SHOT;
act->n_evas = d_i->n_evas;
break;
}
default: break;
}
if (!prev_v)
{
if (vr_list->first_timestamp)
act->delay_ms = _evt_time_get(0, v) - vr_list->first_timestamp;
else
act->delay_ms = 0;
}
else
{
if (vtm > _evt_time_get(0, prev_v))
act->delay_ms = vtm - _evt_time_get(0, prev_v);
else act->delay_ms = 0;
}
unit->actions = eina_list_append(unit->actions, act);
prev_v = v;
}
#ifdef DEBUG_TSUITE
printf("%s number of actions in the scenario <%d>\n", __func__, eina_list_count(unit->actions));
#endif
_free_events(vr_list);
return unit;
}

880
src/lib/tsuite_evas_hook.c Normal file
View File

@ -0,0 +1,880 @@
#define _GNU_SOURCE 1
#include <Elementary.h>
#include <Eet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dlfcn.h>
#include "tsuite_file_data.h"
#define TSUITE_MAX_PATH 1024
#define SHOT_KEY_STR "F2"
#define IMAGE_FILENAME_EXT ".png"
/* START - EET Handling code */
struct _Eet_Event_Type
{
unsigned int version;
};
typedef struct _Eet_Event_Type Eet_Event_Type;
/* END - EET Handling code */
struct _evas_hook_setting
{
char *recording;
char *dest_dir;
char *test_name;
char *file_name;
Eina_Bool verbose;
};
typedef struct _evas_hook_setting evas_hook_setting;
static char *shot_key = SHOT_KEY_STR;
static Lists_st *vr_list = NULL;
static evas_hook_setting *_hook_setting = NULL;
static Tsuite_Data ts;
static Eina_List *evas_list = NULL; /* List of Evas pointers */
static void
_tsuite_verbosef(const char *fmt, ...)
{
va_list ap;
if (!_hook_setting->verbose)
return;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
/**
* @internal
*
* This function initiates Tsuite_Data
* @param name defines test-name
* @param Pointer_Event Pointer to PE.
*
* @ingroup Tsuite
*/
static unsigned int
evt_time_get(unsigned int tm, Variant_st *v)
{
switch(tsuite_event_mapping_type_get(v->t.type))
{
case TSUITE_EVENT_MOUSE_IN:
{
mouse_in_mouse_out *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_OUT:
{
mouse_in_mouse_out *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_DOWN:
{
mouse_down_mouse_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_UP:
{
mouse_down_mouse_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_MOVE:
{
mouse_move *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MOUSE_WHEEL:
{
mouse_wheel *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_DOWN:
{
multi_event *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_UP:
{
multi_event *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_MULTI_MOVE:
{
multi_move *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_DOWN:
{
key_down_key_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_KEY_UP:
{
key_down_key_up *t = v->data;
return t->timestamp;
}
case TSUITE_EVENT_TAKE_SHOT:
{
take_screenshot *t = v->data;
return t->timestamp;
}
default: /* All non-input events are not handeled */
return tm;
break;
}
}
EAPI void
tsuite_evas_hook_init(void)
{ /* Pointer taken from tsuite.c */
shot_key = getenv("TSUITE_SHOT_KEY");
if (!shot_key) shot_key = SHOT_KEY_STR;
if (!vr_list)
vr_list = calloc(1, sizeof(*vr_list));
}
EAPI void
tsuite_evas_hook_reset(void)
{ /* tsuite.c informs us that vr_list is no longer valid */
if (vr_list)
vr_list = free_events(vr_list, _hook_setting->recording);
}
/**
* @internal
*
* This function takes actual shot and saves it in PNG
* @param data Tsuite_Data pointer initiated by user
* @param obj Window pointer
* @param obj name file name. Will use name_+serial if NULL
*
* @ingroup Tsuite
*/
void
tsuite_shot_do(char *name, Evas *e)
{
if (!e)
return;
Ecore_Evas *ee, *ee_orig;
Evas_Object *o;
unsigned int *pixels;
int w, h,dir_name_len = 0;
char *filename;
if (_hook_setting->dest_dir)
dir_name_len = strlen(_hook_setting->dest_dir) + 1; /* includes space of a '/' */
if (name)
{
filename = malloc(strlen(name) + strlen(IMAGE_FILENAME_EXT) +
dir_name_len + 4);
if (_hook_setting->dest_dir)
sprintf(filename, "%s/", _hook_setting->dest_dir);
sprintf(filename + dir_name_len, "%s%s", name, IMAGE_FILENAME_EXT);
}
else
{
filename = malloc(strlen(_hook_setting->test_name) + strlen(IMAGE_FILENAME_EXT) +
dir_name_len + 8); /* also space for serial */
ts.serial++;
if (_hook_setting->dest_dir)
sprintf(filename, "%s/", _hook_setting->dest_dir);
sprintf(filename + dir_name_len, "%s_%d%s", _hook_setting->test_name,
ts.serial, IMAGE_FILENAME_EXT);
}
ee_orig = ecore_evas_ecore_evas_get(e);
ecore_evas_manual_render(ee_orig);
pixels = (void *)ecore_evas_buffer_pixels_get(ee_orig);
if (!pixels) return;
ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h);
if ((w < 1) || (h < 1)) return;
ee = ecore_evas_buffer_new(1, 1);
o = evas_object_image_add(ecore_evas_get(ee));
evas_object_image_alpha_set(o, ecore_evas_alpha_get(ee_orig));
evas_object_image_size_set(o, w, h);
evas_object_image_data_set(o, pixels);
if (!evas_object_image_save(o, filename, NULL, NULL))
{
printf("Cannot save widget to <%s>\n", filename);
}
_tsuite_verbosef("Shot taken (%s).\n", filename);
ecore_evas_free(ee);
free(filename);
}
EAPI int
ecore_init(void)
{
int ret;
int (*_ecore_init)(void) =
dlsym(RTLD_NEXT, "ecore_init");
ret = _ecore_init();
if ((ret == 1) && (!_hook_setting))
{
const char *tmp;
_hook_setting = calloc(1, sizeof(evas_hook_setting));
_hook_setting->recording = getenv("TSUITE_RECORDING");
_hook_setting->dest_dir = getenv("TSUITE_DEST_DIR");
_hook_setting->test_name = getenv("TSUITE_TEST_NAME");
_hook_setting->file_name = getenv("TSUITE_FILE_NAME");
tmp = getenv("TSUITE_VERBOSE");
if (tmp)
_hook_setting->verbose = atoi(tmp);
#ifdef DEBUG_TSUITE
printf("<%s> test_name=<%s>\n", __func__, _hook_setting->test_name);
printf("<%s> dest_dir=<%s>\n", __func__, _hook_setting->dest_dir);
printf("<%s> recording=<%s>\n", __func__, _hook_setting->recording);
printf("<%s> rec file is <%s>\n", __func__, _hook_setting->file_name);
#endif
if (_hook_setting->recording)
tsuite_evas_hook_init();
}
return ret;
}
EAPI int
ecore_shutdown(void)
{
int ret;
int (*_ecore_shutdown)(void) =
dlsym(RTLD_NEXT, "ecore_shutdown");
ret = _ecore_shutdown();
if (ret == 0)
{
if (_hook_setting)
{
if (vr_list && _hook_setting->recording)
write_events(_hook_setting->file_name, vr_list);
tsuite_evas_hook_reset();
free(_hook_setting);
_hook_setting = NULL;
}
if (ts.td)
free(ts.td);
evas_list = eina_list_free(evas_list);
memset(&ts, 0, sizeof(Tsuite_Data));
}
return ret;
}
EAPI Evas_Object *
elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
{
Evas_Object *win;
Evas_Object * (* _elm_win_add) (Evas_Object *, const char *, Elm_Win_Type) =
dlsym(RTLD_NEXT, "elm_win_add");
win = _elm_win_add(parent, name, type);
evas_list = eina_list_append(evas_list, evas_object_evas_get(win));
#ifdef DEBUG_TSUITE
printf("Appended EVAS=<%p> list size=<%d>\n", evas_object_evas_get(win), eina_list_count(evas_list));
#endif
return win;
}
/* We don't use this in the meantime because a new evas
* is allocated at tsuite_shot_do, this changes ts.e
EAPI Evas *
evas_new(void)
{
Evas * (*_evas_new)(void) =
dlsym(RTLD_NEXT, "evas_new");
ts.e = _evas_new();
return ts.e;
}
*/
static Eina_Bool
tsuite_feed_event(void *data)
{
static Ecore_Timer *tmr = NULL;
Timer_Data *td = data;
time_t evt_time;
if (!td)
return ECORE_CALLBACK_CANCEL;
static Evas_Object *rect = NULL;
if (_hook_setting->verbose)
{
if (!rect)
{
rect = evas_object_rectangle_add(eina_list_data_get(evas_list));
evas_object_repeat_events_set(rect, EINA_TRUE);
evas_object_color_set(rect, 255, 0, 0, 255);
evas_object_resize(rect, 15, 15);
evas_object_layer_set(rect, 100);
evas_object_show(rect);
}
}
Variant_st *v = eina_list_data_get(td->current_event);
switch(tsuite_event_mapping_type_get(v->t.type))
{
case TSUITE_EVENT_MOUSE_IN:
{
mouse_in_mouse_out *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Mouse in\n");
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_in timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
evas_event_feed_mouse_in(eina_list_nth(evas_list, t->n_evas),
time(NULL), NULL);
break;
}
case TSUITE_EVENT_MOUSE_OUT:
{
mouse_in_mouse_out *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Mouse out\n");
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_out timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
#endif
evas_event_feed_mouse_out(eina_list_nth(evas_list, t->n_evas),
time(NULL), NULL);
break;
}
case TSUITE_EVENT_MOUSE_DOWN:
{
mouse_down_mouse_up *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Mouse down\n");
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_down timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
evas_event_feed_mouse_down(eina_list_nth(evas_list, t->n_evas),
t->b, t->flags, time(NULL),
NULL);
break;
}
case TSUITE_EVENT_MOUSE_UP:
{
mouse_down_mouse_up *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Mouse up\n");
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_up timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
#endif
evas_event_feed_mouse_up(eina_list_nth(evas_list, t->n_evas),
t->b, t->flags, time(NULL),
NULL);
break;
}
case TSUITE_EVENT_MOUSE_MOVE:
{
mouse_move *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_move (x,y)=(%d,%d) timestamp=<%u> t->n_evas=<%d>\n", __func__, t->x, t->y, t->timestamp,t->n_evas);
#endif
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);
}
break;
}
case TSUITE_EVENT_MOUSE_WHEEL:
{
mouse_wheel *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Mouse wheel\n");
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_mouse_wheel timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
evas_event_feed_mouse_wheel(eina_list_nth(evas_list, t->n_evas),
t->direction, t->z,
time(NULL), NULL);
break;
}
case TSUITE_EVENT_MULTI_DOWN:
{
multi_event *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_multi_down timestamp=<%u>, t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
#endif
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;
}
case TSUITE_EVENT_MULTI_UP:
{
multi_event *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_multi_up timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp,t->n_evas);
#endif
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;
}
case TSUITE_EVENT_MULTI_MOVE:
{
multi_move *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_multi_move timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
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;
}
case TSUITE_EVENT_KEY_DOWN:
{
key_down_key_up *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_key_down timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
evas_event_feed_key_down(eina_list_nth(evas_list, t->n_evas),
t->keyname, t->key, t->string,
t->compose, time(NULL), NULL);
break;
}
case TSUITE_EVENT_KEY_UP:
{
key_down_key_up *t = v->data;
evt_time = t->timestamp;
#ifdef DEBUG_TSUITE
printf("%s evas_event_feed_key_up timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
evas_event_feed_key_up(eina_list_nth(evas_list, t->n_evas),
t->keyname, t->key, t->string,
t->compose, time(NULL), NULL);
break;
}
case TSUITE_EVENT_TAKE_SHOT:
{
take_screenshot *t = v->data;
evt_time = t->timestamp;
_tsuite_verbosef("Shot taken.\n");
#ifdef DEBUG_TSUITE
printf("%s take shot timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas);
#endif
tsuite_shot_do(NULL,
eina_list_nth(evas_list, t->n_evas)); /* Serial name based on test-name */
break;
}
default: /* All non-input events are not handeled */
evt_time = td->recent_event_time;
break;
}
double timer_time;
td->current_event = eina_list_next(td->current_event);
if (!td->current_event)
{ /* Finished reading all events */
elm_exit();
return ECORE_CALLBACK_CANCEL;
}
td->recent_event_time = evt_time;
unsigned int current_event_time = evt_time_get(evt_time, eina_list_data_get(td->current_event));
if (current_event_time < td->recent_event_time) /* Could happen with refeed event */
current_event_time = td->recent_event_time;
#ifdef DEBUG_TSUITE
printf("%s td->recent_event_time=<%u> current_event_time=<%u>\n", __func__, td->recent_event_time, current_event_time);
#endif
timer_time = (current_event_time - td->recent_event_time) / 1000.0;
if (!td->recent_event_time)
timer_time = 0.0;
#ifdef DEBUG_TSUITE
printf("%s timer_time=<%f>\n", __func__, timer_time);
#endif
tmr = ecore_timer_add(timer_time, tsuite_feed_event, td);
return ECORE_CALLBACK_CANCEL;
}
void
ecore_main_loop_begin(void)
{
void (*_ecore_main_loop_begin)(void) =
dlsym(RTLD_NEXT, "ecore_main_loop_begin");
if (!_hook_setting->recording && _hook_setting->file_name)
{
ts.td = calloc(1, sizeof(Timer_Data));
#ifdef DEBUG_TSUITE
printf("<%s> rec file is <%s>\n", __func__, _hook_setting->file_name);
#endif
vr_list = read_events(_hook_setting->file_name, ts.td);
if (ts.td->current_event)
{ /* Got first event in list, run test */
tsuite_feed_event(ts.td);
}
}
return _ecore_main_loop_begin();
}
/* 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) \
{ \
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)
{
switch(t)
{
case EVAS_CALLBACK_MOUSE_IN:
return TSUITE_EVENT_MOUSE_IN;
case EVAS_CALLBACK_MOUSE_OUT:
return TSUITE_EVENT_MOUSE_OUT;
case EVAS_CALLBACK_MOUSE_DOWN:
return TSUITE_EVENT_MOUSE_DOWN;
case EVAS_CALLBACK_MOUSE_UP:
return TSUITE_EVENT_MOUSE_UP;
case EVAS_CALLBACK_MOUSE_MOVE:
return TSUITE_EVENT_MOUSE_MOVE;
case EVAS_CALLBACK_MOUSE_WHEEL:
return TSUITE_EVENT_MOUSE_WHEEL;
case EVAS_CALLBACK_MULTI_DOWN:
return TSUITE_EVENT_MULTI_DOWN;
case EVAS_CALLBACK_MULTI_UP:
return TSUITE_EVENT_MULTI_UP;
case EVAS_CALLBACK_MULTI_MOVE:
return TSUITE_EVENT_MULTI_MOVE;
case EVAS_CALLBACK_KEY_DOWN:
return TSUITE_EVENT_KEY_DOWN;
case EVAS_CALLBACK_KEY_UP:
return TSUITE_EVENT_KEY_UP;
default:
return TSUITE_EVENT_NOT_SUPPORTED;
}
}
EAPI void
evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
mouse_in_mouse_out t = { timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_IN);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_in_mouse_out, t);
void (*orig) (Evas *e, unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, timestamp, data);
}
EAPI void
evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
mouse_in_mouse_out t = { timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_OUT);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_in_mouse_out, t);
void (*orig) (Evas *e, unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, timestamp, data);
}
EAPI void
evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
mouse_down_mouse_up t = { b, flags, timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_DOWN);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_down_mouse_up, t);
void (*orig) (Evas *e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, b, flags, timestamp, data);
}
EAPI void
evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
mouse_down_mouse_up t = { b, flags, timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_UP);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_down_mouse_up, t);
void (*orig) (Evas *e, int b, Evas_Button_Flags flags,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, b, flags, timestamp, data);
}
EAPI void
evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp,
const void *data)
{
mouse_move t = { x, y, timestamp, evas_list_find(e) };
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_MOVE);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_move, t);
void (*orig) (Evas *e, int x, int y, unsigned int timestamp,
const void *data) = dlsym(RTLD_NEXT, __func__);
orig(e, x, y, timestamp, data);
}
EAPI void
evas_event_feed_mouse_wheel(Evas *e, int direction, int z,
unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
mouse_wheel t = { direction, z, timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MOUSE_WHEEL);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, mouse_wheel, t);
void (*orig) (Evas *e, int direction, int z, unsigned int timestamp,
const void *data) = dlsym(RTLD_NEXT, __func__);
orig(e, direction, z, timestamp, data);
}
EAPI void
evas_event_feed_multi_down(Evas *e, int d, int x, int y,
double rad, double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, const void *data)
{
#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) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_DOWN);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, multi_event, t);
void (*orig) (Evas *e, int d, int x, int y, double rad,
double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, d, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, data);
}
EAPI void
evas_event_feed_multi_up(Evas *e, int d, int x, int y,
double rad, double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, const void *data)
{
#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) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_UP);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, multi_event, t);
void (*orig) (Evas *e, int d, int x, int y, double rad,
double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, d, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, data);
}
EAPI void
evas_event_feed_multi_move(Evas *e, int d, int x, int y, double rad,
double radx, double rady, double pres, double ang,
double fx, double fy, unsigned int timestamp, const void *data)
{
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
multi_move t = { d, x, y, rad, radx, rady, pres, ang, fx, fy, timestamp, evas_list_find(e) };
int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_MOVE);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, multi_move, t);
void (*orig) (Evas *e, int d, int x, int y, double rad,
double radx, double rady, double pres, double ang,
double fx, double fy, unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
orig(e, d, x, y, rad, radx, rady, pres, ang, fx, fy, timestamp, data);
}
EAPI void
evas_event_feed_key_down(Evas *e, const char *keyname, const char *key,
const char *string, const char *compose,
unsigned int timestamp, const void *data)
{
int evt = tsuite_event_type_get(EVAS_CALLBACK_KEY_DOWN);
void (*orig) (Evas *e, const char *keyname, const char *key,
const char *string, const char *compose,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
if (!strcmp(key, shot_key))
{
#ifdef DEBUG_TSUITE
printf("Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp);
#endif
take_screenshot t = { timestamp, evas_list_find(e) };
if (t.n_evas >= 0)
ADD_TO_LIST(TSUITE_EVENT_TAKE_SHOT, take_screenshot, t);
orig(e, keyname, key, string, compose, timestamp, data);
return;
}
if (vr_list && _hook_setting->recording)
{ /* Construct duplicate strings, free them when list if freed */
key_down_key_up t;
t.timestamp = timestamp;
t.keyname = eina_stringshare_add(keyname);
t.key = eina_stringshare_add(key);
t.string = eina_stringshare_add(string);
t.compose = eina_stringshare_add(compose);
t.n_evas = evas_list_find(e);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, key_down_key_up, t);
}
orig(e, keyname, key, string, compose, timestamp, data);
}
EAPI void
evas_event_feed_key_up(Evas *e, const char *keyname, const char *key,
const char *string, const char *compose,
unsigned int timestamp, const void *data)
{
void (*orig) (Evas *e, const char *keyname, const char *key,
const char *string, const char *compose,
unsigned int timestamp, const void *data) =
dlsym(RTLD_NEXT, __func__);
if (!strcmp(key, shot_key))
{
#ifdef DEBUG_TSUITE
printf("Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp);
#endif
orig(e, keyname, key, string, compose, timestamp, data);
return; /* Take screenshot done on key-down */
}
int evt = { tsuite_event_type_get(EVAS_CALLBACK_KEY_UP) };
#ifdef DEBUG_TSUITE
printf("Calling %s timestamp=<%u>\n", __func__, timestamp);
#endif
if (vr_list && _hook_setting->recording)
{ /* Construct duplicate strings, free them when list if freed */
key_down_key_up t;
t.timestamp = timestamp;
t.keyname = eina_stringshare_add(keyname);
t.key = eina_stringshare_add(key);
t.string = eina_stringshare_add(string);
t.compose = eina_stringshare_add(compose);
t.n_evas = evas_list_find(e);
if (t.n_evas >= 0)
ADD_TO_LIST(evt, key_down_key_up, t);
}
orig(e, keyname, key, string, compose, timestamp, data);
}

750
src/lib/tsuite_file_data.c Normal file
View File

@ -0,0 +1,750 @@
#include <Eina.h>
#include <Eet.h>
#include <stdio.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <Evas.h>
#include "tsuite_file_data.h"
static data_desc *desc = NULL; /* this struct holds descs (alloc on init) */
static eet_event_type_mapping eet_mapping[] = {
{ TSUITE_EVENT_MOUSE_IN, TSUITE_EVENT_MOUSE_IN_STR },
{ TSUITE_EVENT_MOUSE_OUT, TSUITE_EVENT_MOUSE_OUT_STR },
{ TSUITE_EVENT_MOUSE_DOWN, TSUITE_EVENT_MOUSE_DOWN_STR },
{ TSUITE_EVENT_MOUSE_UP, TSUITE_EVENT_MOUSE_UP_STR },
{ TSUITE_EVENT_MOUSE_MOVE, TSUITE_EVENT_MOUSE_MOVE_STR },
{ TSUITE_EVENT_MOUSE_WHEEL, TSUITE_EVENT_MOUSE_WHEEL_STR },
{ TSUITE_EVENT_MULTI_DOWN, TSUITE_EVENT_MULTI_DOWN_STR },
{ TSUITE_EVENT_MULTI_UP, TSUITE_EVENT_MULTI_UP_STR },
{ TSUITE_EVENT_MULTI_MOVE, TSUITE_EVENT_MULTI_MOVE_STR },
{ TSUITE_EVENT_KEY_DOWN, TSUITE_EVENT_KEY_DOWN_STR },
{ TSUITE_EVENT_KEY_UP, TSUITE_EVENT_KEY_UP_STR },
{ TSUITE_EVENT_TAKE_SHOT, TSUITE_EVENT_TAKE_SHOT_STR },
{ TSUITE_EVENT_NOT_SUPPORTED, NULL }
};
Tsuite_Event_Type
tsuite_event_mapping_type_get(const char *name)
{
int i;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(name, eet_mapping[i].name) == 0)
return eet_mapping[i].t;
return TSUITE_EVENT_NOT_SUPPORTED;
}
const char *
tsuite_event_mapping_type_str_get(Tsuite_Event_Type t)
{
int i;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (t == eet_mapping[i].t)
return eet_mapping[i].name;
return NULL;
}
Lists_st *
free_events(Lists_st *st, char *recording)
{
Variant_st *v;
EINA_LIST_FREE(st->variant_list, v)
{
if (recording)
{
Tsuite_Event_Type e = tsuite_event_mapping_type_get(v->t.type);
if ((e == TSUITE_EVENT_KEY_DOWN) || (e == TSUITE_EVENT_KEY_UP))
{ /* Allocated in tsuite_evas_hook.c */
key_down_key_up *t = v->data;
eina_stringshare_del(t->keyname);
eina_stringshare_del(t->key);
eina_stringshare_del(t->string);
eina_stringshare_del(t->compose);
}
}
free(v->data);
free(v);
}
free(st); /* Allocated when reading data from EET file */
return NULL;
}
#ifdef DEBUG_TSUITE
static void
print_events(Lists_st *vr_list)
{
Eina_List *l;
void *data;
Variant_st *v;
int n = 0;
printf("List size = <%d>\n", eina_list_count(vr_list->variant_list));
EINA_LIST_FOREACH(vr_list->variant_list, l , data)
{
n++;
v = data;
switch(tsuite_event_mapping_type_get(v->t.type))
{
case TSUITE_EVENT_MOUSE_IN:
{
mouse_in_mouse_out *t = v->data;
printf("%d evas_event_feed_mouse_in timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_MOUSE_OUT:
{
mouse_in_mouse_out *t = v->data;
printf("%d evas_event_feed_mouse_out timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp,t->n_evas);
break;
}
case TSUITE_EVENT_MOUSE_DOWN:
{
mouse_down_mouse_up *t = v->data;
printf("%d evas_event_feed_mouse_down timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_MOUSE_UP:
{
mouse_down_mouse_up *t = v->data;
printf("%d evas_event_feed_mouse_up timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp,t->n_evas);
break;
}
case TSUITE_EVENT_MOUSE_MOVE:
{
mouse_move *t = v->data;
printf("%d evas_event_feed_mouse_move (x,y)=(%d,%d) timestamp=<%u> t->n_evas=<%d>\n", n, t->x, t->y, t->timestamp,t->n_evas);
break;
}
case TSUITE_EVENT_MOUSE_WHEEL:
{
mouse_wheel *t = v->data;
printf("%d evas_event_feed_mouse_wheel timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_MULTI_DOWN:
{
multi_event *t = v->data;
printf("%d evas_event_feed_multi_down timestamp=<%u>, t->n_evas=<%d>\n", n, t->timestamp,t->n_evas);
break;
}
case TSUITE_EVENT_MULTI_UP:
{
multi_event *t = v->data;
printf("%d evas_event_feed_multi_up timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp,t->n_evas);
break;
}
case TSUITE_EVENT_MULTI_MOVE:
{
multi_move *t = v->data;
printf("%d evas_event_feed_multi_move timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_KEY_DOWN:
{
key_down_key_up *t = v->data;
printf("%d evas_event_feed_key_down timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_KEY_UP:
{
key_down_key_up *t = v->data;
printf("%d evas_event_feed_key_up timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
case TSUITE_EVENT_TAKE_SHOT:
{
take_screenshot *t = v->data;
printf("%d take shot timestamp=<%u> t->n_evas=<%d>\n", n, t->timestamp, t->n_evas);
break;
}
default: /* All non-input events are not handeled */
printf("%d --- Uknown event ---\n", n);
break;
}
}
}
#endif
void
write_events(const char *filename, Lists_st *vr_list)
{
_data_descriptors_init();
Eet_File *fp = eet_open(filename, EET_FILE_MODE_WRITE);
if (fp)
{
#ifdef DEBUG_TSUITE
print_events(vr_list);
#endif
eet_data_write(fp, desc->_lists_descriptor, CACHE_FILE_ENTRY, vr_list,
EINA_TRUE);
eet_close(fp);
}
else
{
printf("Failed to create record file <%s>.\n", filename);
}
_data_descriptors_shutdown();
}
Lists_st *
read_events(char *filename, Timer_Data *td)
{
Lists_st *vr_list;
td->fp = eet_open(filename, EET_FILE_MODE_READ);
if (!td->fp)
{
printf("Failed to open input file <%s>.\n", filename);
return NULL;
}
/* Read events list */
_data_descriptors_init();
vr_list = eet_data_read(td->fp, desc->_lists_descriptor, CACHE_FILE_ENTRY);
eet_close(td->fp);
_data_descriptors_shutdown();
if (!vr_list->variant_list)
return NULL;
#ifdef DEBUG_TSUITE
print_events(vr_list);
#endif
td->current_event = eina_list_nth_list(vr_list->variant_list, 0);
#ifdef DEBUG_TSUITE
printf("%s list size is <%d>\n", __func__, eina_list_count(vr_list->variant_list));
#endif
return vr_list;
}
const char *
_variant_type_get(const void *data, Eina_Bool *unknow)
{
const Variant_Type_st *type = data;
int i;
if (unknow)
*unknow = type->unknow;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(type->type, eet_mapping[i].name) == 0)
return eet_mapping[i].name;
if (unknow)
*unknow = EINA_FALSE;
return type->type;
} /* _variant_type_get */
Eina_Bool
_variant_type_set(const char *type,
void *data,
Eina_Bool unknow)
{
Variant_Type_st *vt = data;
vt->type = type;
vt->unknow = unknow;
return EINA_TRUE;
} /* _variant_type_set */
/* START - Allocating and setting variant structs */
mouse_in_mouse_out *mouse_in_mouse_out_set(unsigned int timestamp, int n_evas)
{
mouse_in_mouse_out *st = calloc(1, sizeof(mouse_in_mouse_out));
if (st)
{
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *mouse_in_mouse_out_new(Tsuite_Event_Type type,
unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[type].name;
va->data = mouse_in_mouse_out_set(timestamp, n_evas);
return va;
}
mouse_down_mouse_up *mouse_down_mouse_up_set(int b, Evas_Button_Flags flags,
unsigned int timestamp, int n_evas)
{
mouse_down_mouse_up *st = calloc(1, sizeof(mouse_down_mouse_up));
if (st)
{
st->b = b;
st->flags = flags;
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *mouse_down_mouse_up_new(Tsuite_Event_Type type, int b,
Evas_Button_Flags flags, unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[type].name;
va->data = mouse_down_mouse_up_set(b, flags, timestamp, n_evas);
return va;
}
mouse_move *mouse_move_set(int x, int y, unsigned int timestamp, int n_evas)
{
mouse_move *st = calloc(1, sizeof(mouse_move));
if (st)
{
st->x = x;
st->y = y;
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *mouse_move_new(int x, int y, unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[TSUITE_EVENT_MOUSE_MOVE].name;
va->data = mouse_move_set(x, y, timestamp, n_evas);
return va;
}
mouse_wheel *mouse_wheel_set(int direction, int z, unsigned int timestamp,
int n_evas)
{
mouse_wheel *st = calloc(1, sizeof(mouse_wheel));
if (st)
{
st->direction = direction;
st->z = z;
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *mouse_wheel_new(int direction, int z, unsigned int timestamp,
int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[TSUITE_EVENT_MOUSE_WHEEL].name;
va->data = mouse_wheel_set(direction, z, timestamp, n_evas);
return va;
}
multi_event *multi_event_set(int d, int x, int y, double rad,
double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, int n_evas)
{
multi_event *st = calloc(1, sizeof(multi_event));
if (st)
{
st->d = d;
st->x = x;
st->y = y;
st->rad = rad;
st->radx = radx;
st->rady = rady;
st->pres = pres;
st->ang = ang;
st->fx = fx;
st->fy = fy;
st->flags = flags;
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *multi_event_new(Tsuite_Event_Type type, int d, int x, int y,
double rad, double radx, double rady, double pres, double ang,
double fx, double fy, Evas_Button_Flags flags,
unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[type].name;
va->data = multi_event_set(d, x, y, rad, radx, rady, pres, ang, fx, fy,
flags, timestamp, n_evas);
return va;
}
multi_move *multi_move_set(int d, int x, int y, double rad, double radx,
double rady, double pres, double ang, double fx, double fy,
unsigned int timestamp, int n_evas)
{
multi_move *st = calloc(1, sizeof(multi_move));
if (st)
{
st->d = d;
st->x = x;
st->y = y;
st->rad = rad;
st->radx = radx;
st->rady = rady;
st->pres = pres;
st->ang = ang;
st->fx = fx;
st->fy = fy;
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *multi_move_new(int d, int x, int y,
double rad, double radx,double rady, double pres, double ang,
double fx, double fy, unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[TSUITE_EVENT_MULTI_MOVE].name;
va->data = multi_move_set(d, x, y, rad, radx, rady, pres, ang,
fx, fy,timestamp, n_evas);
return va;
}
key_down_key_up *key_down_key_up_set(unsigned int timestamp,
const char *keyname, const char *key, const char *string,
const char *compose, int n_evas)
{
key_down_key_up *st = calloc(1, sizeof(key_down_key_up));
if (st)
{
st->timestamp = timestamp;
st->keyname = keyname;
st->key = key;
st->string = string;
st->compose = compose;
st->n_evas = n_evas;
}
return st;
}
Variant_st *key_down_key_up_new(Tsuite_Event_Type type,
unsigned int timestamp, const char *keyname, const char *key,
const char *string, const char *compose, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[type].name;
va->data = key_down_key_up_set(timestamp, keyname, key, string, compose, n_evas);
return va;
}
take_screenshot *take_screenshot_set(unsigned int timestamp, int n_evas)
{
take_screenshot *st = calloc(1, sizeof(take_screenshot));
if (st)
{
st->timestamp = timestamp;
st->n_evas = n_evas;
}
return st;
}
Variant_st *take_screenshot_new(unsigned int timestamp, int n_evas)
{
Variant_st *va = calloc(1, sizeof(Variant_st));
va->t.type = eet_mapping[TSUITE_EVENT_TAKE_SHOT].name;
va->data = take_screenshot_set(timestamp, n_evas);
return va;
}
/* END - Allocating and setting variant structs */
/* START Event struct descriptors */
Eet_Data_Descriptor *
take_screenshot_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, take_screenshot);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, take_screenshot, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, take_screenshot, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
mouse_in_mouse_out_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_in_mouse_out);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_in_mouse_out, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_in_mouse_out, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
mouse_down_mouse_up_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_down_mouse_up);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "b", b, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "flags",
flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_down_mouse_up, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
mouse_move_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_move);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "x", x, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "y", y, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_move, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
mouse_wheel_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, mouse_wheel);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "direction",
direction, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "z", z, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, mouse_wheel, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
key_down_key_up_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, key_down_key_up);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "keyname",
keyname, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "key",
key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "string",
string, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "compose",
compose, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, key_down_key_up, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
multi_event_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, multi_event);
_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, "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);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "fy", fy, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "flags", flags, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_event, "n_evas",
n_evas, EET_T_INT);
return _d;
}
Eet_Data_Descriptor *
multi_move_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, multi_move);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "d", d, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "x", x, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "y", y, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "rad", rad, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "fy", fy, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "timestamp",
timestamp, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, multi_move, "n_evas",
n_evas, EET_T_INT);
return _d;
}
/* declaring types */
data_desc *_data_descriptors_init(void)
{
if (desc) /* Was allocated */
return desc;
desc = calloc(1, sizeof(data_desc));
Eet_Data_Descriptor_Class eddc;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Lists_st);
desc->_lists_descriptor = eet_data_descriptor_file_new(&eddc);
desc->take_screenshot = take_screenshot_desc_make();
desc->mouse_in_mouse_out = mouse_in_mouse_out_desc_make();
desc->mouse_down_mouse_up = mouse_down_mouse_up_desc_make();
desc->mouse_move = mouse_move_desc_make();
desc->mouse_wheel = mouse_wheel_desc_make();
desc->multi_event = multi_event_desc_make();
desc->multi_move = multi_move_desc_make();
desc->key_down_key_up = key_down_key_up_desc_make();
/* for variant */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Variant_st);
desc->_variant_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _variant_type_get;
eddc.func.type_set = _variant_type_set;
desc->_variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_IN_STR, desc->mouse_in_mouse_out);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_OUT_STR, desc->mouse_in_mouse_out);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_DOWN_STR, desc->mouse_down_mouse_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_UP_STR, desc->mouse_down_mouse_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_MOVE_STR, desc->mouse_move);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MOUSE_WHEEL_STR, desc->mouse_wheel);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MULTI_DOWN_STR, desc->multi_event);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MULTI_UP_STR, desc->multi_event);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_MULTI_MOVE_STR, desc->multi_move);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_KEY_DOWN_STR, desc->key_down_key_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_KEY_UP_STR, desc->key_down_key_up);
EET_DATA_DESCRIPTOR_ADD_MAPPING(desc->_variant_unified_descriptor,
TSUITE_EVENT_TAKE_SHOT_STR, desc->take_screenshot);
EET_DATA_DESCRIPTOR_ADD_VARIANT(desc->_variant_descriptor,
Variant_st, "data", data, t, desc->_variant_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_LIST(desc->_lists_descriptor,
Lists_st, "variant_list", variant_list, desc->_variant_descriptor);
return desc;
}
void _data_descriptors_shutdown(void)
{
if (desc)
{
eet_data_descriptor_free(desc->mouse_in_mouse_out);
eet_data_descriptor_free(desc->mouse_down_mouse_up);
eet_data_descriptor_free(desc->mouse_move);
eet_data_descriptor_free(desc->mouse_wheel);
eet_data_descriptor_free(desc->multi_event);
eet_data_descriptor_free(desc->multi_move);
eet_data_descriptor_free(desc->key_down_key_up);
eet_data_descriptor_free(desc->take_screenshot);
eet_data_descriptor_free(desc->_lists_descriptor);
eet_data_descriptor_free(desc->_variant_descriptor);
eet_data_descriptor_free(desc->_variant_unified_descriptor);
free(desc);
desc = NULL;
/* FIXME: Should probably only init and shutdown once */
}
}
/* END Event struct descriptors */

208
src/lib/tsuite_file_data.h Normal file
View File

@ -0,0 +1,208 @@
#ifndef _TSUITE_EVAS_HOOK_H
#define _TSUITE_EVAS_HOOK_H
#define CACHE_FILE_ENTRY "cache"
/* Macro declaring a function argument to be unused */
#define __UNUSED__ __attribute__((unused))
enum _Tsuite_Event_Type
{ /* Add any supported events here */
TSUITE_EVENT_NOT_SUPPORTED = 0,
TSUITE_EVENT_MOUSE_IN,
TSUITE_EVENT_MOUSE_OUT,
TSUITE_EVENT_MOUSE_DOWN,
TSUITE_EVENT_MOUSE_UP,
TSUITE_EVENT_MOUSE_MOVE,
TSUITE_EVENT_MOUSE_WHEEL,
TSUITE_EVENT_MULTI_DOWN,
TSUITE_EVENT_MULTI_UP,
TSUITE_EVENT_MULTI_MOVE,
TSUITE_EVENT_KEY_DOWN,
TSUITE_EVENT_KEY_UP,
TSUITE_EVENT_TAKE_SHOT
};
typedef enum _Tsuite_Event_Type Tsuite_Event_Type;
struct _eet_event_type_mapping
{
Tsuite_Event_Type t;
const char *name;
};
typedef struct _eet_event_type_mapping eet_event_type_mapping;
struct _Variant_Type_st
{
const char *type;
Eina_Bool unknow : 1;
};
typedef struct _Variant_Type_st Variant_Type_st;
struct _Variant_st
{
Variant_Type_st t;
void *data; /* differently than the union type, we
* don't need to pre-allocate the memory
* for the field*/
};
typedef struct _Variant_st Variant_st;
struct _Timer_Data
{
Eet_File *fp;
unsigned int recent_event_time;
Eina_List *current_event;
};
typedef struct _Timer_Data Timer_Data;
struct _Tsuite_Data
{
int serial; /**< Serial number of current-file */
Timer_Data *td;
};
typedef struct _Tsuite_Data Tsuite_Data;
struct _mouse_in_mouse_out
{
unsigned int timestamp;
int n_evas;
};
struct _mouse_down_mouse_up
{
int b;
Evas_Button_Flags flags;
unsigned int timestamp;
int n_evas;
};
struct _mouse_move
{
int x;
int y;
unsigned int timestamp;
int n_evas;
};
struct _mouse_wheel
{
int direction;
int z;
unsigned int timestamp;
int n_evas;
};
struct _key_down_key_up
{
unsigned int timestamp;
const char *keyname;
const char *key;
const char *string;
const char *compose;
int n_evas;
};
struct _multi_event
{
int d;
int x;
int y;
double rad;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
Evas_Button_Flags flags;
unsigned int timestamp;
int n_evas;
};
struct _multi_move
{
int d;
int x;
int y;
double rad;
double radx;
double rady;
double pres;
double ang;
double fx;
double fy;
unsigned int timestamp;
int n_evas;
};
typedef struct _mouse_in_mouse_out mouse_in_mouse_out;
typedef struct _mouse_down_mouse_up mouse_down_mouse_up;
typedef struct _mouse_move mouse_move;
typedef struct _mouse_wheel mouse_wheel;
typedef struct _multi_event multi_event;
typedef struct _multi_move multi_move;
typedef struct _key_down_key_up key_down_key_up;
typedef struct _mouse_in_mouse_out take_screenshot;
/* START - EET support typedefs */
#define TSUITE_EVENT_MOUSE_IN_STR "tsuite_event_mouse_in"
#define TSUITE_EVENT_MOUSE_OUT_STR "tsuite_event_mouse_out"
#define TSUITE_EVENT_MOUSE_DOWN_STR "tsuite_event_mouse_down"
#define TSUITE_EVENT_MOUSE_UP_STR "tsuite_event_mouse_up"
#define TSUITE_EVENT_MOUSE_MOVE_STR "tsuite_event_mouse_move"
#define TSUITE_EVENT_MOUSE_WHEEL_STR "tsuite_event_mouse_wheel"
#define TSUITE_EVENT_MULTI_DOWN_STR "tsuite_event_multi_down"
#define TSUITE_EVENT_MULTI_UP_STR "tsuite_event_multi_up"
#define TSUITE_EVENT_MULTI_MOVE_STR "tsuite_event_multi_move"
#define TSUITE_EVENT_KEY_DOWN_STR "tsuite_event_key_down"
#define TSUITE_EVENT_KEY_UP_STR "tsuite_event_key_up"
#define TSUITE_EVENT_TAKE_SHOT_STR "tsuite_event_take_shot"
struct _Lists_st
{
Eina_List *variant_list;
};
typedef struct _Lists_st Lists_st;
struct _data_desc
{
Eet_Data_Descriptor *take_screenshot;
Eet_Data_Descriptor *mouse_in_mouse_out;
Eet_Data_Descriptor *mouse_down_mouse_up;
Eet_Data_Descriptor *mouse_move;
Eet_Data_Descriptor *mouse_wheel;
Eet_Data_Descriptor *multi_event;
Eet_Data_Descriptor *multi_move;
Eet_Data_Descriptor *key_down_key_up;
/* list, variant EET desc support */
Eet_Data_Descriptor *_lists_descriptor;
Eet_Data_Descriptor *_variant_descriptor;
Eet_Data_Descriptor *_variant_unified_descriptor;
};
typedef struct _data_desc data_desc;
/* END - EET support typedefs */
/* START Event struct descriptors */
Eet_Data_Descriptor *take_screenshot_desc_make(void);
Eet_Data_Descriptor *mouse_in_mouse_out_desc_make(void);
Eet_Data_Descriptor *mouse_down_mouse_up_desc_make(void);
Eet_Data_Descriptor *mouse_move_desc_make(void);
Eet_Data_Descriptor *mouse_wheel_desc_make(void);
Eet_Data_Descriptor *key_down_key_up_desc_make(void);
Eet_Data_Descriptor *multi_event_desc_make(void);
Eet_Data_Descriptor *multi_move_desc_make(void);
data_desc *_data_descriptors_init(void);
void _data_descriptors_shutdown(void);
/* END Event struct descriptors */
Tsuite_Event_Type tsuite_event_mapping_type_get(const char *name);
const char * tsuite_event_mapping_type_str_get(Tsuite_Event_Type t);
const char * _variant_type_get(const void *data, Eina_Bool *unknow);
Eina_Bool _variant_type_set(const char *type, void *data, Eina_Bool unknow);
Lists_st * free_events(Lists_st *st, char *recording);
void write_events(const char *filename, Lists_st *vr_list);
Lists_st *read_events(char *filename, Timer_Data *td);
#endif

View File

@ -1,424 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Eet.h>
#include "Exactness.h"
#include "exactness_private.h"
typedef struct _Dummy
{
} _Dummy;
/*
static Eet_Data_Descriptor *
_mouse_in_out_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Mouse_In_Out);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Mouse_In_Out, "n_evas", n_evas, EET_T_INT);
return _d;
}
*/
static Eet_Data_Descriptor *
_mouse_wheel_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Mouse_Wheel);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Mouse_Wheel, "direction", direction, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Mouse_Wheel, "z", z, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_key_down_up_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Key_Down_Up);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "keyname", keyname, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "key", key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "string", string, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "compose", compose, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "keycode", keycode, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_multi_event_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Multi_Event);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "d", d, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "b", b, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "x", x, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "y", y, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "rad", rad, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "fy", fy, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "flags", flags, EET_T_INT);
return _d;
}
static Eet_Data_Descriptor *
_multi_move_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Multi_Move);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "d", d, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "x", x, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "y", y, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "rad", rad, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "radx", radx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "rady", rady, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "pres", pres, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "ang", ang, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "fx", fx, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "fy", fy, EET_T_DOUBLE);
return _d;
}
static Eet_Data_Descriptor *
_efl_event_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Efl_Event);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Efl_Event, "wdg_name", wdg_name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Efl_Event, "event_name", event_name, EET_T_STRING);
return _d;
}
static Eet_Data_Descriptor *
_click_on_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Click_On);
_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Click_On, "wdg_name", wdg_name, EET_T_STRING);
return _d;
}
static Eet_Data_Descriptor *
_dummy_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *_d;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, _Dummy);
_d = eet_data_descriptor_stream_new(&eddc);
return _d;
}
/* !!! SAME ORDER AS Exactness_Action_Type */
static const char *_mapping[] =
{
"",
"exactness_action_mouse_in",
"exactness_action_mouse_out",
"exactness_action_mouse_wheel",
"exactness_action_multi_down",
"exactness_action_multi_up",
"exactness_action_multi_move",
"exactness_action_key_down",
"exactness_action_key_up",
"exactness_action_take_shot",
"exactness_action_efl_event",
"exactness_action_click_on",
"exactness_action_stabilize"
};
const char *
_exactness_action_type_to_string_get(Exactness_Action_Type type)
{
if (type <= EXACTNESS_ACTION_LAST) return _mapping[type];
return NULL;
}
static const char *
_variant_type_get(const void *data, Eina_Bool *unknow)
{
const Exactness_Action *act = data;
if (unknow) *unknow = EINA_FALSE;
if (act->type <= EXACTNESS_ACTION_LAST) return _mapping[act->type];
return NULL;
}
static Eina_Bool
_variant_type_set(const char *type,
void *data,
Eina_Bool unknow EINA_UNUSED)
{
int i;
Exactness_Action *act = data;
for (i = 0; i <= EXACTNESS_ACTION_LAST; i++)
{
if (!strcmp(_mapping[i], type)) act->type = i;
}
return EINA_TRUE;
}
static Eet_Data_Descriptor *
_unit_desc_make(void)
{
Eet_Data_Descriptor_Class eddc;
static Eet_Data_Descriptor *unit_d = NULL;
static Eet_Data_Descriptor *action_d = NULL, *action_variant_d = NULL;
static Eet_Data_Descriptor *objs_d = NULL;
static Eet_Data_Descriptor *obj_d = NULL;
if (!obj_d)
{
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Object);
obj_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "kl_name", kl_name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "id", id, EET_T_ULONG_LONG);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "parent_id", parent_id, EET_T_ULONG_LONG);
/* Evas stuff */
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "x", x, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "y", y, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "w", w, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "h", h, EET_T_INT);
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Objects);
objs_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_LIST(objs_d, Exactness_Objects, "objs", objs, obj_d);
}
if (!unit_d)
{
Eet_Data_Descriptor *code_d = NULL;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Source_Code);
code_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(code_d, Exactness_Source_Code, "language", language, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(code_d, Exactness_Source_Code, "content", content, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(code_d, Exactness_Source_Code, "command", command, EET_T_STRING);
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action);
action_d = eet_data_descriptor_stream_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _variant_type_get;
eddc.func.type_set = _variant_type_set;
action_variant_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MOUSE_IN], _dummy_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MOUSE_OUT], _dummy_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MOUSE_WHEEL], _mouse_wheel_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MULTI_DOWN], _multi_event_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MULTI_UP], _multi_event_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_MULTI_MOVE], _multi_move_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_KEY_DOWN], _key_down_up_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_KEY_UP], _key_down_up_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_TAKE_SHOT], _dummy_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_EFL_EVENT], _efl_event_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_CLICK_ON], _click_on_desc_make());
EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
_mapping[EXACTNESS_ACTION_STABILIZE], _dummy_desc_make());
EET_DATA_DESCRIPTOR_ADD_BASIC(action_d, Exactness_Action, "n_evas", n_evas, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_BASIC(action_d, Exactness_Action, "delay_ms", delay_ms, EET_T_UINT);
EET_DATA_DESCRIPTOR_ADD_VARIANT(action_d, Exactness_Action, "data", data, type, action_variant_d);
/* Exactness_Unit */
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Unit);
unit_d = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "actions", actions, action_d);
EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "objs", objs, objs_d);
EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "codes", codes, code_d);
EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "fonts_path", fonts_path, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "nb_shots", nb_shots, EET_T_UINT);
}
return unit_d;
}
/* END Event struct descriptors */
EAPI Exactness_Unit *
exactness_unit_file_read(const char *filename)
{
int i;
Eina_List *itr, *itr2;
Exactness_Objects *e_objs;
Exactness_Object *e_obj, *e_parent;
Exactness_Unit *unit = NULL;
Eet_File *file;
eet_init();
file = eet_open(filename, EET_FILE_MODE_READ);
if (!file)
{
fprintf(stderr, "Impossible to extract EET from %s\n", filename);
return NULL;
}
unit = eet_data_read(file, _unit_desc_make(), "cache");
for (i = 0; i < unit->nb_shots; i++)
{
char entry[32];
Exactness_Image *ex_img = malloc(sizeof(*ex_img));
sprintf(entry, "images/%d", i + 1);
ex_img->pixels = eet_data_image_read(file, entry,
&ex_img->w, &ex_img->h, NULL,
NULL, NULL, NULL);
unit->imgs = eina_list_append(unit->imgs, ex_img);
}
EINA_LIST_FOREACH(unit->objs, itr, e_objs)
{
Eina_Hash *hash = eina_hash_pointer_new(NULL);
EINA_LIST_FOREACH(e_objs->objs, itr2, e_obj)
{
eina_hash_set(hash, &(e_obj->id), e_obj);
}
EINA_LIST_FOREACH(e_objs->objs, itr2, e_obj)
{
if (!e_obj->parent_id)
e_objs->main_objs = eina_list_append(e_objs->main_objs, e_obj);
else
{
e_parent = eina_hash_find(hash, &(e_obj->parent_id));
if (e_parent) e_parent->children = eina_list_append(e_parent->children, e_obj);
}
}
eina_hash_free(hash);
}
eet_close(file);
eet_shutdown();
return unit;
}
EAPI Eina_Bool
exactness_unit_file_write(Exactness_Unit *unit, const char *filename)
{
Eina_List *itr;
Exactness_Image *ex_img;
Eet_File *file;
int i = 1;
eet_init();
file = eet_open(filename, EET_FILE_MODE_WRITE);
eet_data_write(file, _unit_desc_make(), "cache", unit, EINA_TRUE);
EINA_LIST_FOREACH(unit->imgs, itr, ex_img)
{
char entry[32];
sprintf(entry, "images/%d", i++);
eet_data_image_write(file, entry,
ex_img->pixels, ex_img->w, ex_img->h, 0xFF,
9, 100, EET_IMAGE_LOSSLESS);
}
eet_close(file);
eet_shutdown();
return EINA_TRUE;
}
EAPI Eina_Bool
exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **imgO)
{
unsigned int w, h;
int *pxs1, *pxs2, *pxsO = NULL;
unsigned int w1 = img1 ? img1->w : 0, h1 = img1 ? img1->h : 0;
unsigned int w2 = img2 ? img2->w : 0, h2 = img2 ? img2->h : 0;
unsigned int wO = MAX(w1, w2);
unsigned int hO = MAX(h1, h2);
Eina_Bool ret = EINA_FALSE;
if (imgO) *imgO = NULL;
if (!wO || !hO) return EINA_FALSE;
pxs1 = img1 ? img1->pixels : NULL;
pxs2 = img2 ? img2->pixels : NULL;
if (imgO) pxsO = malloc(wO * hO * 4);
for (w = 0; w < wO; w++)
{
for (h = 0; h < hO; h++)
{
Eina_Bool valid1 = img1 ? w < w1 && h < h1 : EINA_FALSE;
Eina_Bool valid2 = img2 ? w < w2 && h < h2 : EINA_FALSE;
int px1 = valid1 ? pxs1[h * w1 + w] : 0;
int px2 = valid2 ? pxs2[h * w2 + w] : 0;
int r1 = (px1 & 0x00FF0000) >> 16;
int r2 = (px2 & 0x00FF0000) >> 16;
int g1 = (px1 & 0x0000FF00) >> 8;
int g2 = (px2 & 0x0000FF00) >> 8;
int b1 = (px1 & 0x000000FF);
int b2 = (px2 & 0x000000FF);
int new_r, new_g, new_b;
if (valid1 || valid2)
{
if (px1 != px2)
{
new_r = 0xFF;
new_g = ((g1 + g2) >> 1) >> 2;
new_b = ((b1 + b2) >> 1) >> 2;
ret = EINA_TRUE;
}
else
{
new_r = (((r1 + r2) >> 1) >> 2) + 0xC0;
new_g = (((g1 + g2) >> 1) >> 2) + 0xC0;
new_b = (((b1 + b2) >> 1) >> 2) + 0xC0;
}
}
else
{
new_r = new_g = new_b = 0x0;
}
if (pxsO) pxsO[h * wO + w] = 0xFF000000 | new_r << 16 | new_g << 8 | new_b;
}
}
if (imgO)
{
Exactness_Image *imgR = calloc(1, sizeof(Exactness_Image));
*imgO = imgR;
imgR->w = wO;
imgR->h = hO;
imgR->pixels = pxsO;
}
return ret;
}
EAPI void exactness_image_free(Exactness_Image *img)
{
if (!img) return;
free(img->pixels);
free(img);
}

1
tasn_is_a_lazy_bastard Normal file
View File

@ -0,0 +1 @@
And he deserves to DIEEEEEE