#define VALUE_TYPE_REPLY_RESLIST "ssi"
#define VALUE_TYPE_FOR_INPUTDEV "ssi"
#define VALUE_TYPE_FOR_PENDING_COMMIT "uiuu"
+#define VALUE_TYPE_REQUEST_FOR_KILL "uts"
+#define VALUE_TYPE_REPLY_KILL "s"
static E_Info_Client e_info_client;
static Eina_Bool compobjs_simple = EINA_FALSE;
-static int keepRunning = 1;
static void end_program(int sig);
static Eina_Bool _e_info_client_eldbus_message(const char *method, E_Info_Message_Cb cb);
static Eina_Bool _e_info_client_eldbus_message_with_args(const char *method, E_Info_Message_Cb cb, const char *signature, ...);
return EINA_TRUE;
}
+static Eina_Bool
+_util_string_to_ulong(const char *str, unsigned long *num, int base)
+{
+ char *end;
+ int errsv;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(num, EINA_FALSE);
+
+ const long sul = strtoul(str, &end, base);
+ errsv = errno;
+
+ EINA_SAFETY_ON_TRUE_RETURN_VAL((end == str), EINA_FALSE); /* given string is not a decimal number */
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(('\0' != *end), EINA_FALSE); /* given string has extra characters */
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(((ULONG_MAX == sul) && (ERANGE == errsv)), EINA_FALSE); /* out of range of type unsigned long */
+
+ *num = (int)sul;
+
+ return EINA_TRUE;
+}
+
+static void
+_e_signal_get_window_under_touch(void *data, const Eldbus_Message *msg)
+{
+ Eina_Bool res;
+ uint64_t w;
+ Ecore_Window *win = data;
+
+ res = eldbus_message_arguments_get(msg, "t", &w);
+ EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+
+ *win = (Ecore_Window)w;
+
+finish:
+ ecore_main_loop_quit();
+}
+
+static void
+_e_message_get_window_under_touch(const Eldbus_Message *msg)
+{
+ const char *name = NULL, *text = NULL;
+ Eina_Bool res;
+ int result = 0;
+
+ res = eldbus_message_error_get(msg, &name, &text);
+ EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+ res = eldbus_message_arguments_get(msg, "i", &result);
+ EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+ EINA_SAFETY_ON_TRUE_GOTO(result, finish);
+
+ return;
+
+finish:
+ if ((name) || (text))
+ {
+ printf("errname:%s errmsg:%s\n", name, text);
+ }
+
+ ecore_main_loop_quit();
+}
+
+static int
+_e_get_window_under_touch(Ecore_Window *win)
+{
+ Eina_Bool res;
+ Eldbus_Signal_Handler *signal_handler = NULL;
+
+ *win = 0;
+
+ signal_handler = eldbus_proxy_signal_handler_add(e_info_client.proxy, "win_under_touch", _e_signal_get_window_under_touch, win);
+ EINA_SAFETY_ON_NULL_GOTO(signal_handler, fail);
+
+ res = _e_info_client_eldbus_message("get_win_under_touch",
+ _e_message_get_window_under_touch);
+ EINA_SAFETY_ON_FALSE_GOTO(res, fail);
+
+ ecore_main_loop_begin();
+
+ eldbus_signal_handler_del(signal_handler);
+
+ return 0;
+
+fail:
+ if (signal_handler)
+ eldbus_signal_handler_del(signal_handler);
+
+ return -1;
+}
+
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)
{
static void
_e_info_client_proc_fps_info(int argc, char **argv)
{
- keepRunning = 1;
-
do
{
if (!_e_info_client_eldbus_message("get_fps_info", _cb_fps_info_get))
return;
usleep(500000);
}
- while (keepRunning);
+ while (1);
}
static Eina_Bool
}
+#define KILL_USAGE \
+ "[COMMAND] [ARG]...\n" \
+ "\t-id : the identifier for the resource whose creator is to be killed.\n" \
+ "\t-name : the name for the resource whose creator is to be killed.\n" \
+ "\t-pid : the pid for the resource whose creator is to be killed.\n" \
+ "\t-all : kill all clients with top level windows\n" \
+ "\t-help\n" \
+ "Example:\n" \
+ "\tenlightenment_info -kill\n" \
+ "\tenlightenment_info -kill [win_id]\n" \
+ "\tenlightenment_info -kill -id [win_id]\n" \
+ "\tenlightenment_info -kill -name [win_name]\n" \
+ "\tenlightenment_info -kill -pid [pid]\n" \
+ "\tenlightenment_info -kill -all\n" \
+ "\tenlightenment_info -kill -help\n" \
+
static void
_e_info_client_proc_screen_rotation(int argc, char **argv)
{
printf("%s\n", result);
return;
+
+finish:
+ if ((name) || (text))
+ {
+ printf("errname:%s errmsg:%s\n", name, text);
+ }
+}
+
+static void
+_e_info_client_cb_kill_client(const Eldbus_Message *msg)
+{
+ const char *name = NULL, *text = NULL;
+ Eina_Bool res;
+ const char *result = NULL;
+ Eldbus_Message_Iter *array_of_string;
+
+ res = eldbus_message_error_get(msg, &name, &text);
+ EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+ res = eldbus_message_arguments_get(msg, "a"VALUE_TYPE_REPLY_KILL, &array_of_string);
+ EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+
+ while (eldbus_message_iter_get_and_next(array_of_string, 's', &result))
+ {
+ printf("%s\n", result);
+ }
+
+ return;
+
finish:
if ((name) || (text))
{
printf("%s\n", USAGE_REMOTE_SURFACE);
}
+static void
+_e_info_client_proc_kill_client(int argc, char **argv)
+{
+ const static int KILL_ID_MODE = 1;
+ const static int KILL_NAME_MODE = 2;
+ const static int KILL_PID_MODE = 3;
+ const static int KILL_ALL_MODE = 4;
+ Eina_Bool res;
+ uint64_t uint64_value;
+ const char *str_value = "";
+ uint32_t mode;
+
+ if (argc == 2)
+ {
+ mode = KILL_ID_MODE;
+ printf("Select the window whose client you wish to kill\n");
+ if (_e_get_window_under_touch((Ecore_Window *)&uint64_value))
+ {
+ printf("Error: cannot get window under touch\n");
+ return;
+ }
+ }
+ else if (argc == 3)
+ {
+ if (eina_streq(argv[2], "-all"))
+ mode = KILL_ALL_MODE;
+ else if (eina_streq(argv[2], "-help"))
+ goto usage;
+ else
+ {
+ mode = KILL_ID_MODE;
+ if (strlen(argv[2]) >= 2 && argv[2][0] == '0' && argv[2][1] == 'x')
+ res = _util_string_to_ulong(argv[2], (unsigned long *)&uint64_value, 16);
+ else
+ res = _util_string_to_ulong(argv[2], (unsigned long *)&uint64_value, 10);
+
+ EINA_SAFETY_ON_FALSE_GOTO(res, usage);
+ }
+ }
+ else if (argc == 4)
+ {
+ if (eina_streq(argv[2], "-id"))
+ {
+ mode = KILL_ID_MODE;
+ if (strlen(argv[3]) >= 2 && argv[3][0] == '0' && argv[3][1] == 'x')
+ res = _util_string_to_ulong(argv[3], (unsigned long *)&uint64_value, 16);
+ else
+ res = _util_string_to_ulong(argv[3], (unsigned long *)&uint64_value, 10);
+
+ EINA_SAFETY_ON_FALSE_GOTO(res, usage);
+ }
+ else if (eina_streq(argv[2], "-name"))
+ {
+ mode = KILL_NAME_MODE;
+ str_value = argv[3];
+ }
+ else if (eina_streq(argv[2], "-pid"))
+ {
+ mode = KILL_PID_MODE;
+ if (strlen(argv[3]) >= 2 && argv[3][0] == '0' && argv[3][1] == 'x')
+ res = _util_string_to_ulong(argv[3], (unsigned long *)&uint64_value, 16);
+ else
+ res = _util_string_to_ulong(argv[3], (unsigned long *)&uint64_value, 10);
+
+ EINA_SAFETY_ON_FALSE_GOTO(res, usage);
+ }
+ else
+ goto usage;
+ }
+ else
+ goto usage;
+
+ res = _e_info_client_eldbus_message_with_args("kill_client",
+ _e_info_client_cb_kill_client,
+ VALUE_TYPE_REQUEST_FOR_KILL,
+ mode, uint64_value, str_value);
+ EINA_SAFETY_ON_FALSE_RETURN(res);
+
+ return;
+usage:
+ printf("Usage: enlightenment_info %s", KILL_USAGE);
+}
+
static struct
{
const char *option;
USAGE_REMOTE_SURFACE,
"for remote surface debugging",
_e_info_client_proc_remote_surface
+ },
+ {
+ "kill",
+ KILL_USAGE,
+ "kill a client",
+ _e_info_client_proc_kill_client
}
};
static void
end_program(int sig)
{
- keepRunning = 0;
+ ecore_main_loop_quit();
+ /* disconnecting dbus */
+ _e_info_client_eldbus_disconnect();
+ exit(EXIT_FAILURE);
}
int
#define VALUE_TYPE_REPLY_RESLIST "ssi"
#define VALUE_TYPE_FOR_INPUTDEV "ssi"
#define VALUE_TYPE_FOR_PENDING_COMMIT "uiuu"
+#define VALUE_TYPE_REQUEST_FOR_KILL "uts"
+#define VALUE_TYPE_REPLY_KILL "s"
+
+enum
+{
+ E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH = 0
+};
static E_Info_Transform *_e_info_transform_new(E_Client *ec, int id, int enable, int x, int y, int sx, int sy, int degree, int background);
static E_Info_Transform *_e_info_transform_find(E_Client *ec, int id);
Eldbus_Message_Iter *array_of_ec;
E_Client *ec;
Evas_Object *o;
- uint32_t value_number = 0;
+ uint64_t value_number = 0;
Eina_Bool res = EINA_FALSE;
eldbus_message_iter_arguments_append(iter, "a(ss)", &array_of_ec);
else
{
if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
- res = e_util_string_to_uint(value, &value_number, 16);
+ res = e_util_string_to_ulong(value, (unsigned long *)&value_number, 16);
else
- res = e_util_string_to_uint(value, &value_number, 10);
+ res = e_util_string_to_ulong(value, (unsigned long *)&value_number, 10);
EINA_SAFETY_ON_FALSE_GOTO(res, finish);
}
uint32_t x, y, sx, sy, degree;
uint32_t background;
const char *value = NULL;
- uint32_t value_number;
+ uint64_t value_number;
Evas_Object *o;
E_Client *ec;
Eina_Bool res = EINA_FALSE;
}
if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
- res = e_util_string_to_uint(value, &value_number, 16);
+ res = e_util_string_to_ulong(value, (unsigned long *)&value_number, 16);
else
- res = e_util_string_to_uint(value, &value_number, 10);
+ res = e_util_string_to_ulong(value, (unsigned long *)&value_number, 10);
EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
Eldbus_Message_Iter *opt_iter;
const char *win_str, *key, *val, *opt;
Eina_List *options = NULL;
- uint32_t win_id = 0;
+ uint64_t win_id = 0;
E_Client *ec;
Evas_Object *o;
Eina_Bool res = EINA_FALSE;
options = eina_list_append(options, str);
}
- res = e_util_string_to_uint(win_str, &win_id, 16);
+ res = e_util_string_to_ulong(win_str, (unsigned long *)&win_id, 16);
EINA_SAFETY_ON_FALSE_RETURN_VAL(res, reply);
for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
return reply;
}
+static Ecore_Window
+_e_info_server_top_win_at_xy_get(int x, int y)
+{
+ Evas_Object *o;
+ E_Client *ec;
+
+ o = evas_object_top_at_xy_get(e_comp->evas, x, y, EINA_FALSE, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0);
+
+ ec = evas_object_data_get(o, "E_Client");
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ec, 0);
+
+ return e_client_util_win_get(ec);
+}
+
+static Eina_Bool
+_e_info_server_cb_ecore_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void *event)
+{
+ Ecore_Event_Mouse_Button *e;
+ Ecore_Window win;
+ Ecore_Event_Filter **event_filter;
+
+ if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN && type != ECORE_EVENT_MOUSE_BUTTON_UP
+ && type != ECORE_EVENT_MOUSE_MOVE && type != ECORE_EVENT_MOUSE_WHEEL
+ && type != ECORE_EVENT_MOUSE_IN && type != ECORE_EVENT_MOUSE_OUT)
+ return EINA_TRUE;
+
+ if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
+ {
+ e = event;
+ event_filter = data;
+
+ win = _e_info_server_top_win_at_xy_get(e->x, e->y);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(win, EINA_FALSE);
+
+ ecore_event_filter_del(*event_filter);
+ free(event_filter);
+
+ eldbus_service_signal_emit(e_info_server.iface, E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH, (uint64_t)win);
+ }
+
+ return EINA_FALSE;
+}
+
+static Eldbus_Message *
+_e_info_server_cb_get_win_under_touch(const Eldbus_Service_Interface *iface EINA_UNUSED,
+ const Eldbus_Message *msg)
+{
+ int result = 0;
+ Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+ Ecore_Event_Filter **event_filter;;
+
+ event_filter = calloc(1, sizeof(Ecore_Event_Filter *));
+ EINA_SAFETY_ON_NULL_GOTO(event_filter, fail);
+
+ *event_filter = ecore_event_filter_add(NULL, _e_info_server_cb_ecore_event_filter,
+ NULL, event_filter);
+ EINA_SAFETY_ON_NULL_GOTO(*event_filter, fail);
+
+ goto finish;
+
+fail:
+ result = -1;
+ if (event_filter)
+ free(event_filter);
+
+finish:
+ eldbus_message_arguments_append(reply, "i", result);
+
+ return reply;
+}
+
+static E_Client *
+_e_info_server_ec_find_by_win(Ecore_Window win)
+{
+ E_Client *ec;
+ Evas_Object *o;
+
+ for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+ {
+ Ecore_Window w;
+
+ ec = evas_object_data_get(o, "E_Client");
+ if (!ec) continue;
+ if (e_client_util_ignored_get(ec)) continue;
+
+ w = e_client_util_win_get(ec);
+ if (w == win)
+ return ec;
+ }
+
+ return NULL;
+}
+
+const static int KILL_ID_MODE = 1;
+const static int KILL_NAME_MODE = 2;
+const static int KILL_PID_MODE = 3;
+const static int KILL_ALL_MODE = 4;
+
+static int
+_e_info_server_ec_kill(uint32_t mode, void *value, Eldbus_Message_Iter *array_of_string)
+{
+ E_Client *ec;
+ Evas_Object *o;
+ int count = 0;
+ char result[1024];
+
+ for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+ {
+ const char *ec_name, *find;
+
+ ec = evas_object_data_get(o, "E_Client");
+ if (!ec) continue;
+ if (e_client_util_ignored_get(ec)) continue;
+
+ ec_name = e_client_util_name_get(ec) ?: "NO NAME";
+
+ if (mode == KILL_NAME_MODE)
+ {
+ find = strstr(ec_name, (const char *)value);
+
+ if (!find)
+ continue;
+ }
+ else if (mode == KILL_PID_MODE)
+ {
+ pid_t pid = -1;
+ pid = ec->netwm.pid;
+ if (pid <= 0)
+ {
+ if (ec->comp_data)
+ {
+ E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+ if (cdata->surface)
+ wl_client_get_credentials(wl_resource_get_client(cdata->surface), &pid, NULL, NULL);
+ }
+ }
+ if (pid != *(pid_t *)value)
+ continue;
+ }
+
+ count++;
+ e_client_act_kill_begin(ec);
+
+ snprintf(result, sizeof(result),
+ "[Server] killing creator(%s) of resource 0x%lx",
+ ec_name, (unsigned long)e_client_util_win_get(ec));
+ eldbus_message_iter_arguments_append(array_of_string, VALUE_TYPE_REPLY_KILL, result);
+ }
+
+ return count;
+}
+
+static Eldbus_Message *
+_e_info_server_cb_kill_client(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);
+ Eina_Bool res;
+ char result[1024];
+ E_Client *ec;
+ uint64_t uint64_value;
+ uint32_t mode;
+ const char *str_value;
+ int count;
+ Eldbus_Message_Iter *array_of_string;
+
+ res = eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_FOR_KILL,
+ &mode, &uint64_value, &str_value);
+ if (res != EINA_TRUE)
+ {
+ snprintf(result, sizeof(result),
+ "[Server] Error: cannot get the arguments from an Eldbus_Message");
+ goto finish;
+ }
+
+ eldbus_message_iter_arguments_append(iter, "a"VALUE_TYPE_REPLY_KILL, &array_of_string);
+
+ if (mode == KILL_ID_MODE)
+ {
+ Ecore_Window win = uint64_value;
+
+ ec = _e_info_server_ec_find_by_win(win);
+ if (!ec)
+ {
+ snprintf(result, sizeof(result),
+ "[Server] Error: cannot find the E_Client.");
+ goto finish;
+ }
+
+ e_client_act_kill_begin(ec);
+
+ snprintf(result, sizeof(result),
+ "[Server] killing creator(%s) of resource 0x%lx",
+ e_client_util_name_get(ec) ?: "NO NAME", (unsigned long)win);
+ }
+ else if (mode >= KILL_NAME_MODE && mode <= KILL_ALL_MODE)
+ {
+ if (mode == KILL_NAME_MODE)
+ count = _e_info_server_ec_kill(mode, (void *)str_value, array_of_string);
+ else
+ count = _e_info_server_ec_kill(mode, (void *)&uint64_value, array_of_string);
+
+ snprintf(result, sizeof(result),
+ "\n[Server] killed %d client(s)", count);
+ }
+ else
+ {
+ snprintf(result, sizeof(result), "[Server] Error: wrong mode.");
+ }
+
+finish:
+ eldbus_message_iter_arguments_append(array_of_string, VALUE_TYPE_REPLY_KILL, result);
+ eldbus_message_iter_container_close(iter, array_of_string);
+
+ return reply;
+}
+
//{ "method_name", arguments_from_client, return_values_to_client, _method_cb, ELDBUS_METHOD_FLAG },
static const Eldbus_Method methods[] = {
{ "get_window_info", NULL, ELDBUS_ARGS({"a("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
{ "frender", ELDBUS_ARGS({"i", "frender"}), ELDBUS_ARGS({"s", "force_render_result"}), _e_info_server_cb_force_render, 0},
{ "screen_rotation", ELDBUS_ARGS({"i", "value"}), NULL, _e_info_server_cb_screen_rotation, 0},
{ "remote_surface", ELDBUS_ARGS({"ii", "remote surface query"}), ELDBUS_ARGS({"as", "remote surfac information"}), _e_info_server_cb_remote_surface, 0},
+ { "get_win_under_touch", NULL, ELDBUS_ARGS({"i", "result"}), _e_info_server_cb_get_win_under_touch, 0 },
+ { "kill_client", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_KILL, "window"}), ELDBUS_ARGS({"a"VALUE_TYPE_REPLY_KILL, "kill result"}), _e_info_server_cb_kill_client, 0 },
{ NULL, NULL, NULL, NULL, 0 }
};
+static const Eldbus_Signal signals[] = {
+ [E_INFO_SERVER_SIGNAL_WIN_UNDER_TOUCH] = {"win_under_touch", ELDBUS_ARGS({ "t", "win_under_touch" }), 0},
+ { }
+};
+
static const Eldbus_Service_Interface_Desc iface_desc = {
- IFACE, methods, NULL, NULL, NULL, NULL
+ IFACE, methods, signals, NULL, NULL, NULL
};
Eina_Bool