[e_info] add the kill option
authorKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Wed, 12 Apr 2017 14:10:27 +0000 (17:10 +0300)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 25 May 2017 23:24:58 +0000 (08:24 +0900)
Change-Id: Ib1122cb6bdc5f163fe42129f7097965c1d97787a
Signed-off-by: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
src/bin/e_info_client.c
src/bin/e_info_server.c

index 08e432d0d0c810af0a29d66f555477b096ed78a7..649daf7be5f5b5e04ff8589e4fecb2990aa894a0 100644 (file)
@@ -76,7 +76,6 @@ 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, ...);
@@ -151,6 +150,75 @@ _util_string_to_double(const char *str, double *num)
    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)
 {
@@ -1557,15 +1625,13 @@ finish:
 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
@@ -2561,6 +2627,50 @@ _e_info_client_proc_screen_rotation(int argc, char **argv)
      printf("_e_info_client_eldbus_message_with_args error");
 }
 
+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;
+
+   res = eldbus_message_error_get(msg, &name, &text);
+   EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+   res = eldbus_message_arguments_get(msg, "s", &result);
+   EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+
+   printf("%s\n", result);
+   return;
+
+finish:
+   if ((name) || (text))
+     {
+        printf("errname:%s errmsg:%s\n", name, text);
+     }
+}
+
+static void
+_e_info_client_proc_kill_client(int argc, char **argv)
+{
+   Eina_Bool res;
+   Ecore_Window win;
+
+   printf("Select the window whose client you wish to kill\n");
+   if (_e_get_window_under_touch(&win))
+     {
+        printf("Error: cannot get window under touch\n");
+        return;
+     }
+
+   res = _e_info_client_eldbus_message_with_args("kill_client",
+                                                 _e_info_client_cb_kill_client,
+                                                 "t", (uint64_t)win);
+   EINA_SAFETY_ON_FALSE_RETURN(res);
+
+   return;
+}
+
 static struct
 {
    const char *option;
@@ -2754,6 +2864,13 @@ static struct
       "to rotate screen",
       _e_info_client_proc_screen_rotation
    },
+   {
+
+      "kill",
+       NULL,
+      "kill a client",
+      _e_info_client_proc_kill_client
+   }
 };
 
 static void
@@ -2901,7 +3018,10 @@ _e_info_client_print_usage(const char *exec)
 static void
 end_program(int sig)
 {
-   keepRunning = 0;
+   ecore_main_loop_quit();
+   /* disconnecting dbus */
+   _e_info_client_eldbus_disconnect();
+   exit(EXIT_FAILURE);
 }
 
 int
index 4a2f7ea5f043b1ad63ac07019ccbf9eed75c76ae..cda4ba1812bb28d9efa0c2304a3d2d046178f185 100755 (executable)
@@ -87,6 +87,11 @@ static Eina_List *module_hook = NULL;
 #define VALUE_TYPE_FOR_INPUTDEV "ssi"
 #define VALUE_TYPE_FOR_PENDING_COMMIT "uiuu"
 
+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);
 static void              _e_info_transform_set(E_Info_Transform *transform, int enable, int x, int y, int sx, int sy, int degree);
@@ -2969,6 +2974,136 @@ _e_info_server_cb_screen_rotation(const Eldbus_Service_Interface *iface EINA_UNU
    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;
+}
+
+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);
+   Eina_Bool res;
+   char result[1024];
+   E_Client *ec;
+   uint64_t win;
+
+   res = eldbus_message_arguments_get(msg, "t", &win);
+   if (res != EINA_TRUE)
+     {
+        snprintf(result, sizeof(result),
+                "[Server] Error: cannot get the arguments from an Eldbus_Message");
+        goto finish;
+     }
+
+   ec = _e_info_server_ec_find_by_win((Ecore_Window)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);
+
+finish:
+   eldbus_message_arguments_append(reply, "s", result);
+
+   return reply;
+}
+
 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 },
    { "compobjs", NULL, ELDBUS_ARGS({"a("SIGNATURE_COMPOBJS_CLIENT")", "array of comp objs"}), _e_info_server_cb_compobjs, 0 },
@@ -3009,11 +3144,18 @@ static const Eldbus_Method methods[] = {
    { "desk_zoom", ELDBUS_ARGS({"ddii", "Zoom"}), NULL, _e_info_server_cb_desk_zoom, 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},
+   { "get_win_under_touch", NULL, ELDBUS_ARGS({"i", "result"}), _e_info_server_cb_get_win_under_touch, 0 },
+   { "kill_client", ELDBUS_ARGS({"t", "window"}), ELDBUS_ARGS({"s", "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