#define _GNU_SOURCE 1 #define EFL_EO_API_SUPPORT #define EFL_BETA_API_SUPPORT #include #include #include #include #include #include #include #include #include #include #include #include "tsuite_file_data.h" #include "exactness_private.h" #define TSUITE_MAX_PATH 1024 #define SHOT_KEY_STR "F2" #define SAVE_KEY_STR "F3" #define IMAGE_FILENAME_EXT ".png" 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 int ignore_evas_new = 0; /* Counter to know if we should ignore evas new or not. */ static Tsuite_Event_Type tsuite_event_pointer_type_get(Efl_Pointer_Action t) { switch(t) { case EFL_POINTER_ACTION_IN: return TSUITE_EVENT_MOUSE_IN; case EFL_POINTER_ACTION_OUT: return TSUITE_EVENT_MOUSE_OUT; case EFL_POINTER_ACTION_DOWN: return TSUITE_EVENT_MULTI_DOWN; case EFL_POINTER_ACTION_UP: return TSUITE_EVENT_MULTI_UP; case EFL_POINTER_ACTION_MOVE: return TSUITE_EVENT_MULTI_MOVE; case EFL_POINTER_ACTION_WHEEL: return TSUITE_EVENT_MOUSE_WHEEL; default: return TSUITE_EVENT_NOT_SUPPORTED; } } #ifdef DEBUG_TSUITE static const char * _event_name_get(Tsuite_Event_Type type) { switch(type) { case TSUITE_EVENT_MOUSE_IN: return "Mouse In"; case TSUITE_EVENT_MOUSE_OUT: return "Mouse Out"; case TSUITE_EVENT_MOUSE_DOWN: return "Mouse Down"; case TSUITE_EVENT_MOUSE_UP: return "Mouse Up"; case TSUITE_EVENT_MOUSE_MOVE: return "Mouse Move"; case TSUITE_EVENT_MOUSE_WHEEL: return "Mouse Wheel"; case TSUITE_EVENT_MULTI_DOWN: return "Multi Down"; case TSUITE_EVENT_MULTI_UP: return "Multi Up"; case TSUITE_EVENT_MULTI_MOVE: return "Multi Move"; case TSUITE_EVENT_KEY_DOWN: return "Key Down"; case TSUITE_EVENT_KEY_UP: return "Key Up"; case TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE: return "Key Down with Keycode"; case TSUITE_EVENT_KEY_UP_WITH_KEYCODE: return "Key Up with Keycode"; case TSUITE_EVENT_TAKE_SHOT: return "Take shot"; default: return NULL; } } #endif static Eina_Bool _is_hook_duplicate(const Variant_st *v, Tsuite_Event_Type ev_type, const void *info, int len) { if (v->t.type == tsuite_event_mapping_type_str_get(ev_type) && !memcmp(v->data, info, len)) return EINA_TRUE; return EINA_FALSE; } /* Adding variant to list, this list is later written to EET file */ #define ADD_TO_LIST(EVT_TYPE, INFO) \ do { /* This macro will add event to EET data list */ \ if (vr_list && _hook_setting->recording) \ { \ const Variant_st *prev_v = eina_list_last_data_get(vr_list->variant_list); \ if (!prev_v || !_is_hook_duplicate(prev_v, EVT_TYPE, &INFO, sizeof(INFO))) \ { \ printf("Recording %s\n", tsuite_event_mapping_type_str_get(EVT_TYPE)); \ Variant_st *v = malloc(sizeof(Variant_st)); \ v->data = malloc(sizeof(INFO)); \ _variant_type_set(tsuite_event_mapping_type_str_get(EVT_TYPE), \ &v->t, EINA_FALSE); \ memcpy(v->data, &INFO, sizeof(INFO)); \ vr_list->variant_list = eina_list_append(vr_list->variant_list, v); \ } \ } \ } while (0) static int evas_list_find(void *ptr) { /* We just compare the pointers */ Eina_List *l; void *data; int n = 0; EINA_LIST_FOREACH(evas_list, l, data) { /* Get the nuber of Evas Pointer */ if (ptr == data) { return n; } n++; } return -1; } static void _tsuite_verbosef(const char *fmt, ...) { 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 */ 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_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 void _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) { struct sysinfo s_info; sysinfo(&s_info); vr_list = calloc(1, sizeof(*vr_list)); vr_list->first_timestamp = s_info.uptime * 1000; #ifdef DEBUG_TSUITE printf("Uptime=<%u>\n", vr_list->first_timestamp); #endif } } static void _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 */ 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 */ ts.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) { Eina_Bool initing = EINA_FALSE; 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->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 initing = EINA_TRUE; } ret = _ecore_init(); eet_init(); if (initing) { if (_hook_setting->recording) _evas_hook_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) { if (vr_list && _hook_setting->recording) write_events(_hook_setting->file_name, vr_list); _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)); } eet_shutdown(); return _ecore_shutdown(); } static void _event_pointer_cb(void *data, const Efl_Event *event) { Eo *eo_e = data; Eo *evp = event->info; if (!evp) return; int timestamp = efl_input_timestamp_get(evp); int n_evas = evas_list_find(eo_e); Efl_Pointer_Action action = efl_input_pointer_action_get(evp); Tsuite_Event_Type evt = tsuite_event_pointer_type_get(action); if (!timestamp) return; #ifdef DEBUG_TSUITE printf("Calling \"%s\" timestamp=<%u>\n", _event_name_get(evt), timestamp); #endif switch (action) { case EFL_POINTER_ACTION_MOVE: { double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0; int tool = efl_input_pointer_tool_get(evp); int x = 0, y = 0; efl_input_pointer_position_get(evp, &x, &y); multi_move t = { tool, x, y, rad, radx, rady, pres, ang, fx, fy, timestamp, n_evas }; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); break; } case EFL_POINTER_ACTION_DOWN: case EFL_POINTER_ACTION_UP: { double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0; int b = efl_input_pointer_button_get(evp); int tool = efl_input_pointer_tool_get(evp); int x = 0, y = 0; efl_input_pointer_position_get(evp, &x, &y); Efl_Pointer_Flags flags = efl_input_pointer_button_flags_get(evp); multi_event t = { tool, b, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, n_evas }; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); break; } case EFL_POINTER_ACTION_IN: case EFL_POINTER_ACTION_OUT: { mouse_in_mouse_out t = { timestamp, n_evas }; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); break; } case EFL_POINTER_ACTION_WHEEL: { int direction = efl_input_pointer_wheel_direction_get(evp); int z = efl_input_pointer_wheel_delta_get(evp); mouse_wheel t = { direction, z, timestamp, n_evas }; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); break; } default: break; } } static void _event_key_cb(void *data, const Efl_Event *event) { Efl_Input_Key *evk = event->info; Eo *eo_e = data; if (!evk) return; const char *key = efl_input_key_name_get(evk); int timestamp = efl_input_timestamp_get(evk); int n_evas = evas_list_find(eo_e); Tsuite_Event_Type evt = TSUITE_EVENT_KEY_UP_WITH_KEYCODE; if (efl_input_key_pressed_get(evk)) { if (!strcmp(key, shot_key)) { #ifdef DEBUG_TSUITE printf("Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp); #endif take_screenshot t = { timestamp, n_evas }; if (t.n_evas >= 0) ADD_TO_LIST(TSUITE_EVENT_TAKE_SHOT, t); return; } if (!strcmp(key, SAVE_KEY_STR)) { if (_hook_setting) { if (vr_list && _hook_setting->recording) write_events(_hook_setting->file_name, vr_list); #ifdef DEBUG_TSUITE printf("Save events: %s timestamp=<%u>\n", __func__, timestamp); #endif } return; } evt = TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE; } else { if (!strcmp(key, shot_key) || !strcmp(key, SAVE_KEY_STR)) return; } if (vr_list && _hook_setting->recording) { /* Construct duplicate strings, free them when list if freed */ key_down_key_up_with_keycode t; t.timestamp = timestamp; t.keyname = eina_stringshare_add(key); t.key = eina_stringshare_add(efl_input_key_get(evk)); t.string = eina_stringshare_add(efl_input_key_string_get(evk)); t.compose = eina_stringshare_add(efl_input_key_compose_get(evk)); t.keycode = efl_input_key_code_get(evk); t.n_evas = n_evas; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); } } // note: "hold" event comes from above (elm), not below (ecore) EFL_CALLBACKS_ARRAY_DEFINE(_event_pointer_callbacks, { EFL_EVENT_POINTER_MOVE, _event_pointer_cb }, { EFL_EVENT_POINTER_DOWN, _event_pointer_cb }, { EFL_EVENT_POINTER_UP, _event_pointer_cb }, { EFL_EVENT_POINTER_IN, _event_pointer_cb }, { EFL_EVENT_POINTER_OUT, _event_pointer_cb }, { EFL_EVENT_POINTER_WHEEL, _event_pointer_cb }, { EFL_EVENT_FINGER_MOVE, _event_pointer_cb }, { EFL_EVENT_FINGER_DOWN, _event_pointer_cb }, { EFL_EVENT_FINGER_UP, _event_pointer_cb }, { EFL_EVENT_KEY_DOWN, _event_key_cb }, { EFL_EVENT_KEY_UP, _event_key_cb } ) EAPI Evas * evas_new(void) { Evas *evas; Evas * (*_evas_new)(void) = dlsym(RTLD_NEXT, __FUNCTION__); evas = _evas_new(); if (ignore_evas_new == 0) { evas_list = eina_list_append(evas_list, evas); efl_event_callback_array_add(evas, _event_pointer_callbacks(), evas); #ifdef DEBUG_TSUITE printf("Appended EVAS=<%p> list size=<%d>\n", evas, eina_list_count(evas_list)); #endif } return evas; } EAPI Ecore_Evas * ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options) { Ecore_Evas *ecore_evas; 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__); if(!_hook_setting->recording) ecore_evas = _ecore_evas_new("buffer", x, y, w, h, extra_options); else ecore_evas = _ecore_evas_new(engine_name, x, y, w, h, extra_options); return ecore_evas; } 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; 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 if (rect) evas_object_color_set(rect, 255, 255, 0, 255); 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); if (rect) evas_object_color_set(rect, 255, 0, 0, 255); 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); evas_object_color_set(rect, 255, 0, 0, 255); } 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 if (!t->d) { evas_event_feed_mouse_down(eina_list_nth(evas_list, t->n_evas), t->b, t->flags, time(NULL), NULL); if (rect) evas_object_color_set(rect, 255, 255, 0, 255); } else { evas_event_feed_multi_down(eina_list_nth(evas_list, t->n_evas), t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, t->flags, time(NULL), NULL); } break; } 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 if (!t->d) { evas_event_feed_mouse_up(eina_list_nth(evas_list, t->n_evas), t->b, t->flags, time(NULL), NULL); if (rect) evas_object_color_set(rect, 255, 0, 0, 255); } else { evas_event_feed_multi_up(eina_list_nth(evas_list, t->n_evas), t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, t->flags, time(NULL), NULL); } break; } 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 if (!t->d) { evas_event_feed_mouse_move(eina_list_nth(evas_list, t->n_evas), t->x, t->y, time(NULL), NULL); if (rect) { evas_object_move(rect, t->x, t->y); evas_object_color_set(rect, 255, 0, 0, 255); } } else { evas_event_feed_multi_move(eina_list_nth(evas_list, t->n_evas), t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, time(NULL), NULL); } break; } 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_KEY_DOWN_WITH_KEYCODE: { key_down_key_up_with_keycode *t = v->data; 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 evas_event_feed_key_down_with_keycode(eina_list_nth(evas_list, t->n_evas), 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; 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 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; #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); _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 */ 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; } 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) { 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 _ecore_main_loop_begin(); } 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; 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, 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); } /* FIXME: Handle framespace. */ EAPI void evas_event_input_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const void *data) { if (!timestamp) return; 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, 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; #ifdef DEBUG_TSUITE printf("Calling %s timestamp=<%u>\n", __func__, timestamp); #endif multi_event t = { d, 0, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, evas_list_find(e)}; int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_DOWN); if (t.n_evas >= 0) ADD_TO_LIST(evt, 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) { if (!timestamp) return; #ifdef DEBUG_TSUITE printf("Calling %s timestamp=<%u>\n", __func__, timestamp); #endif multi_event t = { d, 0, x, y, rad, radx, rady, pres, ang, fx, fy, flags, timestamp, evas_list_find(e) }; int evt = tsuite_event_type_get(EVAS_CALLBACK_MULTI_UP); if (t.n_evas >= 0) ADD_TO_LIST(evt, 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) { if (!timestamp) return; #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, 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) { if (!timestamp) return; 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, t); orig(e, keyname, key, string, compose, timestamp, data); return; } if (!strcmp(key, SAVE_KEY_STR)) { if (_hook_setting) { if (vr_list && _hook_setting->recording) write_events(_hook_setting->file_name, vr_list); #ifdef DEBUG_TSUITE printf("Save events: %s timestamp=<%u>\n", __func__, timestamp); #endif } return; } 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, 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) { if (!timestamp) return; 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 */ } if (!strcmp(key, SAVE_KEY_STR)) { #ifdef DEBUG_TSUITE printf("Save events: %s timestamp=<%u>\n", __func__, timestamp); #endif orig(e, keyname, key, string, compose, timestamp, data); return; /* Save events 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, t); } orig(e, keyname, key, string, compose, timestamp, data); } EAPI void evas_event_feed_key_down_with_keycode(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode) { if (!timestamp) return; int evt = TSUITE_EVENT_KEY_DOWN_WITH_KEYCODE; void (*orig) (Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode) = 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, t); orig(e, keyname, key, string, compose, timestamp, data, keycode); return; } if (!strcmp(key, SAVE_KEY_STR)) { if (_hook_setting) { if (vr_list && _hook_setting->recording) write_events(_hook_setting->file_name, vr_list); #ifdef DEBUG_TSUITE printf("Save events: %s timestamp=<%u>\n", __func__, timestamp); #endif } return; } if (vr_list && _hook_setting->recording) { /* Construct duplicate strings, free them when list if freed */ key_down_key_up_with_keycode t; t.timestamp = timestamp; t.keyname = eina_stringshare_add(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); t.keycode = keycode; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); } orig(e, keyname, key, string, compose, timestamp, data, keycode); } EAPI void evas_event_feed_key_up_with_keycode(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode) { if (!timestamp) return; void (*orig) (Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data, unsigned int keycode) = 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, keycode); return; /* Take screenshot done on key-down */ } if (!strcmp(key, SAVE_KEY_STR)) { #ifdef DEBUG_TSUITE printf("Save events: %s timestamp=<%u>\n", __func__, timestamp); #endif orig(e, keyname, key, string, compose, timestamp, data, keycode); return; /* Save events done on key-down */ } int evt = TSUITE_EVENT_KEY_UP_WITH_KEYCODE; #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_with_keycode 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); t.keycode = keycode; if (t.n_evas >= 0) ADD_TO_LIST(evt, t); } orig(e, keyname, key, string, compose, timestamp, data, keycode); }