e_devicemgr: release input events occurred by input generator 25/196625/7
authorjeon <jhyuni.kang@samsung.com>
Thu, 3 Jan 2019 05:07:41 +0000 (14:07 +0900)
committerjeon <jhyuni.kang@samsung.com>
Mon, 7 Jan 2019 07:50:52 +0000 (16:50 +0900)
  - input events must be paired up.
  - but sometimes client request touch/key/mouse down events
    and suddenly destroyed before request up events.
  - for prepare these issue, input generator release events
    if client is destroyed except up events.

Change-Id: I75624bf706bc792fa714bfa96bb624677f7f866c

src/bin/e_devicemgr_inputgen.c
src/bin/e_devicemgr_private.h

index 47153385c35ebb73dad9a01f0f1ac8c32d5210a7..da675f90c8acfd142f206a2ea5a6c306f1db46ff 100644 (file)
@@ -52,283 +52,6 @@ _e_devicemgr_inputgen_device_check(char *name, Ecore_Device_Class clas)
    return EINA_FALSE;
 }
 
-static void
-_e_devicemgr_inputgen_remove_device(E_Devicemgr_Inputgen_Device_Data *device)
-{
-   if (!device || device->uinp_fd < 0)
-     {
-        DMWRN("There are no devices created for input generation.\n");
-        return;
-     }
-
-   e_devicemgr_destroy_virtual_device(device->uinp_fd);
-   device->uinp_fd = -1;
-   eina_stringshare_del(device->identifier);
-   device->identifier = NULL;
-}
-
-static void
-_e_devicemgr_inputgen_client_device_remove(struct wl_client *client, Ecore_Device_Class clas)
-{
-   Eina_List **dev_list, *l, *l_next, *ll, *ll_next;
-   E_Devicemgr_Inputgen_Device_Data *ddata;
-   E_Devicemgr_Inputgen_Client_Data *cdata;
-
-   dev_list = _e_devicemgr_inputgen_list_get(clas);
-   EINA_SAFETY_ON_NULL_RETURN(dev_list);
-
-   EINA_LIST_FOREACH_SAFE(*dev_list, l, l_next, ddata)
-     {
-        EINA_LIST_FOREACH_SAFE(ddata->clients, ll, ll_next, cdata)
-          {
-             if (cdata->client == client)
-               {
-                  ddata->clients = eina_list_remove_list(ddata->clients, ll);
-                  E_FREE(cdata);
-               }
-          }
-        if (eina_list_count(ddata->clients) == 0)
-          {
-             _e_devicemgr_inputgen_remove_device(ddata);
-             *dev_list = eina_list_remove_list(*dev_list, l);
-             E_FREE(ddata);
-          }
-     }
-}
-
-static void
-_e_devicemgr_inputgen_client_cb_destroy(struct wl_listener *l, void *data)
-{
-   struct wl_client *client = (struct wl_client *)data;
-   E_Devicemgr_Inputgen_Resource_Data *rdata;
-   E_Devicemgr_Inputgen_Client_Global_Data *gdata;
-   Eina_List *list, *l_next;
-
-   EINA_SAFETY_ON_NULL_RETURN(l);
-
-   wl_list_remove(&l->link);
-   E_FREE(l);
-
-   EINA_LIST_FOREACH_SAFE(e_devicemgr->watched_clients, list, l_next, gdata)
-     {
-        if (gdata->client == client)
-          {
-             e_devicemgr->watched_clients =
-               eina_list_remove_list(e_devicemgr->watched_clients, list);
-             E_FREE(gdata);
-
-             break;
-          }
-     }
-
-   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_KEYBOARD);
-   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_MOUSE);
-   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_TOUCH);
-
-   EINA_LIST_FOREACH_SAFE(e_devicemgr->inputgen.resource_list, list, l_next, rdata)
-     {
-        if (wl_resource_get_client(rdata->resource) == client)
-          {
-             e_devicemgr->inputgen.resource_list =
-               eina_list_remove_list(e_devicemgr->inputgen.resource_list, list);
-             E_FREE(rdata);
-          }
-     }
-}
-
-static void
-_e_devicemgr_inputgen_client_add(struct wl_client *client, unsigned int clas)
-{
-   struct wl_listener *destroy_listener;
-   E_Devicemgr_Inputgen_Client_Global_Data *data;
-   Eina_List *l;
-
-   EINA_LIST_FOREACH(e_devicemgr->watched_clients, l, data)
-     {
-        if (data->client == client)
-          {
-             data->clas |= clas;
-             return;
-          }
-     }
-   data = NULL;
-
-   destroy_listener = E_NEW(struct wl_listener, 1);
-   EINA_SAFETY_ON_NULL_GOTO(destroy_listener, failed);
-   destroy_listener->notify = _e_devicemgr_inputgen_client_cb_destroy;
-   wl_client_add_destroy_listener(client, destroy_listener);
-
-   data = E_NEW(E_Devicemgr_Inputgen_Client_Global_Data, 1);
-   EINA_SAFETY_ON_NULL_GOTO(data, failed);
-
-   data->client = client;
-   data->clas = clas;
-
-   e_devicemgr->watched_clients =
-      eina_list_append(e_devicemgr->watched_clients, data);
-
-   return;
-
-failed:
-   if (destroy_listener)
-     {
-        wl_list_remove(&destroy_listener->link);
-        E_FREE(destroy_listener);
-     }
-}
-
-static void
-_e_devicemgr_inputgen_client_del(struct wl_client *client, unsigned int clas)
-{
-   E_Devicemgr_Inputgen_Client_Global_Data *data;
-   E_Devicemgr_Inputgen_Client_Data *cdata;
-   E_Devicemgr_Inputgen_Device_Data *ddata;
-   Eina_List *l, *ll, *l_next, *ll_next, **list;
-
-   list = _e_devicemgr_inputgen_list_get(clas);
-   EINA_SAFETY_ON_NULL_RETURN(list);
-
-   EINA_LIST_FOREACH_SAFE(*list, l, l_next, ddata)
-     {
-        EINA_LIST_FOREACH_SAFE(ddata->clients, ll, ll_next, cdata)
-          {
-             if (cdata->client == client)
-               {
-                  cdata->ref--;
-                  if (cdata->ref <= 0)
-                    {
-                       ddata->clients = eina_list_remove_list(ddata->clients, ll);
-                       E_FREE(cdata);
-                    }
-               }
-          }
-
-        if (eina_list_count(ddata->clients) == 0)
-          {
-             ddata->clients = NULL;
-             _e_devicemgr_inputgen_remove_device(ddata);
-             *list = eina_list_remove_list(*list, l);
-             E_FREE(ddata);
-          }
-     }
-
-   EINA_LIST_FOREACH(e_devicemgr->watched_clients, l, data)
-     {
-        if (data->client == client)
-          {
-             data->clas &= ~clas;
-          }
-     }
-}
-
-static void
-_e_devicemgr_inputgen_resource_add(struct wl_resource *resource, const char *name)
-{
-   E_Devicemgr_Inputgen_Resource_Data *rdata;
-   Eina_List *l;
-
-   EINA_LIST_FOREACH(e_devicemgr->inputgen.resource_list, l, rdata)
-     {
-        if (rdata->resource == resource) return;
-     }
-
-   rdata = NULL;
-   rdata = E_NEW(E_Devicemgr_Inputgen_Resource_Data, 1);
-   EINA_SAFETY_ON_NULL_RETURN(rdata);
-
-   rdata->resource = resource;
-   strncpy(rdata->name, name, UINPUT_MAX_NAME_SIZE - 1);
-
-   e_devicemgr->inputgen.resource_list = eina_list_append(e_devicemgr->inputgen.resource_list, rdata);
-}
-
-static void
-_e_devicemgr_inputgen_resource_del(struct wl_resource *resource)
-{
-   E_Devicemgr_Inputgen_Resource_Data *rdata;
-   Eina_List *l, *l_next;
-
-   EINA_LIST_FOREACH_SAFE(e_devicemgr->inputgen.resource_list, l, l_next, rdata)
-     {
-        if (rdata->resource == resource)
-          {
-             e_devicemgr->inputgen.resource_list =
-               eina_list_remove_list(e_devicemgr->inputgen.resource_list, l);
-             E_FREE(rdata);
-          }
-     }
-}
-
-int
-_e_devicemgr_inputgen_create_device(Ecore_Device_Class clas, struct wl_client *client, const char *device_name)
-{
-   int uinp_fd = -1;
-   Eina_List **dev_list, *l, *ll;
-   E_Devicemgr_Inputgen_Client_Data *cdata;
-   E_Devicemgr_Inputgen_Device_Data *ddata, *device = NULL;
-   Eina_Bool exist_device_flag = EINA_FALSE;
-
-   dev_list = _e_devicemgr_inputgen_list_get(clas);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dev_list, EINA_FALSE);
-
-   EINA_LIST_FOREACH(*dev_list, l, ddata)
-     {
-        if (!strncmp(ddata->name, device_name, UINPUT_MAX_NAME_SIZE))
-          {
-             EINA_LIST_FOREACH(ddata->clients, ll, cdata)
-               {
-                  if (cdata->client == client)
-                    {
-                       cdata->ref++;
-                       return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-                    }
-               }
-
-             device = ddata;
-             exist_device_flag = EINA_TRUE;
-             break;
-          }
-     }
-
-   if (!device)
-     {
-        device = E_NEW(E_Devicemgr_Inputgen_Device_Data, 1);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(device, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
-        strncpy(device->name, device_name, UINPUT_MAX_NAME_SIZE - 1);
-     }
-
-   cdata = E_NEW(E_Devicemgr_Inputgen_Client_Data, 1);
-   if(!cdata)
-     {
-        if (!exist_device_flag) E_FREE(device);
-        return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-     }
-
-   cdata->ref = 1;
-   cdata->client = client;
-
-   device->clients = eina_list_append(device->clients, cdata);
-
-   if (exist_device_flag)
-     return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
-   uinp_fd = e_devicemgr_create_virtual_device(clas, device_name);
-
-   if (uinp_fd < 0)
-     goto fail_create_device;
-
-   device->uinp_fd = uinp_fd;
-   *dev_list = eina_list_append(*dev_list, device);
-
-   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-
-fail_create_device:
-   EINA_LIST_FREE(device->clients, cdata)
-     E_FREE(cdata);
-   E_FREE(device);
-   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
-}
-
 static void
 _e_devicemgr_inputgen_key_event_free(void *data EINA_UNUSED, void *ev)
 {
@@ -449,132 +172,474 @@ _e_devicemgr_inputgen_mouse_move_event_free(void *data EINA_UNUSED, void *ev)
 {
    Ecore_Event_Mouse_Move *e = ev;
 
-   if (e->dev) ecore_device_unref(e->dev);
+   if (e->dev) ecore_device_unref(e->dev);
+
+   free(e);
+}
+
+int
+_e_devicemgr_inputgen_mouse_move_event(int x, int y, char *identifier)
+{
+   Ecore_Event_Mouse_Move *e;
+
+   DMERR("Try\n");
+
+   e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
+   if (!e) return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+
+   e->window = e_comp->ee_win;
+   e->event_window = e_comp->ee_win;
+   e->root_window = e_comp->ee_win;
+   e->timestamp = (int)(ecore_time_get() * 1000);
+   e->same_screen = 1;
+
+   e->x = x;
+   e->y = y;
+   e->root.x = e->x;
+   e->root.y = e->y;
+
+   e->multi.device = 0;
+   e->multi.radius = 1;
+   e->multi.radius_x = 1;
+   e->multi.radius_y = 1;
+   e->multi.pressure = 1.0;
+   e->multi.angle = 0.0;
+
+   e->multi.x = e->x;
+   e->multi.y = e->y;
+   e->multi.root.x = e->x;
+   e->multi.root.y = e->y;
+   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_MOUSE));
+
+   DMDBG("Generate mouse move event: (%d, %d)\n", e->x, e->y);
+
+   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+
+   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+static int
+_e_devicemgr_inputgen_touch_event(uint32_t type, uint32_t x, uint32_t y, uint32_t finger, char *identifier)
+{
+   Ecore_Event_Mouse_Button *e;
+
+   e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+
+   e->window = e_comp->ee_win;
+   e->event_window = e_comp->ee_win;
+   e->root_window = e_comp->ee_win;
+   e->timestamp = (int)(ecore_time_get() * 1000);
+   e->same_screen = 1;
+
+   e->x = x;
+   e->y = y;
+   e->root.x = e->x;
+   e->root.y = e->y;
+
+   e->multi.device = finger;
+   e->multi.radius = 1;
+   e->multi.radius_x = 1;
+   e->multi.radius_y = 1;
+   e->multi.pressure = 1.0;
+   e->multi.angle = 0.0;
+
+   e->multi.x = e->x;
+   e->multi.y = e->y;
+   e->multi.root.x = e->x;
+   e->multi.root.y = e->y;
+   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_TOUCH));
+   e->buttons = 1;
+
+   DMDBG("Generate touch event: device: %d (%d, %d)\n", e->multi.device, e->x, e->y);
+
+   if (type == TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN)
+     ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
+   else
+     ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
+
+   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+static int
+_e_devicemgr_inputgen_touch_update_event(uint32_t x, uint32_t y, uint32_t finger, char *identifier)
+{
+   Ecore_Event_Mouse_Move *e;
+
+   e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+
+   e->window = e_comp->ee_win;
+   e->event_window = e_comp->ee_win;
+   e->root_window = e_comp->ee_win;
+   e->timestamp = (int)(ecore_time_get() * 1000);
+   e->same_screen = 1;
+
+   e->x = x;
+   e->y = y;
+   e->root.x = e->x;
+   e->root.y = e->y;
+
+   e->multi.device = finger;
+   e->multi.radius = 1;
+   e->multi.radius_x = 1;
+   e->multi.radius_y = 1;
+   e->multi.pressure = 1.0;
+   e->multi.angle = 0.0;
+
+   e->multi.x = e->x;
+   e->multi.y = e->y;
+   e->multi.root.x = e->x;
+   e->multi.root.y = e->y;
+   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_TOUCH));
+
+   DMDBG("Generate touch move event: device: %d (%d, %d)\n", e->multi.device, e->x, e->y);
+
+   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+
+   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+}
+
+static void
+_e_devicemgr_inputgen_remove_device(E_Devicemgr_Inputgen_Device_Data *device)
+{
+   int i = 0, ret;
+   Eina_List *l, *l_next;
+   Eina_Stringshare *str_data;
+
+   if (!device || device->uinp_fd < 0)
+     {
+        DMWRN("There are no devices created for input generation.\n");
+        return;
+     }
+
+   switch (device->clas)
+     {
+        case ECORE_DEVICE_CLASS_TOUCH:
+          while (device->touch.pressed)
+            {
+               if (device->touch.pressed & (1 << i))
+                 {
+                    ret = _e_devicemgr_inputgen_touch_event(
+                            TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END,
+                            device->touch.coords[i].x,
+                            device->touch.coords[i].y,
+                            i, device->identifier);
+                    if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
+                      DMWRN("Failed to generate touch up event: %d\n", ret);
+                    device->touch.pressed &= ~(1 << i);
+                 }
+               i++;
+               if (i >= INPUTGEN_MAX_TOUCH) break;
+            }
+          break;
+        case ECORE_DEVICE_CLASS_MOUSE:
+          while (device->mouse.pressed)
+            {
+               if (device->mouse.pressed & (1 << i))
+                 {
+                    ret = _e_devicemgr_inputgen_mouse_button_event(
+                            EINA_FALSE,
+                            device->mouse.coords.x,
+                            device->mouse.coords.y,
+                            i + 1, device->identifier);
+                    if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
+                      DMWRN("Failed to generate mouse button up event: %d\n", ret);
+                    device->mouse.pressed &= ~(1 << i);
+                 }
+               i++;
+               if (i >= INPUTGEN_MAX_BTN) break;
+            }
+          break;
+        case ECORE_DEVICE_CLASS_KEYBOARD:
+          EINA_LIST_FOREACH_SAFE(device->key.pressed, l, l_next, str_data)
+            {
+               ret = _e_devicemgr_inputgen_key_event_add(str_data, EINA_FALSE, device->identifier);
+               if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
+                 DMWRN("Failed to generate key up event: %d\n", ret);
+               eina_stringshare_del(str_data);
+               device->key.pressed = eina_list_remove_list(device->key.pressed, l);
+            }
+          break;
+        default:
+          break;
+     }
+
+   e_devicemgr_destroy_virtual_device(device->uinp_fd);
+   device->uinp_fd = -1;
+   eina_stringshare_del(device->identifier);
+   device->identifier = NULL;
+}
+
+static void
+_e_devicemgr_inputgen_client_device_remove(struct wl_client *client, Ecore_Device_Class clas)
+{
+   Eina_List **dev_list, *l, *l_next, *ll, *ll_next;
+   E_Devicemgr_Inputgen_Device_Data *ddata;
+   E_Devicemgr_Inputgen_Client_Data *cdata;
+
+   dev_list = _e_devicemgr_inputgen_list_get(clas);
+   EINA_SAFETY_ON_NULL_RETURN(dev_list);
+
+   EINA_LIST_FOREACH_SAFE(*dev_list, l, l_next, ddata)
+     {
+        EINA_LIST_FOREACH_SAFE(ddata->clients, ll, ll_next, cdata)
+          {
+             if (cdata->client == client)
+               {
+                  ddata->clients = eina_list_remove_list(ddata->clients, ll);
+                  E_FREE(cdata);
+               }
+          }
+        if (eina_list_count(ddata->clients) == 0)
+          {
+             _e_devicemgr_inputgen_remove_device(ddata);
+             *dev_list = eina_list_remove_list(*dev_list, l);
+             E_FREE(ddata);
+          }
+     }
+}
+
+static void
+_e_devicemgr_inputgen_client_cb_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_client *client = (struct wl_client *)data;
+   E_Devicemgr_Inputgen_Resource_Data *rdata;
+   E_Devicemgr_Inputgen_Client_Global_Data *gdata;
+   Eina_List *list, *l_next;
+
+   EINA_SAFETY_ON_NULL_RETURN(l);
+
+   wl_list_remove(&l->link);
+   E_FREE(l);
+
+   EINA_LIST_FOREACH_SAFE(e_devicemgr->watched_clients, list, l_next, gdata)
+     {
+        if (gdata->client == client)
+          {
+             e_devicemgr->watched_clients =
+               eina_list_remove_list(e_devicemgr->watched_clients, list);
+             E_FREE(gdata);
+
+             break;
+          }
+     }
+
+   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_KEYBOARD);
+   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_MOUSE);
+   _e_devicemgr_inputgen_client_device_remove(client, ECORE_DEVICE_CLASS_TOUCH);
+
+   EINA_LIST_FOREACH_SAFE(e_devicemgr->inputgen.resource_list, list, l_next, rdata)
+     {
+        if (wl_resource_get_client(rdata->resource) == client)
+          {
+             e_devicemgr->inputgen.resource_list =
+               eina_list_remove_list(e_devicemgr->inputgen.resource_list, list);
+             E_FREE(rdata);
+          }
+     }
+}
+
+static void
+_e_devicemgr_inputgen_client_add(struct wl_client *client, unsigned int clas)
+{
+   struct wl_listener *destroy_listener;
+   E_Devicemgr_Inputgen_Client_Global_Data *data;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(e_devicemgr->watched_clients, l, data)
+     {
+        if (data->client == client)
+          {
+             data->clas |= clas;
+             return;
+          }
+     }
+   data = NULL;
+
+   destroy_listener = E_NEW(struct wl_listener, 1);
+   EINA_SAFETY_ON_NULL_GOTO(destroy_listener, failed);
+   destroy_listener->notify = _e_devicemgr_inputgen_client_cb_destroy;
+   wl_client_add_destroy_listener(client, destroy_listener);
+
+   data = E_NEW(E_Devicemgr_Inputgen_Client_Global_Data, 1);
+   EINA_SAFETY_ON_NULL_GOTO(data, failed);
+
+   data->client = client;
+   data->clas = clas;
+
+   e_devicemgr->watched_clients =
+      eina_list_append(e_devicemgr->watched_clients, data);
 
-   free(e);
+   return;
+
+failed:
+   if (destroy_listener)
+     {
+        wl_list_remove(&destroy_listener->link);
+        E_FREE(destroy_listener);
+     }
 }
 
-int
-_e_devicemgr_inputgen_mouse_move_event(int x, int y, char *identifier)
+static void
+_e_devicemgr_inputgen_client_del(struct wl_client *client, unsigned int clas)
 {
-   Ecore_Event_Mouse_Move *e;
+   E_Devicemgr_Inputgen_Client_Global_Data *data;
+   E_Devicemgr_Inputgen_Client_Data *cdata;
+   E_Devicemgr_Inputgen_Device_Data *ddata;
+   Eina_List *l, *ll, *l_next, *ll_next, **list;
 
-   DMERR("Try\n");
+   list = _e_devicemgr_inputgen_list_get(clas);
+   EINA_SAFETY_ON_NULL_RETURN(list);
 
-   e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
-   if (!e) return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+   EINA_LIST_FOREACH_SAFE(*list, l, l_next, ddata)
+     {
+        EINA_LIST_FOREACH_SAFE(ddata->clients, ll, ll_next, cdata)
+          {
+             if (cdata->client == client)
+               {
+                  cdata->ref--;
+                  if (cdata->ref <= 0)
+                    {
+                       ddata->clients = eina_list_remove_list(ddata->clients, ll);
+                       E_FREE(cdata);
+                    }
+               }
+          }
 
-   e->window = e_comp->ee_win;
-   e->event_window = e_comp->ee_win;
-   e->root_window = e_comp->ee_win;
-   e->timestamp = (int)(ecore_time_get() * 1000);
-   e->same_screen = 1;
+        if (eina_list_count(ddata->clients) == 0)
+          {
+             ddata->clients = NULL;
+             _e_devicemgr_inputgen_remove_device(ddata);
+             *list = eina_list_remove_list(*list, l);
+             E_FREE(ddata);
+          }
+     }
 
-   e->x = x;
-   e->y = y;
-   e->root.x = e->x;
-   e->root.y = e->y;
+   EINA_LIST_FOREACH(e_devicemgr->watched_clients, l, data)
+     {
+        if (data->client == client)
+          {
+             data->clas &= ~clas;
+          }
+     }
+}
 
-   e->multi.device = 0;
-   e->multi.radius = 1;
-   e->multi.radius_x = 1;
-   e->multi.radius_y = 1;
-   e->multi.pressure = 1.0;
-   e->multi.angle = 0.0;
+static void
+_e_devicemgr_inputgen_resource_add(struct wl_resource *resource, const char *name)
+{
+   E_Devicemgr_Inputgen_Resource_Data *rdata;
+   Eina_List *l;
 
-   e->multi.x = e->x;
-   e->multi.y = e->y;
-   e->multi.root.x = e->x;
-   e->multi.root.y = e->y;
-   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_MOUSE));
+   EINA_LIST_FOREACH(e_devicemgr->inputgen.resource_list, l, rdata)
+     {
+        if (rdata->resource == resource) return;
+     }
 
-   DMDBG("Generate mouse move event: (%d, %d)\n", e->x, e->y);
+   rdata = NULL;
+   rdata = E_NEW(E_Devicemgr_Inputgen_Resource_Data, 1);
+   EINA_SAFETY_ON_NULL_RETURN(rdata);
 
-   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+   rdata->resource = resource;
+   strncpy(rdata->name, name, UINPUT_MAX_NAME_SIZE - 1);
 
-   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+   e_devicemgr->inputgen.resource_list = eina_list_append(e_devicemgr->inputgen.resource_list, rdata);
 }
 
-static int
-_e_devicemgr_inputgen_touch_event(uint32_t type, uint32_t x, uint32_t y, uint32_t finger, char *identifier)
+static void
+_e_devicemgr_inputgen_resource_del(struct wl_resource *resource)
 {
-   Ecore_Event_Mouse_Button *e;
-
-   e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
-   EINA_SAFETY_ON_NULL_RETURN_VAL(e, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+   E_Devicemgr_Inputgen_Resource_Data *rdata;
+   Eina_List *l, *l_next;
 
-   e->window = e_comp->ee_win;
-   e->event_window = e_comp->ee_win;
-   e->root_window = e_comp->ee_win;
-   e->timestamp = (int)(ecore_time_get() * 1000);
-   e->same_screen = 1;
+   EINA_LIST_FOREACH_SAFE(e_devicemgr->inputgen.resource_list, l, l_next, rdata)
+     {
+        if (rdata->resource == resource)
+          {
+             e_devicemgr->inputgen.resource_list =
+               eina_list_remove_list(e_devicemgr->inputgen.resource_list, l);
+             E_FREE(rdata);
+          }
+     }
+}
 
-   e->x = x;
-   e->y = y;
-   e->root.x = e->x;
-   e->root.y = e->y;
+int
+_e_devicemgr_inputgen_create_device(Ecore_Device_Class clas, struct wl_client *client, const char *device_name)
+{
+   int uinp_fd = -1;
+   Eina_List **dev_list, *l, *ll;
+   E_Devicemgr_Inputgen_Client_Data *cdata;
+   E_Devicemgr_Inputgen_Device_Data *ddata, *device = NULL;
+   Eina_Bool exist_device_flag = EINA_FALSE;
+   int i;
 
-   e->multi.device = finger;
-   e->multi.radius = 1;
-   e->multi.radius_x = 1;
-   e->multi.radius_y = 1;
-   e->multi.pressure = 1.0;
-   e->multi.angle = 0.0;
+   dev_list = _e_devicemgr_inputgen_list_get(clas);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dev_list, EINA_FALSE);
 
-   e->multi.x = e->x;
-   e->multi.y = e->y;
-   e->multi.root.x = e->x;
-   e->multi.root.y = e->y;
-   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_TOUCH));
-   e->buttons = 1;
+   EINA_LIST_FOREACH(*dev_list, l, ddata)
+     {
+        if (!strncmp(ddata->name, device_name, UINPUT_MAX_NAME_SIZE))
+          {
+             EINA_LIST_FOREACH(ddata->clients, ll, cdata)
+               {
+                  if (cdata->client == client)
+                    {
+                       cdata->ref++;
+                       return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+                    }
+               }
 
-   DMDBG("Generate touch event: device: %d (%d, %d)\n", e->multi.device, e->x, e->y);
+             device = ddata;
+             exist_device_flag = EINA_TRUE;
+             break;
+          }
+     }
 
-   if (type == TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN)
-     ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
-   else
-     ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, _e_devicemgr_inputgen_mouse_button_event_free, NULL);
+   if (!device)
+     {
+        device = E_NEW(E_Devicemgr_Inputgen_Device_Data, 1);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(device, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+        strncpy(device->name, device_name, UINPUT_MAX_NAME_SIZE - 1);
+     }
 
-   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
-}
+   cdata = E_NEW(E_Devicemgr_Inputgen_Client_Data, 1);
+   if(!cdata)
+     {
+        if (!exist_device_flag) E_FREE(device);
+        return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+     }
 
-static int
-_e_devicemgr_inputgen_touch_update_event(uint32_t x, uint32_t y, uint32_t finger, char *identifier)
-{
-   Ecore_Event_Mouse_Move *e;
+   cdata->ref = 1;
+   cdata->client = client;
 
-   e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
-   EINA_SAFETY_ON_NULL_RETURN_VAL(e, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES);
+   device->clients = eina_list_append(device->clients, cdata);
 
-   e->window = e_comp->ee_win;
-   e->event_window = e_comp->ee_win;
-   e->root_window = e_comp->ee_win;
-   e->timestamp = (int)(ecore_time_get() * 1000);
-   e->same_screen = 1;
+   if (exist_device_flag)
+     return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
 
-   e->x = x;
-   e->y = y;
-   e->root.x = e->x;
-   e->root.y = e->y;
+   uinp_fd = e_devicemgr_create_virtual_device(clas, device_name);
 
-   e->multi.device = finger;
-   e->multi.radius = 1;
-   e->multi.radius_x = 1;
-   e->multi.radius_y = 1;
-   e->multi.pressure = 1.0;
-   e->multi.angle = 0.0;
+   if (uinp_fd < 0)
+     goto fail_create_device;
 
-   e->multi.x = e->x;
-   e->multi.y = e->y;
-   e->multi.root.x = e->x;
-   e->multi.root.y = e->y;
-   e->dev = ecore_device_ref(e_input_evdev_get_ecore_device(identifier, ECORE_DEVICE_CLASS_TOUCH));
+   device->uinp_fd = uinp_fd;
+   *dev_list = eina_list_append(*dev_list, device);
 
-   DMDBG("Generate touch move event: device: %d (%d, %d)\n", e->multi.device, e->x, e->y);
+   device->clas = clas;
 
-   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _e_devicemgr_inputgen_mouse_move_event_free, NULL);
+   for (i = 0; i < INPUTGEN_MAX_TOUCH; i++)
+     {
+        device->touch.coords[i].x = -1;
+        device->touch.coords[i].y = -1;
+     }
 
    return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
+
+fail_create_device:
+   EINA_LIST_FREE(device->clients, cdata)
+     E_FREE(cdata);
+   E_FREE(device);
+   return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
 }
 
 int
@@ -639,9 +704,10 @@ e_devicemgr_inputgen_remove(struct wl_client *client, struct wl_resource *resour
 int
 e_devicemgr_inputgen_generate_key(struct wl_client *client, struct wl_resource *resource, const char *keyname, Eina_Bool pressed)
 {
-   Eina_List *l;
+   Eina_List *l, *l_next;
    E_Devicemgr_Inputgen_Device_Data *ddata;
    char *name, *identifier = NULL;
+   Eina_Stringshare *name_data;
    int ret;
 
    name = _e_devicemgr_inputgen_name_get(resource);
@@ -666,6 +732,25 @@ e_devicemgr_inputgen_generate_key(struct wl_client *client, struct wl_resource *
           }
      }
 
+   if (ddata)
+     {
+        if (pressed)
+          {
+             ddata->key.pressed = eina_list_append(ddata->key.pressed, eina_stringshare_add(keyname));
+          }
+        else
+          {
+             EINA_LIST_FOREACH_SAFE(ddata->key.pressed, l, l_next, name_data)
+               {
+                  if (e_devicemgr_strcmp(name_data, keyname))
+                    {
+                       ddata->key.pressed = eina_list_remove_list(ddata->key.pressed, l);
+                       eina_stringshare_del(name_data);
+                    }
+               }
+          }
+     }
+
    ret = _e_devicemgr_inputgen_key_event_add(keyname, pressed, identifier);
    return ret;
 }
@@ -676,9 +761,15 @@ e_devicemgr_inputgen_generate_pointer(struct wl_client *client, struct wl_resour
    int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
    Eina_Bool state;
    Eina_List *l;
-   E_Devicemgr_Inputgen_Device_Data *ddata;
+   E_Devicemgr_Inputgen_Device_Data *ddata = NULL;
    char *name, *identifier = NULL;
 
+   if (0 >= button || button >= INPUTGEN_MAX_BTN)
+     {
+        DMWRN("Invalid button: %d\n", button);
+        return TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+     }
+
    name = _e_devicemgr_inputgen_name_get(resource);
 
    if (!_e_devicemgr_inputgen_device_check(name, ECORE_DEVICE_CLASS_MOUSE))
@@ -697,11 +788,25 @@ e_devicemgr_inputgen_generate_pointer(struct wl_client *client, struct wl_resour
      }
 
    if (type == TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE)
-      ret = _e_devicemgr_inputgen_mouse_move_event(x, y, identifier);
+     {
+        ret = _e_devicemgr_inputgen_mouse_move_event(x, y, identifier);
+        if (ddata)
+          {
+             ddata->mouse.coords.x = x;
+             ddata->mouse.coords.y = y;
+          }
+     }
    else
      {
         state = (type == TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN) ?
                 EINA_TRUE : EINA_FALSE;
+        if (ddata)
+          {
+             if (state)  ddata->mouse.pressed |= 1 << (button - 1);
+             else ddata->touch.pressed &= ~(1 << (button - 1));
+             ddata->mouse.coords.x = x;
+             ddata->mouse.coords.y = y;
+          }
         ret = _e_devicemgr_inputgen_mouse_button_event(state, x, y, button, identifier);
      }
 
@@ -713,11 +818,17 @@ e_devicemgr_inputgen_generate_touch(struct wl_client *client, struct wl_resource
 {
    int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE;
    Eina_List *l;
-   E_Devicemgr_Inputgen_Device_Data *ddata;
+   E_Devicemgr_Inputgen_Device_Data *ddata = NULL;
    char *name, *identifier = NULL;
 
    name = _e_devicemgr_inputgen_name_get(resource);
 
+   if (finger >= INPUTGEN_MAX_TOUCH)
+     {
+        DMWRN("Invalid fingers: %d\n", finger);
+        return TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER;
+     }
+
    if (!_e_devicemgr_inputgen_device_check(name, ECORE_DEVICE_CLASS_TOUCH))
      {
         DMWRN("generate is not init\n");
@@ -738,12 +849,29 @@ e_devicemgr_inputgen_generate_touch(struct wl_client *client, struct wl_resource
         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN:
            ret = _e_devicemgr_inputgen_touch_update_event(x, y, finger, identifier);
            ret = _e_devicemgr_inputgen_touch_event(type, x, y, finger, identifier);
+           if (ddata)
+             {
+                ddata->touch.pressed |= 1 << finger;
+                ddata->touch.coords[finger].x = x;
+                ddata->touch.coords[finger].y = y;
+             }
            break;
         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END:
            ret = _e_devicemgr_inputgen_touch_event(type, x, y, finger, identifier);
+           if (ddata)
+             {
+                ddata->touch.pressed &= ~(1 << finger);
+                ddata->touch.coords[finger].x = -1;
+                ddata->touch.coords[finger].y = -1;
+             }
            break;
         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE:
            ret = _e_devicemgr_inputgen_touch_update_event(x, y, finger, identifier);
+           if (ddata)
+             {
+                ddata->touch.coords[finger].x = x;
+                ddata->touch.coords[finger].y = y;
+             }
            break;
      }
 
@@ -849,7 +977,7 @@ e_devicemgr_create_virtual_device(Ecore_Device_Class clas, const char *name)
        uinp.absmin[ABS_Y] = 0;
        uinp.absmax[ABS_Y] = 1000;
        uinp.absmin[ABS_MT_SLOT] = 0;
-       uinp.absmax[ABS_MT_SLOT] = 9;
+       uinp.absmax[ABS_MT_SLOT] = INPUTGEN_MAX_TOUCH - 1;
        uinp.absmin[ABS_MT_TOUCH_MAJOR] = 0;
        uinp.absmax[ABS_MT_TOUCH_MAJOR] = 255;
        uinp.absmin[ABS_MT_TOUCH_MINOR] = 0;
index acafeae6cad822acbc8b40c4deb76a5d75d48a57..baa520fc0f0d72fe955fc7c80240afd9d5b11bb0 100644 (file)
 
 #define INPUT_GENERATOR_DEVICE "Input Generator"
 #define DETENT_DEVICE_NAME "tizen_detent"
+#define INPUTGEN_MAX_TOUCH 10
+#define INPUTGEN_MAX_BTN 16
 
 typedef struct _E_Devicemgr_Input_Device_User_Data E_Devicemgr_Input_Device_User_Data;
+typedef struct _E_Devicemgr_Coords E_Devicemgr_Coords;
 typedef struct _E_Devicemgr_Inputgen_Client_Data E_Devicemgr_Inputgen_Client_Data;
 typedef struct _E_Devicemgr_Inputgen_Client_Global_Data E_Devicemgr_Inputgen_Client_Global_Data;
 typedef struct _E_Devicemgr_Inputgen_Device_Data E_Devicemgr_Inputgen_Device_Data;
@@ -53,6 +56,11 @@ struct _E_Devicemgr_Input_Device_User_Data
    struct wl_resource *seat_res;
 };
 
+struct _E_Devicemgr_Coords
+{
+   int x, y;
+};
+
 struct _E_Devicemgr_Inputgen_Client_Data
 {
    struct wl_client *client;
@@ -70,6 +78,22 @@ struct _E_Devicemgr_Inputgen_Device_Data
    int uinp_fd;
    char *identifier;
    char name[UINPUT_MAX_NAME_SIZE];
+   Ecore_Device_Class clas;
+   struct
+     {
+        unsigned int pressed;
+        E_Devicemgr_Coords coords[INPUTGEN_MAX_TOUCH];
+     } touch;
+   struct
+     {
+        unsigned int pressed;
+        E_Devicemgr_Coords coords;
+     } mouse;
+   struct
+     {
+        Eina_List *pressed;
+     } key;
+
    Eina_List *clients;
 };