From 5e771a6cb6123d3e19a8b7913ef8a84ee8dd9a4b Mon Sep 17 00:00:00 2001 From: Ju Yeon Lee Date: Thu, 11 Feb 2016 14:46:22 +0900 Subject: [PATCH] enlightenment_info: added reslist Change-Id: I005a3b684a527dfc6971d0318e36a5e85d2f514e --- src/bin/e_info_client.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/e_info_server.c | 92 +++++++++++++++++++++ 2 files changed, 302 insertions(+) diff --git a/src/bin/e_info_client.c b/src/bin/e_info_client.c index fd3513b..17077c5 100644 --- a/src/bin/e_info_client.c +++ b/src/bin/e_info_client.c @@ -35,6 +35,8 @@ typedef struct _E_Win_Info } E_Win_Info; #define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiibbs" +#define VALUE_TYPE_REQUEST_RESLIST "ui" +#define VALUE_TYPE_REPLY_RESLIST "ssi" static E_Info_Client e_info_client; @@ -553,6 +555,209 @@ arg_err: printf("Usage: enlightenment_info -rotation %s", ROTATION_USAGE); } +#define RESLIST_USAGE \ + "\t-tree : All resources\n" \ + "\t-p {pid} : Specify client pid\n" + +enum +{ + DEFAULT_SUMMARY = 0, + TREE, + PID +}; + +static void +_pname_get(pid_t pid, char *name, int size) +{ + if (!name) return; + + FILE *h; + char proc[512], pname[512]; + size_t len; + + snprintf(proc, 512,"/proc/%d/cmdline", pid); + + h = fopen(proc, "r"); + if (!h) return; + + len = fread(pname, sizeof(char), 512, h); + if (len > 0) + { + if ('\n' == pname[len - 1]) + pname[len - 1] = '\0'; + } + + fclose(h); + + strncpy(name, pname, size); +} + + +static void +_cb_disp_res_lists_get(const Eldbus_Message *msg) +{ + const char *name = NULL, *text = NULL; + Eldbus_Message_Iter *array, *resource; + Eina_Bool res; + int nClient = 0, nResource = 0; + char temp[PATH_MAX]; + int pid = 0; + + 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_RESLIST")", &array); + EINA_SAFETY_ON_FALSE_GOTO(res, finish); + + snprintf(temp, PATH_MAX,"%6s %6s %s %s\n", "NO", "PID", "N_of_Res", "NAME"); + printf("%s",temp); + + while (eldbus_message_iter_get_and_next(array, 'r', &resource)) + { + char cmd[512] = {0, }; + const char *type; + const char *item; + int id = 0; + res = eldbus_message_iter_arguments_get(resource, + VALUE_TYPE_REPLY_RESLIST, + &type, + &item, + &id); + if (!res) + { + printf("Failed to get connected clients info\n"); + continue; + } + if (!strcmp(type, "[client]")) + { + pid = id; + nResource = 0; + ++nClient; + } + else if (!strcmp(type, "[count]")) + { + nResource = id; + _pname_get(pid, cmd, sizeof(cmd)); + + printf("%6d %6d %4d %9s\n", nClient, pid, nResource, cmd); + pid = 0; + } + } + +finish: + if ((name) || (text)) + { + printf("errname:%s errmsg:%s\n", name, text); + } +} + +static void +_cb_disp_res_lists_get_detail(const Eldbus_Message *msg) +{ + const char *name = NULL, *text = NULL; + Eldbus_Message_Iter *array, *resource; + Eina_Bool res; + int nClient = 0, nResource = 0; + + 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_RESLIST")", &array); + EINA_SAFETY_ON_FALSE_GOTO(res, finish); + + while (eldbus_message_iter_get_and_next(array, 'r', &resource)) + { + const char *type; + const char *item; + char cmd[512] = {0, }; + int id = 0, pid = 0, rid = 0; + + res = eldbus_message_iter_arguments_get(resource, + VALUE_TYPE_REPLY_RESLIST, + &type, + &item, + &id); + + if (!res) + { + printf("Failed to get connected clients info\n"); + continue; + } + if (!strcmp(type, "[client]")) + { + nResource = 0; + pid = id; + ++nClient; + _pname_get(pid, cmd, sizeof(cmd)); + printf("[%2d] pid %d (%s)\n", nClient, pid, cmd); + + } + else if (!strcmp(type, "[resource]")) + { + ++nResource; + rid = id; + printf(" |----- %s obj@%d\n", item, id); + } + + } + +finish: + if ((name) || (text)) + { + printf("errname:%s errmsg:%s\n", name, text); + } +} + +static void +_e_info_server_proc_res_lists(int argc, char **argv) +{ + uint32_t mode; + int pid = 0; + + if (argc == 2) + { + mode = DEFAULT_SUMMARY; + if (!_e_info_client_eldbus_message_with_args("get_res_lists", _cb_disp_res_lists_get, VALUE_TYPE_REQUEST_RESLIST, mode, pid)) + { + printf("%s error\n", __FUNCTION__); + return; + } + } + else if (argc == 3) + { + if (eina_streq(argv[2], "-tree")) mode = TREE; + else goto arg_err; + + if (!_e_info_client_eldbus_message_with_args("get_res_lists", _cb_disp_res_lists_get_detail, VALUE_TYPE_REQUEST_RESLIST, mode, pid)) + { + printf("%s error\n", __FUNCTION__); + return; + } + } + else if (argc == 4) + { + if (eina_streq(argv[2], "-p")) + { + mode = PID; + pid = atoi(argv[3]); + if (pid <= 0) goto arg_err; + } + else goto arg_err; + + if (!_e_info_client_eldbus_message_with_args("get_res_lists", _cb_disp_res_lists_get_detail, VALUE_TYPE_REQUEST_RESLIST, mode, pid)) + { + printf("%s error\n", __FUNCTION__); + return; + } + } + else goto arg_err; + + return; +arg_err: + printf("Usage: enlightenment_info -reslist\n%s", RESLIST_USAGE); + +} + static struct { const char *option; @@ -597,6 +802,11 @@ static struct "Send a message about rotation", _e_info_client_proc_rotation }, + { + "reslist", "[-tree|-p]", + "Print connected client's and their resources", + _e_info_server_proc_res_lists + } }; static void diff --git a/src/bin/e_info_server.c b/src/bin/e_info_server.c index 94f26bd..7065185 100644 --- a/src/bin/e_info_server.c +++ b/src/bin/e_info_server.c @@ -1,8 +1,10 @@ +#define E_COMP_WL #include "e.h" #include #include #ifdef HAVE_WAYLAND_ONLY #include +#include "e_comp_wl.h" #endif #define BUS "org.enlightenment.wm" @@ -20,6 +22,8 @@ typedef struct _E_Info_Server static E_Info_Server e_info_server; #define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiibbs" +#define VALUE_TYPE_REQUEST_RESLIST "ui" +#define VALUE_TYPE_REPLY_RESLIST "ssi" static void _msg_clients_append(Eldbus_Message_Iter *iter) @@ -152,6 +156,93 @@ _e_info_server_cb_connected_clients_get(const Eldbus_Service_Interface *iface EI return reply; } +#define wl_client_for_each(client, list) \ + for (client = 0, client = wl_client_from_link((list)->next); \ + wl_client_get_link(client) != (list); \ + client = wl_client_from_link(wl_client_get_link(client)->next)) + +static int resurceCnt = 0; + +static void +_e_info_server_get_resource(void *element, void *data) +{ + struct wl_resource *resource = element; + Eldbus_Message_Iter* array_of_res= data; + Eldbus_Message_Iter* struct_of_res; + + eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res); + eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[resource]", wl_resource_get_name(resource), wl_resource_get_id(resource)); + eldbus_message_iter_container_close(array_of_res, struct_of_res); + resurceCnt++; +} + +static void +_msg_clients_res_list_append(Eldbus_Message_Iter *iter, uint32_t mode, int id) +{ + Eldbus_Message_Iter *array_of_res; + + struct wl_list * client_list; + struct wl_client *client; + struct wl_map *res_objs; + //E_Comp_Data *cdata; + E_Comp_Wl_Data *cdata; + int pid = -1; + + enum { + DEFAULT_SUMMARY, + TREE, + PID} type = mode; + + eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_REPLY_RESLIST")", &array_of_res); + + if (!e_comp) return; + if (!(cdata = e_comp->wl_comp_data)) return; + if (!cdata->wl.disp) return; + + client_list = wl_display_get_client_list(cdata->wl.disp); + + wl_client_for_each(client, client_list) + { + Eldbus_Message_Iter* struct_of_res; + + wl_client_get_credentials(client, &pid, NULL, NULL); + + if ((type == PID) && (pid != id)) continue; + + eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res); + + eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[client]", "pid", pid); + eldbus_message_iter_container_close(array_of_res, struct_of_res); + + resurceCnt = 0; + res_objs = wl_client_get_resources(client); + wl_map_for_each(res_objs, _e_info_server_get_resource, array_of_res); + + eldbus_message_iter_arguments_append(array_of_res, "("VALUE_TYPE_REPLY_RESLIST")", &struct_of_res); + eldbus_message_iter_arguments_append(struct_of_res, VALUE_TYPE_REPLY_RESLIST, "[count]", "resurceCnt", resurceCnt); + eldbus_message_iter_container_close(array_of_res, struct_of_res); + } + eldbus_message_iter_container_close(iter, array_of_res); +} + +static Eldbus_Message * +_e_info_server_cb_res_lists_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply = eldbus_message_method_return_new(msg); + uint32_t mode = 0; + int pid = -1; + + if (!eldbus_message_arguments_get(msg, VALUE_TYPE_REQUEST_RESLIST, &mode, &pid)) + { + ERR("Error getting arguments."); + return reply; + } + + _msg_clients_res_list_append(eldbus_message_iter_get(reply), mode, pid); + + return reply; +} + static void _msg_window_prop_client_append(Eldbus_Message_Iter *iter, E_Client *target_ec) { @@ -572,6 +663,7 @@ static const Eldbus_Method methods[] = { { "get_connected_clients", NULL, ELDBUS_ARGS({"a(ss)", "array of ec"}), _e_info_server_cb_connected_clients_get, 0 }, { "rotation_query", ELDBUS_ARGS({"i", "query_rotation"}), NULL, _e_info_server_cb_rotation_query, 0}, { "rotation_message", ELDBUS_ARGS({"iii", "rotation_message"}), NULL, _e_info_server_cb_rotation_message, 0}, + { "get_res_lists", ELDBUS_ARGS({VALUE_TYPE_REQUEST_RESLIST, "client resource"}), ELDBUS_ARGS({"a("VALUE_TYPE_REPLY_RESLIST")", "array of client resources"}), _e_info_server_cb_res_lists_get, 0 }, { NULL, NULL, NULL, NULL, 0 } }; -- 2.7.4