You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
707 lines
22 KiB
707 lines
22 KiB
#define _GNU_SOURCE 1 |
|
#define EFL_EO_API_SUPPORT |
|
#define EFL_BETA_API_SUPPORT |
|
#include <Eo.h> |
|
#include <Eet.h> |
|
#include <Evas.h> |
|
#include <Ecore.h> |
|
#include <Ecore_Evas.h> |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <sys/types.h> |
|
#include <sys/sysinfo.h> |
|
#include <dlfcn.h> |
|
#include "tsuite_file_data.h" |
|
#include "exactness_private.h" |
|
|
|
#define TSUITE_MAX_PATH 1024 |
|
#define IMAGE_FILENAME_EXT ".png" |
|
#define OBJECTS_FILENAME_EXT ".eet" |
|
|
|
struct _evas_hook_setting |
|
{ |
|
char *dest_dir; |
|
char *test_name; |
|
char *file_name; |
|
Eina_Bool verbose; |
|
Eina_Bool store_objects; |
|
}; |
|
typedef struct _evas_hook_setting evas_hook_setting; |
|
|
|
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 int ignore_evas_new = 0; /* Counter to know if we should ignore evas new or not. */ |
|
|
|
typedef struct |
|
{ |
|
const char *kl_name; |
|
int last; |
|
} Main_Widget_Id; |
|
static Eina_List *_main_widget_ids = NULL; |
|
static Object_Info _widgets_list = {0}; |
|
static void _objects_snapshot_do(); |
|
|
|
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 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 |
|
*/ |
|
static void |
|
_shot_do(char *name, Evas *e) |
|
{ |
|
if (!e) |
|
return; |
|
|
|
Ecore_Evas *ee = NULL, *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 */ |
|
|
|
if (_hook_setting->dest_dir) |
|
sprintf(filename, "%s/", _hook_setting->dest_dir); |
|
|
|
sprintf(filename + dir_name_len, "%s%c%03d%s", _hook_setting->test_name, |
|
SHOT_DELIMITER, ts.serial, IMAGE_FILENAME_EXT); |
|
} |
|
_tsuite_verbosef("Shot taken (%s).\n", filename); |
|
|
|
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) goto end; |
|
ecore_evas_geometry_get(ee_orig, NULL, NULL, &w, &h); |
|
if ((w < 1) || (h < 1)) goto end; |
|
|
|
ignore_evas_new++; |
|
ee = ecore_evas_buffer_new(1, 1); |
|
ignore_evas_new--; |
|
|
|
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); |
|
} |
|
|
|
end: |
|
if (ee) |
|
{ |
|
ecore_evas_free(ee); |
|
} |
|
free(filename); |
|
} |
|
|
|
static int _ecore_init_count = 0; |
|
|
|
EAPI int |
|
ecore_init(void) |
|
{ |
|
int ret; |
|
int (*_ecore_init)(void) = |
|
dlsym(RTLD_NEXT, "ecore_init"); |
|
|
|
_ecore_init_count++; |
|
|
|
if ((_ecore_init_count == 1) && (!_hook_setting)) |
|
{ |
|
const char *tmp; |
|
_hook_setting = calloc(1, sizeof(evas_hook_setting)); |
|
_hook_setting->dest_dir = getenv("TSUITE_DEST_DIR"); |
|
_hook_setting->test_name = getenv("TSUITE_TEST_NAME"); |
|
_hook_setting->file_name = getenv("TSUITE_FILE_NAME"); |
|
_hook_setting->store_objects = !!getenv("TSUITE_STORE_OBJECTS"); |
|
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> rec file is <%s>\n", __func__, _hook_setting->file_name); |
|
#endif |
|
} |
|
|
|
ret = _ecore_init(); |
|
eet_init(); |
|
|
|
return ret; |
|
} |
|
|
|
EAPI int |
|
ecore_shutdown(void) |
|
{ |
|
int (*_ecore_shutdown)(void) = |
|
dlsym(RTLD_NEXT, "ecore_shutdown"); |
|
|
|
_ecore_init_count--; |
|
|
|
if (_ecore_init_count == 0) |
|
{ |
|
if (_hook_setting) |
|
{ |
|
vr_list = free_events(vr_list, EINA_FALSE); |
|
|
|
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)); |
|
} |
|
|
|
eet_shutdown(); |
|
return _ecore_shutdown(); |
|
} |
|
|
|
EAPI Evas * |
|
evas_new(void) |
|
{ |
|
Evas * (*_evas_new)(void) = dlsym(RTLD_NEXT, __FUNCTION__); |
|
|
|
Evas *evas = _evas_new(); |
|
if (ignore_evas_new == 0) |
|
{ |
|
evas_list = eina_list_append(evas_list, evas); |
|
#ifdef DEBUG_TSUITE |
|
printf("Appended EVAS=<%p> list size=<%d>\n", evas, eina_list_count(evas_list)); |
|
#endif |
|
} |
|
|
|
return evas; |
|
} |
|
|
|
EAPI Ecore_Evas * |
|
ecore_evas_new(const char *engine_name EINA_UNUSED, int x, int y, |
|
int w, int h, const char *extra_options) |
|
{ |
|
Ecore_Evas * (*_ecore_evas_new)(const char *engine_name, int x, int y, |
|
int w, int h, const char *extra_options) = dlsym(RTLD_NEXT, __FUNCTION__); |
|
|
|
return _ecore_evas_new("buffer", x, y, w, h, extra_options); |
|
} |
|
|
|
static Eina_Bool |
|
tsuite_feed_event(void *data) |
|
{ |
|
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; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_mouse_in(e, time(NULL), NULL); |
|
break; |
|
} |
|
case TSUITE_EVENT_MOUSE_OUT: |
|
{ |
|
mouse_in_mouse_out *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_mouse_out(e, time(NULL), NULL); |
|
break; |
|
} |
|
case TSUITE_EVENT_MOUSE_DOWN: |
|
{ |
|
mouse_down_mouse_up *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (rect) evas_object_color_set(rect, 255, 255, 0, 255); |
|
if (e) evas_event_feed_mouse_down(e, t->b, t->flags, time(NULL), NULL); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_MOUSE_UP: |
|
{ |
|
mouse_down_mouse_up *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_mouse_up(e, t->b, t->flags, time(NULL), NULL); |
|
if (rect) evas_object_color_set(rect, 255, 0, 0, 255); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_MOUSE_MOVE: |
|
{ |
|
mouse_move *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_mouse_move(e, t->x, t->y, time(NULL), NULL); |
|
|
|
if (rect) |
|
{ |
|
evas_object_move(rect, t->x, t->y); |
|
evas_object_color_set(rect, 255, 0, 0, 255); |
|
} |
|
break; |
|
} |
|
case TSUITE_EVENT_MOUSE_WHEEL: |
|
{ |
|
mouse_wheel *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_mouse_wheel(e, t->direction, t->z, time(NULL), NULL); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_MULTI_DOWN: |
|
{ |
|
multi_event *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (!t->d) |
|
{ |
|
if (e) evas_event_feed_mouse_down(e, t->b, t->flags, time(NULL), NULL); |
|
if (rect) evas_object_color_set(rect, 255, 255, 0, 255); |
|
} |
|
else |
|
{ |
|
if (e) evas_event_feed_multi_down(e, |
|
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; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (!t->d) |
|
{ |
|
if (e) evas_event_feed_mouse_up(e, t->b, t->flags, time(NULL), NULL); |
|
if (rect) evas_object_color_set(rect, 255, 0, 0, 255); |
|
} |
|
else |
|
{ |
|
if (e) evas_event_feed_multi_up(e, |
|
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; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (!t->d) |
|
{ |
|
if (e) evas_event_feed_mouse_move(e, t->x, t->y, time(NULL), NULL); |
|
if (rect) |
|
{ |
|
evas_object_move(rect, t->x, t->y); |
|
evas_object_color_set(rect, 255, 0, 0, 255); |
|
} |
|
} |
|
else |
|
{ |
|
if (e) evas_event_feed_multi_move(e, |
|
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; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_key_down(e, |
|
t->keyname, t->key, t->string, |
|
t->compose, time(NULL), NULL); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_KEY_UP: |
|
{ |
|
key_down_key_up *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
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 |
|
if (e) evas_event_feed_key_up(e, |
|
t->keyname, t->key, t->string, |
|
t->compose, time(NULL), NULL); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: |
|
{ |
|
key_down_key_up_with_keycode *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
evt_time = t->timestamp; |
|
#ifdef DEBUG_TSUITE |
|
printf("%s evas_event_feed_key_down_with_keycode timestamp=<%u> t->n_evas=<%d> t->keycode=<%u>\n", __func__, t->timestamp, t->n_evas, t->keycode); |
|
#endif |
|
if (e) evas_event_feed_key_down_with_keycode(e, |
|
t->keyname, t->key, t->string, |
|
t->compose, time(NULL), NULL, t->keycode); |
|
|
|
break; |
|
} |
|
case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: |
|
{ |
|
key_down_key_up_with_keycode *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
evt_time = t->timestamp; |
|
#ifdef DEBUG_TSUITE |
|
printf("%s evas_event_feed_key_up_with_keycode timestamp=<%u> t->n_evas=<%d> t->keycode=<%u>\n", __func__, t->timestamp, t->n_evas, t->keycode); |
|
#endif |
|
if (e) evas_event_feed_key_up(e, |
|
t->keyname, t->key, t->string, |
|
t->compose, time(NULL), NULL); |
|
|
|
break; |
|
} |
|
|
|
case TSUITE_EVENT_TAKE_SHOT: |
|
{ |
|
take_screenshot *t = v->data; |
|
Eo *e = eina_list_nth(evas_list, t->n_evas); |
|
evt_time = t->timestamp; |
|
#ifdef DEBUG_TSUITE |
|
printf("%s take shot timestamp=<%u> t->n_evas=<%d>\n", __func__, t->timestamp, t->n_evas); |
|
#endif |
|
if (rect) evas_object_color_set(rect, 0, 0, 255, 255); |
|
ts.serial++; |
|
if (_hook_setting->dest_dir) |
|
{ |
|
if (e) _shot_do(NULL, e); /* Serial name based on test-name */ |
|
if (_hook_setting->store_objects) _objects_snapshot_do(); |
|
} |
|
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 */ |
|
ecore_main_loop_quit(); |
|
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 |
|
ecore_timer_add(timer_time, tsuite_feed_event, td); |
|
|
|
return ECORE_CALLBACK_CANCEL; |
|
} |
|
|
|
EOAPI Eina_Value * |
|
efl_loop_begin(Eo *obj) |
|
{ |
|
static Eina_Value * (*_foo)(Eo *) = NULL; |
|
if (!_foo) _foo = dlsym(RTLD_NEXT, __func__); |
|
|
|
if (_hook_setting->file_name) |
|
{ |
|
double diff_time = 0; /* Time to wait before feeding the first event */ |
|
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 */ |
|
|
|
/* Calculate the time to wait before feeding the first event */ |
|
unsigned int current_event_time = evt_time_get(0, eina_list_data_get(ts.td->current_event)); |
|
if (current_event_time > vr_list->first_timestamp) |
|
diff_time = (current_event_time - vr_list->first_timestamp) / 1000.0; |
|
|
|
#ifdef DEBUG_TSUITE |
|
printf("%s first_time_stamp=<%u> current_event_time=<%u>\n", __func__, vr_list->first_timestamp, current_event_time); |
|
#endif |
|
|
|
if (diff_time) |
|
{ |
|
#ifdef DEBUG_TSUITE |
|
printf(" Waiting <%f>\n", diff_time); |
|
#endif |
|
ecore_timer_add(diff_time, tsuite_feed_event, ts.td); |
|
} |
|
else |
|
{ |
|
tsuite_feed_event(ts.td); |
|
} |
|
} |
|
} |
|
|
|
return _foo(obj); |
|
} |
|
|
|
static void |
|
_obj_del(void *data EINA_UNUSED, const Efl_Event *event) |
|
{ |
|
Eo *parent = efl_parent_get(event->object); |
|
Object_Info *info = efl_key_data_get(event->object, "exactness_info"); |
|
if (parent) |
|
{ |
|
Object_Info *parent_info = parent ? efl_key_data_get(parent, "exactness_info") : NULL; |
|
if (parent_info) parent_info->children = eina_list_remove(parent_info->children, info); |
|
} |
|
else |
|
{ |
|
_widgets_list.children = eina_list_remove(_widgets_list.children, info); |
|
} |
|
efl_key_data_set(event->object, "exactness_info", NULL); |
|
eina_stringshare_del(info->kl_name); |
|
free(info); |
|
} |
|
|
|
EAPI Eo * |
|
_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback) |
|
{ |
|
Eo *(*foo)(const char *, int, const Efl_Class *, Eo *, Eina_Bool, Eina_Bool) = |
|
dlsym(RTLD_NEXT, __FUNCTION__); |
|
Eo *ret = foo(file, line, klass_id, parent_id, ref, is_fallback); |
|
|
|
if (!efl_isa(ret, EFL_CANVAS_INTERFACE) && !efl_isa(ret, EFL_CANVAS_OBJECT_CLASS)) goto end; |
|
|
|
efl_event_callback_add(ret, EFL_EVENT_DEL, _obj_del, NULL); |
|
end: |
|
return ret; |
|
} |
|
|
|
EOAPI void |
|
efl_parent_set(Eo *obj, Efl_Object *new_parent) |
|
{ |
|
void (*foo)(Eo *, Efl_Object *) = dlsym(RTLD_NEXT, __FUNCTION__); |
|
Object_Info *info = NULL; |
|
if (!efl_isa(obj, EFL_CANVAS_INTERFACE) && !efl_isa(obj, EFL_CANVAS_OBJECT_CLASS)) goto end; |
|
|
|
info = efl_key_data_get(obj, "exactness_info"); |
|
if (!info) |
|
{ |
|
info = calloc(1, sizeof(*info)); |
|
info->object = obj; |
|
info->kl_name = eina_stringshare_add(efl_class_name_get(obj)); |
|
efl_key_data_set(obj, "exactness_info", info); |
|
} |
|
|
|
Eo *old_parent = efl_parent_get(obj); |
|
if (info->id && old_parent == new_parent) goto end; |
|
if (old_parent) |
|
{ |
|
Object_Info *old_parent_info = efl_key_data_get(old_parent, "exactness_info"); |
|
if (old_parent_info) |
|
old_parent_info->children = eina_list_remove(old_parent_info->children, info); |
|
|
|
int last_parent_id = (intptr_t)efl_key_data_get(old_parent, info->kl_name); |
|
if (info->id && last_parent_id == info->id) |
|
efl_key_data_set(old_parent, info->kl_name, (void *)(intptr_t)(last_parent_id - 1)); |
|
} |
|
else |
|
{ |
|
Eina_List *itr; |
|
Main_Widget_Id *wid; |
|
EINA_LIST_FOREACH(_main_widget_ids, itr, wid) |
|
{ |
|
if (info->kl_name == wid->kl_name) goto found_old_parent; |
|
} |
|
wid = NULL; |
|
found_old_parent: |
|
if (wid && wid->last == info->id) wid->last--; |
|
_widgets_list.children = eina_list_remove(_widgets_list.children, info); |
|
} |
|
info->id = 0; |
|
info->parent = new_parent; |
|
if (new_parent) |
|
{ |
|
int last_parent_id = (intptr_t)efl_key_data_get(new_parent, info->kl_name); |
|
info->id = ++last_parent_id; |
|
efl_key_data_set(new_parent, info->kl_name, (void *)(intptr_t)last_parent_id); |
|
|
|
Object_Info *new_parent_info = efl_key_data_get(new_parent, "exactness_info"); |
|
if (new_parent_info) |
|
new_parent_info->children = eina_list_append(new_parent_info->children, info); |
|
} |
|
else |
|
{ |
|
Eina_List *itr; |
|
Main_Widget_Id *wid; |
|
EINA_LIST_FOREACH(_main_widget_ids, itr, wid) |
|
{ |
|
if (info->kl_name == wid->kl_name) goto found_new_parent; |
|
} |
|
wid = calloc(1, sizeof(*wid)); |
|
wid->kl_name = info->kl_name; |
|
_main_widget_ids = eina_list_append(_main_widget_ids, wid); |
|
found_new_parent: |
|
info->id = ++wid->last; |
|
_widgets_list.children = eina_list_append(_widgets_list.children, info); |
|
} |
|
end: |
|
foo(obj, new_parent); |
|
} |
|
|
|
static void |
|
_info_fill(Object_Info *info) |
|
{ |
|
Eina_List *itr; |
|
if (efl_isa(info->object, EFL_CANVAS_OBJECT_CLASS)) |
|
evas_object_geometry_get(info->object, &info->x, &info->y, &info->w, &info->h); |
|
EINA_LIST_FOREACH(info->children, itr, info) |
|
{ |
|
_info_fill(info); |
|
} |
|
} |
|
|
|
static void |
|
_objects_snapshot_do() |
|
{ |
|
Eina_List *itr; |
|
Object_Info *info; |
|
int dir_name_len = _hook_setting->dest_dir ? strlen(_hook_setting->dest_dir) + 1 : 0; /* includes space of a '/' */ |
|
char *filename = malloc(strlen(_hook_setting->test_name) + strlen(OBJECTS_FILENAME_EXT) + |
|
dir_name_len + 8); /* also space for serial */ |
|
|
|
if (_hook_setting->dest_dir) |
|
sprintf(filename, "%s/", _hook_setting->dest_dir); |
|
|
|
sprintf(filename + dir_name_len, "%s%c%03d%s", _hook_setting->test_name, |
|
SHOT_DELIMITER, ts.serial, OBJECTS_FILENAME_EXT); |
|
|
|
printf("%d objects saved into %s\n", eina_list_count(_widgets_list.children), filename); |
|
|
|
EINA_LIST_FOREACH(_widgets_list.children, itr, info) |
|
{ |
|
_info_fill(info); |
|
} |
|
|
|
Eet_File *file = eet_open(filename, EET_FILE_MODE_WRITE); |
|
eet_data_write(file, object_info_desc_make(), "entry", &_widgets_list, EINA_TRUE); |
|
eet_close(file); |
|
|
|
free(filename); |
|
}
|
|
|