From 24b73e374c7a04a7d6e4aaae3401d67d43654e2a Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Mon, 28 May 2018 20:44:15 +0900 Subject: [PATCH] e_info: print input_region information using winfo Change-Id: Id1748ccf69f0aaf454ceca6f9c599bfba39fad64 --- src/bin/e_comp_object.c | 20 +++++ src/bin/e_comp_object.h | 1 + src/bin/e_info_client.c | 191 ++++++++++++++++++++++++++++++++++++---- src/bin/e_info_server.c | 163 +++++++++++++++++++++++++++++++++- 4 files changed, 356 insertions(+), 19 deletions(-) diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 52e5242cee..8290c96587 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -3725,6 +3725,26 @@ e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h) } } +EINTERN void +e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list) +{ + API_ENTRY; + E_Input_Rect_Smart_Data *input_rect_sd; + E_Input_Rect_Data *input_rect_data; + Eina_List *l; + + if (!cw->input_obj) return; + + input_rect_sd = evas_object_smart_data_get(cw->input_obj); + if (input_rect_sd) + { + EINA_LIST_FOREACH(input_rect_sd->input_rect_data_list, l, input_rect_data) + { + *list = eina_list_append(*list, &input_rect_data->rect); + } + } +} + E_API void e_comp_object_frame_geometry_get(Evas_Object *obj, int *l, int *r, int *t, int *b) { diff --git a/src/bin/e_comp_object.h b/src/bin/e_comp_object.h index 889923bcfa..e93381dd7a 100644 --- a/src/bin/e_comp_object.h +++ b/src/bin/e_comp_object.h @@ -117,6 +117,7 @@ E_API void e_comp_object_signal_callback_del(Evas_Object *obj, const char *sig, E_API void e_comp_object_signal_callback_del_full(Evas_Object *obj, const char *sig, const char *src, Edje_Signal_Cb cb, const void *data); E_API void e_comp_object_input_objs_del(Evas_Object *obj); E_API void e_comp_object_input_area_set(Evas_Object *obj, int x, int y, int w, int h); +EINTERN void e_comp_object_input_rect_get(Evas_Object *obj, Eina_List **list); E_API void e_comp_object_damage(Evas_Object *obj, int x, int y, int w, int h); E_API Eina_Bool e_comp_object_damage_exists(Evas_Object *obj); E_API void e_comp_object_render_update_add(Evas_Object *obj); diff --git a/src/bin/e_info_client.c b/src/bin/e_info_client.c index 026c1ee757..28da63f269 100644 --- a/src/bin/e_info_client.c +++ b/src/bin/e_info_client.c @@ -52,6 +52,7 @@ typedef struct _E_Win_Info int pl_zpos; Ecore_Window parent_id; const char *layer_name; // layer name + Eina_Bool has_input_region; } E_Win_Info; typedef struct output_mode_info @@ -79,7 +80,7 @@ typedef struct _E_Layer_Fps_Info double fps; } E_Layer_Fps_Info; -#define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiiibbiius" +#define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiiibbiiusb" #define VALUE_TYPE_REQUEST_RESLIST "ui" #define VALUE_TYPE_REPLY_RESLIST "ssi" #define VALUE_TYPE_FOR_INPUTDEV "ssi" @@ -360,7 +361,7 @@ _e_get_windows(int mode, char *value) } static E_Win_Info * -_e_win_info_new(Ecore_Window id, uint32_t res_id, int pid, Eina_Bool alpha, int opaque, const char *name, int x, int y, int w, int h, int layer, int visible, int visibility, int iconic, int frame_visible, int focused, int hwc, int pl_zpos, Ecore_Window parent_id, const char *layer_name) +_e_win_info_new(Ecore_Window id, uint32_t res_id, int pid, Eina_Bool alpha, int opaque, const char *name, int x, int y, int w, int h, int layer, int visible, int visibility, int iconic, int frame_visible, int focused, int hwc, int pl_zpos, Ecore_Window parent_id, const char *layer_name, Eina_Bool has_input_region) { E_Win_Info *win = NULL; @@ -387,6 +388,7 @@ _e_win_info_new(Ecore_Window id, uint32_t res_id, int pid, Eina_Bool alpha, int win->pl_zpos = pl_zpos; win->parent_id = parent_id; win->layer_name = eina_stringshare_add(layer_name); + win->has_input_region = has_input_region; return win; } @@ -421,6 +423,7 @@ _e_win_info_make_array(Eldbus_Message_Iter *array) uint32_t res_id; int pid; E_Win_Info *win = NULL; + Eina_Bool has_input_region = EINA_FALSE; res = eldbus_message_iter_arguments_get(ec, VALUE_TYPE_FOR_TOPVWINS, &id, @@ -442,14 +445,15 @@ _e_win_info_make_array(Eldbus_Message_Iter *array) &hwc, &pl_zpos, &parent_id, - &layer_name); + &layer_name, + &has_input_region); if (!res) { printf("Failed to get win info\n"); continue; } - win = _e_win_info_new(id, res_id, pid, alpha, opaque, win_name, x, y, w, h, layer, visible, visibility, iconic, frame_visible, focused, hwc, pl_zpos, parent_id, layer_name); + win = _e_win_info_new(id, res_id, pid, alpha, opaque, win_name, x, y, w, h, layer, visible, visibility, iconic, frame_visible, focused, hwc, pl_zpos, parent_id, layer_name, has_input_region); e_info_client.win_list = eina_list_append(e_info_client.win_list, win); } } @@ -1003,9 +1007,9 @@ _e_info_client_proc_topvwins_info(int argc, char **argv) printf("Deiconify Approve: %s\n", e_info_client.deiconify_approve ? "on":"off"); printf("\n%d Top level windows\n", eina_list_count(e_info_client.win_list)); - printf("--------------------------------------[ topvwins ]----------------------------------------------------------------------------\n"); - printf(" No Win_ID RcsID PID w h x y Foc Dep Opaq Visi Icon Map Frame PL@ZPos Parent Title\n"); - printf("------------------------------------------------------------------------------------------------------------------------------\n"); + printf("--------------------------------------[ topvwins ]----------------------------------------------------------------------------------\n"); + printf(" No Win_ID RcsID PID w h x y Foc InReg Dep Opaq Visi Icon Map Frame PL@ZPos Parent Title\n"); + printf("------------------------------------------------------------------------------------------------------------------------------------\n"); if (!e_info_client.win_list) { @@ -1021,7 +1025,7 @@ _e_info_client_proc_topvwins_info(int argc, char **argv) if (win->layer != prev_layer) { if (prev_layer != -1) - printf("---------------------------------------------------------------------------------------------------------------------[%s]\n", + printf("------------------------------------------------------------------------------------------------------------------------------------[%s]\n", prev_layer_name ? prev_layer_name : " "); prev_layer = win->layer; prev_layer_name = win->layer_name; @@ -1048,12 +1052,12 @@ _e_info_client_proc_topvwins_info(int argc, char **argv) snprintf(tmp, sizeof(tmp), " - "); } - printf("%3d 0x%08x %5d %5d %5d %5d %6d %6d %c %3d %2d ", i, win->id, win->res_id, win->pid, win->w, win->h, win->x, win->y, win->focused ? 'O':' ', win->alpha? 32:24, win->opaque); + printf("%3d 0x%08x %5d %5d %5d %5d %6d %6d %c %c %3d %2d ", i, win->id, win->res_id, win->pid, win->w, win->h, win->x, win->y, win->focused ? 'O':' ', win->has_input_region?'C':' ', win->alpha? 32:24, win->opaque); printf("%2d %d %s %3d %-8s %-8x %s\n", win->visibility, win->iconic, win->vis? "V":"N", win->frame_visible, tmp, win->parent_id, win->name?:"No Name"); } if (prev_layer_name) - printf("---------------------------------------------------------------------------------------------------------------------[%s]\n", + printf("------------------------------------------------------------------------------------------------------------------------------------[%s]\n", prev_layer_name ? prev_layer_name : " "); if(hwc_off) @@ -1082,9 +1086,9 @@ _e_info_client_proc_topwins_info(int argc, char **argv) return; printf("%d Top level windows\n", eina_list_count(e_info_client.win_list)); - printf("--------------------------------------[ topvwins ]----------------------------------------------------------------------------\n"); - printf(" No Win_ID RcsID PID w h x y Foc Dep Opaq Visi Icon Map Frame PL@ZPos Parent Title\n"); - printf("------------------------------------------------------------------------------------------------------------------------------\n"); + printf("--------------------------------------[ topvwins ]----------------------------------------------------------------------------------\n"); + printf(" No Win_ID RcsID PID w h x y Foc InReg Dep Opaq Visi Icon Map Frame PL@ZPos Parent Title\n"); + printf("------------------------------------------------------------------------------------------------------------------------------------\n"); if (!e_info_client.win_list) { @@ -1100,7 +1104,7 @@ _e_info_client_proc_topwins_info(int argc, char **argv) if (win->layer != prev_layer) { if (prev_layer != -1) - printf("---------------------------------------------------------------------------------------------------------------------[%s]\n", + printf("------------------------------------------------------------------------------------------------------------------------------------[%s]\n", prev_layer_name ? prev_layer_name : " "); prev_layer = win->layer; prev_layer_name = win->layer_name; @@ -1127,12 +1131,12 @@ _e_info_client_proc_topwins_info(int argc, char **argv) snprintf(tmp, sizeof(tmp), " - "); } - printf("%3d 0x%08x %5d %5d %5d %5d %6d %6d %c %3d %2d ", i, win->id, win->res_id, win->pid, win->w, win->h, win->x, win->y, win->focused ? 'O':' ', win->alpha? 32:24, win->opaque); + printf("%3d 0x%08x %5d %5d %5d %5d %6d %6d %c %c %3d %2d ", i, win->id, win->res_id, win->pid, win->w, win->h, win->x, win->y, win->focused ? 'O':' ', win->has_input_region ? 'C':' ',win->alpha? 32:24, win->opaque); printf("%2d %d %s %3d %-8s %-8x %s\n", win->visibility, win->iconic, win->vis? "V":"N", win->frame_visible, tmp, win->parent_id, win->name?:"No Name"); } if (prev_layer_name) - printf("---------------------------------------------------------------------------------------------------------------------[%s]\n", + printf("------------------------------------------------------------------------------------------------------------------------------------[%s]\n", prev_layer_name ? prev_layer_name : " "); if(hwc_off) @@ -4579,6 +4583,154 @@ _e_info_client_memchecker(int argc, char **argv) printf("e20 dump log file under /tmp dir.\n"); } +static void +_cb_input_region_get(const Eldbus_Message *msg) +{ + const char *name = NULL, *text = NULL; + Eldbus_Message_Iter *array; + Eldbus_Message_Iter *iter; + Eina_Bool res; + int cnt = 0; + + res = eldbus_message_error_get(msg, &name, &text); + EINA_SAFETY_ON_TRUE_GOTO(res, finish); + + printf("Input region\n"); + + res = eldbus_message_arguments_get(msg, "a(iiii)", &array); + if (!res) + { + printf("\tNo Input region\n"); + return; + } + + while (eldbus_message_iter_get_and_next(array, 'r', &iter)) + { + int x = 0, y = 0, w = 0, h = 0; + res = eldbus_message_iter_arguments_get(iter, + "iiii", + &x, + &y, + &w, + &h); + if (!res) + { + printf("Failed to get input region info\n"); + continue; + } + cnt++; + printf("\t[%d] [(%d, %d), %dx%d]\n", cnt, x, y, w, h); + } + if (cnt == 0) printf("\tNo Input region\n"); + +finish: + if ((name) || (text)) + { + printf("errname:%s errmsg:%s\n", name, text); + } +} + +static void +_e_info_client_input_region_usage(void) +{ + printf("\nUsage: \n"); + printf("\twinfo -input_region [options] [window_id]\n"); + printf("\t\toption: -t: time to show input_regions area (sec)\n"); + printf("\t\t -color: color to shwo input_regions area (r, g, b) default: red\n"); + printf("\tex> winfo -input_region\n"); + printf("\t winfo -input_region -t 2 -color g 0xabc123\n"); +} + +static void +_e_info_client_proc_input_region(int argc, char **argv) +{ + const char *win_id = NULL; + + Ecore_Window win; + char win_temp[64] = {0, }; + int time = 5; + int cnt, idx; + int color_r = 0, color_g = 0, color_b = 0; + + cnt = argc - 2; + idx = 2; + + while (cnt > 0) + { + if (argv[idx][0] == '-') + { + if (argv[idx][1] == 't') + { + idx++; + cnt--; + if (cnt <= 0) + { + printf("Please input correct options\n"); + _e_info_client_input_region_usage(); + return; + } + time = atoi(argv[idx]); + } + else if (!strncmp(argv[idx], "-color", sizeof("-color"))) + { + idx++; + cnt--; + if (cnt <= 0) + { + printf("Please input correct options\n"); + _e_info_client_input_region_usage(); + return; + } + if (argv[idx][0] == 'r') + { + color_r = 255; + } + else if (argv[idx][0] == 'g') + { + color_g = 255; + } + else if (argv[idx][0] == 'b') + { + color_b = 255; + } + } + } + else if (strstr(argv[idx], "0x")) + { + win_id = argv[idx]; + } + else if (!strncmp(argv[idx], "help", sizeof("help"))) + { + _e_info_client_input_region_usage(); + return; + } + + idx++; + cnt--; + } + if (!win_id) + { + printf("Select the window whose input_regions you wish to show\n"); + printf("If you want to see more option, please input \"help\" > winfo -input_region help\n"); + if (_e_get_window_under_touch(&win)) + { + printf("Error: cannot get window under touch\n"); + return; + } + + snprintf(win_temp, sizeof(win_temp), "%lu", (unsigned long int)win); + + win_id = win_temp; + } + if (!color_r && !color_g && !color_b) + color_r = 255; + + if (!_e_info_client_eldbus_message_with_args("input_region", _cb_input_region_get, "siiii", win_id, time, color_r, color_g, color_b)) + printf("Error occured while send message\n"); + + return; +} + static struct { const char *option; @@ -4858,7 +5010,12 @@ static struct "dump stack information by allocations", _e_info_client_memchecker }, - + { + "input_region", + NULL, + "Print input regions", + _e_info_client_proc_input_region + }, }; static void diff --git a/src/bin/e_info_server.c b/src/bin/e_info_server.c index 5062b5b87f..6c5838060c 100644 --- a/src/bin/e_info_server.c +++ b/src/bin/e_info_server.c @@ -8,6 +8,7 @@ #include "e_comp_wl.h" #include "e_info_protocol.h" #include +#include "e_comp_object.h" #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT #include @@ -73,7 +74,7 @@ static Eina_List *module_hook = NULL; str_r -= str_l; \ } while(0) -#define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiiibbiius" +#define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiiibbiiusb" #define VALUE_TYPE_REQUEST_RESLIST "ui" #define VALUE_TYPE_REPLY_RESLIST "ssi" #define VALUE_TYPE_FOR_INPUTDEV "ssi" @@ -242,6 +243,8 @@ _msg_clients_append(Eldbus_Message_Iter *iter, Eina_Bool is_visible) char layer_name[32]; int hwc = -1, pl_zpos = -999; int iconified = 0; + Eina_Bool has_input_region = EINA_FALSE; + Eina_List *list_input_region = NULL; ec = evas_object_data_get(o, "E_Client"); if (!ec) continue; @@ -278,6 +281,10 @@ _msg_clients_append(Eldbus_Message_Iter *iter, Eina_Bool is_visible) _e_info_server_ec_hwc_info_get(ec, &hwc, &pl_zpos); + e_comp_object_input_rect_get(o, &list_input_region); + if (list_input_region && (eina_list_count(list_input_region) > 0)) + has_input_region = EINA_TRUE; + eldbus_message_iter_arguments_append(array_of_ec, "("VALUE_TYPE_FOR_TOPVWINS")", &struct_of_ec); eldbus_message_iter_arguments_append @@ -288,7 +295,7 @@ _msg_clients_append(Eldbus_Message_Iter *iter, Eina_Bool is_visible) e_client_util_name_get(ec) ?: "NO NAME", ec->x, ec->y, ec->w, ec->h, ec->layer, ec->visible, ec->argb, ec->visibility.opaque, ec->visibility.obscured, iconified, - evas_object_visible_get(ec->frame), ec->focused, hwc, pl_zpos, pwin, layer_name); + evas_object_visible_get(ec->frame), ec->focused, hwc, pl_zpos, pwin, layer_name, has_input_region); eldbus_message_iter_container_close(array_of_ec, struct_of_ec); } @@ -929,6 +936,36 @@ _astrcat(char **dst, const char *src) } \ free(temp); }) + +static const char * +_get_win_prop_Input_region(const Evas_Object *evas_obj) +{ + Eina_List *list = NULL, *l; + Eina_Rectangle *data; + char *str = NULL; + + e_comp_object_input_rect_get((Evas_Object *)evas_obj, &list); + if (!list || (eina_list_count(list) <= 0)) + { + astrcat_(&str, "No Input Region\n"); + return str; + } + + EINA_LIST_FOREACH(list, l, data) + { + astrcat_(&str, "[(%d, %d) %dx%d]\n", data->x, data->y, data->w, data->h); + } + EINA_LIST_FREE(list, data); + list = NULL; + + return str; +fail: + if (str) free(str); + return NULL; +} + + + static const char* _get_win_prop_Rotation(const Evas_Object *evas_obj) { @@ -2135,6 +2172,11 @@ static struct property_manager "Rotation", _get_win_prop_Rotation, NULL + }, + { + "Input Region", + _get_win_prop_Input_region, + NULL } }; @@ -5463,6 +5505,122 @@ _e_info_server_cb_memchecker(const Eldbus_Service_Interface *iface EINA_UNUSED, e_comp->func_memory_dump(); else ERR("Not available to dump memory"); + + } + + return reply; +} + +static Eina_Bool +_input_rect_timer(void *data) +{ + Evas_Object *rect = (Evas_Object *)data; + + evas_object_hide(rect); + evas_object_del(rect); + + e_comp_render_queue(); + + return ECORE_CALLBACK_CANCEL;; +} + +static void +_input_rect_draw(int x, int y, int w, int h, int time, int color_r, int color_g, int color_b) +{ + Evas_Object *rect; + EINA_SAFETY_ON_NULL_RETURN(e_comp->evas); + + rect = evas_object_rectangle_add(e_comp->evas); + EINA_SAFETY_ON_NULL_RETURN(rect); + + evas_object_color_set(rect, color_r, color_g, color_b, 150); + evas_object_resize(rect, w, h); + evas_object_move(rect, x, y); + + evas_object_layer_set(rect, E_LAYER_DESK_OBJECT_ABOVE); + + evas_object_show(rect); + + e_comp_render_queue(); + + ecore_timer_add((double)time, _input_rect_timer, rect); +} + +static void +_input_region_msg_clients_append(Eldbus_Message_Iter *iter, Evas_Object *obj, int time, int color_r, int color_g, int color_b) +{ + Eldbus_Message_Iter *array_of_ec; + Eina_List *list = NULL, *l; + Eina_Rectangle *data; + + e_comp_object_input_rect_get(obj, &list); + if (!list) return; + if (eina_list_count(list) <= 0) return; + + eldbus_message_iter_arguments_append(iter, "a(iiii)", &array_of_ec); + + EINA_LIST_FOREACH(list, l, data) + { + Eldbus_Message_Iter* struct_of_ec; + + eldbus_message_iter_arguments_append(array_of_ec, "(iiii)", &struct_of_ec); + + eldbus_message_iter_arguments_append(struct_of_ec, "iiii", data->x, data->y, data->w, data->h); + eldbus_message_iter_container_close(array_of_ec, struct_of_ec); + + _input_rect_draw(data->x, data->y, data->w, data->h, time, color_r, color_g, color_b); + } + eldbus_message_iter_container_close(iter, array_of_ec); + + EINA_LIST_FREE(list, data); + list = NULL; +} + +static Eldbus_Message * +_e_info_server_cb_input_region(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply = eldbus_message_method_return_new(msg); + Eldbus_Message_Iter *iter = eldbus_message_iter_get(reply); + + Evas_Object *o; + E_Client *ec; + Ecore_Window win; + uint64_t win_id_value = 0; + const char *win_id_str = NULL; + unsigned long tmp = 0; + int time = 0, color_r = 0, color_g = 0, color_b = 0; + Eina_Bool res = EINA_FALSE; + + if (!eldbus_message_arguments_get(msg, "siiii", &win_id_str, &time, &color_r, &color_g, &color_b)) + { + ERR("Error getting arguments."); + return reply; + } + if (!e_comp) return reply; + + if (strlen(win_id_str) >= 2 && win_id_str[0] == '0' && win_id_str[1] == 'x') + res = e_util_string_to_ulong(win_id_str, &tmp, 16); + else + res = e_util_string_to_ulong(win_id_str, &tmp, 10); + if (res == EINA_FALSE) + { + ERR("input_region: invalid input arguments"); + return eldbus_message_error_new(msg, INVALID_ARGS, + "input_region: invalid input arguments"); + } + win_id_value = (uint64_t)tmp; + + for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o)) + { + ec = evas_object_data_get(o, "E_Client"); + if (!ec) continue; + if (e_client_util_ignored_get(ec)) continue; + + win = e_client_util_win_get(ec); + if (!win || win != win_id_value) continue; + + _input_region_msg_clients_append(iter, o, time, color_r, color_g, color_b); + break; } return reply; @@ -5530,6 +5688,7 @@ static const Eldbus_Method methods[] = { { "deiconify_approve", ELDBUS_ARGS({"it", "option"}), ELDBUS_ARGS({"s", "deiconify_approve status"}), _e_info_server_cb_deiconify_approve, 0}, { "key_repeat", ELDBUS_ARGS({"sii", "option"}), NULL, _e_info_server_cb_key_repeat, 0}, { "dump_memchecker", NULL, NULL, _e_info_server_cb_memchecker, 0}, + { "input_region", ELDBUS_ARGS({"siiii", "options"}), ELDBUS_ARGS({"a(iiii)", "path"}), _e_info_server_cb_input_region, 0}, { NULL, NULL, NULL, NULL, 0 } }; -- 2.34.1