[e_info] add the kill option 93/131193/2
authorKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Wed, 12 Apr 2017 14:10:27 +0000 (17:10 +0300)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 26 May 2017 05:45:39 +0000 (14:45 +0900)
- [e_info] add the kill option
- [e_info] use the uint64_t type instead the int32_t for window id
    We have some error when a window id exceeds INT_MAX, because
    the Ecore_Window is the uintptr_t type and the  window id the
    int32_t type. I think we need use the uint64_t(for arm7l and arm64)
    type instead the int32_t type for window id.
- [e_info] add the id suboption for the kill
- [e_info] add the name suboption for the kill
- [e_info] add the "-pid" and the "-all" suboptions for the kill

Change-Id: I304592eb6c1daf33e9203be1a15092d94b6f8006
Signed-off-by: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
Signed-off-by: SooChan Lim <sc1.lim@samsung.com>
src/bin/e_info_client.c
src/bin/e_info_server.c
src/bin/e_utils.c
src/bin/e_utils.h

index 70b2b0e9903b9b79cb9124b8327f463f77ffbffc..83b79fa24279a7563dee24016e0ae4960b47013e 100644 (file)
@@ -71,12 +71,13 @@ typedef struct _E_Pending_Commit_Info
 #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, ...);
@@ -151,6 +152,96 @@ _util_string_to_double(const char *str, double *num)
    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)
 {
@@ -1557,15 +1648,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
@@ -2539,6 +2628,22 @@ arg_err:
 
 }
 
+#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)
 {
@@ -2579,6 +2684,35 @@ _e_info_client_cb_remote_surface(const Eldbus_Message *msg)
      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))
      {
@@ -2624,6 +2758,89 @@ arg_err:
    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;
@@ -2822,6 +3039,12 @@ static struct
       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
    }
 };
 
@@ -2970,7 +3193,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 28c362978f1475ac21a7da33218843eab68a6aa8..d763de5d5ce7156c89ab6feb76846a47b6e3560d 100755 (executable)
@@ -87,6 +87,13 @@ static Eina_List *module_hook = NULL;
 #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);
@@ -1053,7 +1060,7 @@ _msg_window_prop_append(Eldbus_Message_Iter *iter, uint32_t mode, const char *va
    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);
@@ -1064,9 +1071,9 @@ _msg_window_prop_append(Eldbus_Message_Iter *iter, uint32_t mode, const char *va
         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);
           }
@@ -2024,7 +2031,7 @@ e_info_server_cb_transform_message(const Eldbus_Service_Interface *iface EINA_UN
    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;
@@ -2036,9 +2043,9 @@ e_info_server_cb_transform_message(const Eldbus_Service_Interface *iface EINA_UN
      }
 
    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);
 
@@ -2846,7 +2853,7 @@ e_info_server_cb_aux_message(const Eldbus_Service_Interface *iface EINA_UNUSED,
    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;
@@ -2871,7 +2878,7 @@ e_info_server_cb_aux_message(const Eldbus_Service_Interface *iface EINA_UNUSED,
         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))
@@ -3007,6 +3014,224 @@ _e_info_server_cb_remote_surface(const Eldbus_Service_Interface *iface EINA_UNUS
    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 },
@@ -3049,11 +3274,18 @@ static const Eldbus_Method methods[] = {
    { "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
index 9e9bbe07a6db775ee3b12504d3a7c5e4a312f5b8..557dfbbb360aa0c33b89c490a55fbb1432a2054e 100644 (file)
@@ -1067,6 +1067,27 @@ e_util_string_to_double(const char *str, double *num)
    return EINA_TRUE;
 }
 
+E_API Eina_Bool
+e_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;
+}
+
 E_API void
 e_util_evas_objects_above_print(Evas_Object *o)
 {
index cb4a21640b01534f5141a9c68d2b0be888ae957e..00ae522a51e4fb93b3de80ec58a4cbdb0b81b095 100644 (file)
@@ -58,6 +58,7 @@ E_API Eina_Bool e_util_string_to_uint(const char *str, unsigned int *num, int ba
 E_API Eina_Bool e_util_string_to_int(const char *str, int *num, int base);
 E_API Eina_Bool e_util_string_to_int_token(const char *str, char **next, int *num, int base);
 E_API Eina_Bool e_util_string_to_double(const char *str, double *num);
+E_API Eina_Bool e_util_string_to_ulong(const char *str, unsigned long *num, int base);
 
 E_API void e_util_evas_objects_above_print(Evas_Object *o);
 E_API void e_util_evas_objects_above_print_smart(Evas_Object *o);