[TEMP] e_comp_wl: add E_Comp_Wl_Seat struct for multi-seat 56/96256/2 sandbox/duna/devel
authorDuna Oh <duna.oh@samsung.com>
Fri, 4 Nov 2016 05:18:22 +0000 (14:18 +0900)
committerDuna Oh <duna.oh@samsung.com>
Thu, 10 Nov 2016 04:42:47 +0000 (13:42 +0900)
Change-Id: If82c06e6d77a2a57b9a9f31e801d9fc5a8a5f293
Signed-off-by: Duna Oh <duna.oh@samsung.com>
17 files changed:
src/bin/e_client.h
src/bin/e_comp.c
src/bin/e_comp.h
src/bin/e_comp_canvas.c
src/bin/e_comp_screen.c
src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_data.c
src/bin/e_comp_wl_data.h
src/bin/e_comp_wl_input.c
src/bin/e_comp_wl_input.h
src/bin/e_comp_wl_rsm.c
src/bin/e_info_client.c
src/bin/e_info_server.c
src/bin/e_pointer.c
src/bin/services/e_service_volume.c
src/modules/wl_desktop_shell/e_mod_main.c

index 5770f6b3a0acd186a30804245bff6eed564d8705..f90ebc8c052c5d8a84be89589a62a3bd0a7bd546 100644 (file)
@@ -891,6 +891,10 @@ struct E_Client
    } indicator;
 
    E_Plane_Renderer_Client *renderer_client;
+
+#ifdef HAVE_WAYLAND_ONLY
+   E_Comp_Wl_Seat *seat;
+#endif
 };
 
 #define e_client_focus_policy_click(ec) \
index 816fc48d1b21dc4cfed322b7240cb5b5eba9fbc8..529e0c1bac6144550f3ff5c20d9e751db3305adf 100644 (file)
@@ -569,11 +569,13 @@ _e_comp_hwc_usable(void)
    Eina_List *l;
    E_Zone *zone;
    Eina_Bool ret = EINA_FALSE;
+   E_Comp_Wl_Seat *seat;
 
    if (!e_comp->hwc) return EINA_FALSE;
 
    // will be removed once hwc cursor is supported
-   if (!e_pointer_is_hidden(e_comp->pointer)) return EINA_FALSE;
+   EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
+     if (!e_pointer_is_hidden(seat->pointer)) return EINA_FALSE;
 
    // check whether to use hwc
    // core assignment policy
index e2cdf3f9ca49086969360e0a5abd131ca4f9b810..2b2222947eb1674332cf985f69f08f2a7fa333f1 100644 (file)
@@ -3,6 +3,7 @@ typedef struct _E_Comp                       E_Comp;
 typedef struct _E_Comp_Wl_Client_Data        E_Comp_Client_Data;
 typedef struct _E_Comp_Wl_Data               E_Comp_Wl_Data;
 typedef struct _E_Comp_Connected_Client_Info E_Comp_Connected_Client_Info;
+typedef struct _E_Comp_Wl_Seat               E_Comp_Wl_Seat;
 
 # define E_COMP_TYPE (int) 0xE0b01003
 
@@ -82,7 +83,6 @@ struct _E_Comp
    Evas           *evas;
    Evas_Object    *bg_blank_object;
    Eina_List      *zones;
-   E_Pointer      *pointer;
    Eina_List *clients;
    unsigned int new_clients;
 
index 7042e0b23178135f6882d24fc98d99aa40cd1bc2..4f17d1cd41bbdae5b129c2f098717cdab3937915 100644 (file)
@@ -235,7 +235,6 @@ e_comp_canvas_clear(void)
    E_FREE_FUNC(e_comp->fps_bg, evas_object_del);
    E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
    E_FREE_FUNC(e_comp->shape_job, ecore_job_del);
-   E_FREE_FUNC(e_comp->pointer, e_object_del);
 }
 
 //////////////////////////////////////////////
index 7a6f736c02cc0b5ea78521697230e236e50752ea..8bdd11379cb6831e24d28cb95ced6667792fb8c6 100644 (file)
@@ -166,29 +166,39 @@ end:
 static Eina_Bool
 _e_comp_screen_cb_input_device_add(void *data, int type, void *event)
 {
-   Ecore_Drm_Event_Input_Device_Add *e;
-   E_Comp *comp = data;
+   Ecore_Event_Device_Info *e;
+   E_Comp_Wl_Seat *seat;
 
    if (!(e = event)) goto end;
 
-   if (e->caps & EVDEV_SEAT_POINTER)
+   if (e->clas == ECORE_DEVICE_CLASS_SEAT)
      {
-        if (comp->wl_comp_data->ptr.num_devices == 0)
+        if (!(seat = e_comp_wl_input_seat_get(e->seatname)))
+          e_comp_wl_input_add(e->seatname);
+        return ECORE_CALLBACK_PASS_ON;
+     }
+
+   seat = e_comp_wl_input_seat_get(e->seatname);
+   if (!seat) goto end;
+
+   if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
+     {
+        if (seat->ptr.num_devices == 0)
           {
-             e_pointer_object_set(comp->pointer, NULL, 0, 0);
-             e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
+             e_pointer_object_set(seat->pointer, NULL, 0, 0);
+             e_comp_wl_input_pointer_enabled_set(seat, EINA_TRUE);
           }
-        comp->wl_comp_data->ptr.num_devices++;
+        seat->ptr.num_devices++;
      }
-   if (e->caps & EVDEV_SEAT_KEYBOARD)
+   if (e->clas == ECORE_DEVICE_CLASS_KEYBOARD)
      {
-        comp->wl_comp_data->kbd.num_devices++;
-        e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
+        seat->kbd.num_devices++;
+        e_comp_wl_input_keyboard_enabled_set(seat, EINA_TRUE);
      }
-   if (e->caps & EVDEV_SEAT_TOUCH)
+   if (e->clas == ECORE_DEVICE_CLASS_TOUCH)
      {
-        e_comp_wl_input_touch_enabled_set(EINA_TRUE);
-        comp->wl_comp_data->touch.num_devices++;
+        e_comp_wl_input_touch_enabled_set(seat, EINA_TRUE);
+        seat->touch.num_devices++;
      }
 
 end:
@@ -198,19 +208,22 @@ end:
 static Eina_Bool
 _e_comp_screen_cb_input_device_del(void *data, int type, void *event)
 {
-   Ecore_Drm_Event_Input_Device_Del *e;
-   E_Comp *comp = data;
+   Ecore_Event_Device_Info *e;
+   E_Comp_Wl_Seat *seat;
 
    if (!(e = event)) goto end;
 
-   if (e->caps & EVDEV_SEAT_POINTER)
+   seat = e_comp_wl_input_seat_get(e->seatname);
+   if (!seat) goto end;
+
+   if (e->clas == ECORE_DEVICE_CLASS_MOUSE)
      {
-        comp->wl_comp_data->ptr.num_devices--;
-        if (comp->wl_comp_data->ptr.num_devices == 0)
+        seat->ptr.num_devices--;
+        if (seat->ptr.num_devices == 0)
           {
-             e_comp_wl_input_pointer_enabled_set(EINA_FALSE);
-             e_pointer_object_set(comp->pointer, NULL, 0, 0);
-             e_pointer_hide(e_comp->pointer);
+             e_comp_wl_input_pointer_enabled_set(seat, EINA_FALSE);
+             e_pointer_object_set(seat->pointer, NULL, 0, 0);
+             e_pointer_hide(seat->pointer);
           }
      }
 
@@ -959,17 +972,20 @@ e_comp_screen_init()
 
    e_comp_wl->screenshooter.read_pixels = _drm_read_pixels;
 
+   E_Comp_Wl_Seat *seat = e_comp_wl_input_seat_get("default");
+   if (seat)
+     {
    /* pointer */
    ecore_evas_pointer_xy_get(e_comp->ee,
-                             &e_comp_wl->ptr.x,
-                             &e_comp_wl->ptr.y);
-
+                             &seat->ptr.x,
+                             &seat->ptr.y);
+     }
    evas_event_feed_mouse_in(e_comp->evas, 0, NULL);
 
    e_main_ts("\tE_Pointer New");
-   if ((comp->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
+   if (seat && (seat->pointer = e_pointer_canvas_new(comp->ee, EINA_TRUE)))
      {
-        e_pointer_hide(comp->pointer);
+        e_pointer_hide(seat->pointer);
      }
    e_main_ts("\tE_Pointer New Done");
 
@@ -1008,8 +1024,8 @@ e_comp_screen_init()
       E_LIST_HANDLER_APPEND(event_handlers, ECORE_DRM_EVENT_OUTPUT,        _e_comp_screen_cb_output_drm,       comp);
 
    E_LIST_HANDLER_APPEND(event_handlers, ECORE_DRM_EVENT_ACTIVATE,         _e_comp_screen_cb_activate,         comp);
-   E_LIST_HANDLER_APPEND(event_handlers, ECORE_DRM_EVENT_INPUT_DEVICE_ADD, _e_comp_screen_cb_input_device_add, comp);
-   E_LIST_HANDLER_APPEND(event_handlers, ECORE_DRM_EVENT_INPUT_DEVICE_DEL, _e_comp_screen_cb_input_device_del, comp);
+   E_LIST_HANDLER_APPEND(event_handlers, ECORE_EVENT_DEVICE_ADD, _e_comp_screen_cb_input_device_add, comp);
+   E_LIST_HANDLER_APPEND(event_handlers, ECORE_EVENT_DEVICE_DEL, _e_comp_screen_cb_input_device_del, comp);
 
 #ifdef HAVE_HWC
    ecore_idle_enterer_add(_e_comp_screen_commit_idle_cb, comp);
index cc696654ad1dc99a44fa10e794b03e8c5cf57431..90665cc573b7c0d26b86c87dbbc20e7933f5d9ed 100644 (file)
@@ -640,8 +640,8 @@ _e_comp_wl_send_touch_cancel(E_Client *ec)
    if (ec->ignored) return;
 
    wc = wl_resource_get_client(ec->comp_data->surface);
-
-   EINA_LIST_FOREACH(e_comp->wl_comp_data->touch.resources, l, res)
+   if (!ec->seat) return;
+   EINA_LIST_FOREACH(ec->seat->touch.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (!e_comp_wl_input_touch_check(res)) continue;
@@ -653,13 +653,16 @@ _e_comp_wl_send_touch_cancel(E_Client *ec)
 static void
 _e_comp_wl_touch_cancel(void)
 {
-   if (!e_comp_wl->ptr.ec)
+   E_Comp_Wl_Seat *seat;
+
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (!seat->ptr.ec)
      return;
 
    if (!need_send_released)
      return;
 
-   _e_comp_wl_send_touch_cancel(e_comp_wl->ptr.ec);
+   _e_comp_wl_send_touch_cancel(seat->ptr.ec);
 
    need_send_released = EINA_FALSE;
    need_send_motion = EINA_FALSE;
@@ -813,9 +816,10 @@ _e_comp_wl_device_send_event_device(E_Client *ec, Evas_Device *dev, uint32_t tim
    last_device = _e_comp_wl_device_last_device_get(dev_class);
    ec_last_device = _e_comp_wl_device_client_last_device_get(ec, dev_class);
 
+   if (!ec->seat) return;
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    wc = wl_resource_get_client(ec->comp_data->surface);
-   EINA_LIST_FOREACH(e_comp_wl->input_device_manager.device_list, l, input_dev)
+   EINA_LIST_FOREACH(ec->seat->device_list, l, input_dev)
      {
         if (!eina_streq(input_dev->identifier, dev_name) || (input_dev->clas != dev_class)) continue;
         if ((!last_device) || (last_device != input_dev) || (!ec_last_device) || (ec_last_device != input_dev))
@@ -858,7 +862,7 @@ _e_comp_wl_device_send_last_event_device(E_Client *ec, Ecore_Device_Class dev_cl
  }
 
  static void
-_e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial)
+_e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Device *dev, uint32_t serial, E_Comp_Wl_Seat *seat)
 {
    E_Comp_Wl_Input_Device *input_dev;
    struct wl_resource *dev_res;
@@ -866,10 +870,11 @@ _e_comp_wl_send_event_device(struct wl_client *wc, uint32_t timestamp, Ecore_Dev
    Eina_List *l, *ll;
 
    EINA_SAFETY_ON_NULL_RETURN(dev);
+   EINA_SAFETY_ON_NULL_RETURN(seat);
 
    dev_name = ecore_device_identifier_get(dev);
 
-   EINA_LIST_FOREACH(e_comp_wl->input_device_manager.device_list, l, input_dev)
+   EINA_LIST_FOREACH(seat->device_list, l, input_dev)
      {
         if (!eina_streq(input_dev->identifier, dev_name)) continue;
         _e_comp_wl_device_last_device_set(ecore_device_class_get(dev), input_dev);
@@ -891,19 +896,20 @@ _e_comp_wl_cursor_reload(E_Client *ec)
    uint32_t serial;
    int cx, cy;
 
-   if (e_comp->pointer->o_ptr && (!evas_object_visible_get(e_comp->pointer->o_ptr)))
-     e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
-
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
    if (!ec->comp_data->surface) return;
+   if (!ec->seat) return;
 
-   cx = wl_fixed_to_int(e_comp_wl->ptr.x) - ec->client.x;
-   cy = wl_fixed_to_int(e_comp_wl->ptr.y) - ec->client.y;
+   if (ec->seat->pointer->o_ptr && (!evas_object_visible_get(ec->seat->pointer->o_ptr)))
+     e_pointer_object_set(ec->seat->pointer, NULL, 0, 0);
+
+   cx = wl_fixed_to_int(ec->seat->ptr.x) - ec->client.x;
+   cy = wl_fixed_to_int(ec->seat->ptr.y) - ec->client.y;
 
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
@@ -932,10 +938,12 @@ _e_comp_wl_device_send_axis(const char *dev_name, Evas_Device_Class dev_class, E
    Eina_List *l, *ll;
    wl_fixed_t f_value;
 
+   if (!ec->seat) return;
+
    f_value = wl_fixed_from_double(value);
    wc = wl_resource_get_client(ec->comp_data->surface);
 
-   EINA_LIST_FOREACH(e_comp_wl->input_device_manager.device_list, l, input_dev)
+   EINA_LIST_FOREACH(ec->seat->device_list, l, input_dev)
      {
         if ((strcmp(input_dev->identifier, dev_name)) || (input_dev->clas != (Ecore_Device_Class)dev_class)) continue;
         EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
@@ -980,6 +988,8 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
    struct wl_client *wc;
    Eina_List *l;
    uint32_t serial;
+   const Evas_Device *seat_dev = NULL;
+   E_Comp_Wl_Seat *seat = NULL;
 
    ev = event;
    if (!(ec = data)) return;
@@ -987,7 +997,19 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
 
    if (!ec->comp_data->surface) return;
 
-   e_comp_wl->ptr.ec = ec;
+   ERR("cb_mouse_in() ec:%s", ec->icccm.name? : "NULL");
+   if ((seat_dev = evas_device_parent_get(ev->dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_mouse_in() seat NULL! return");
+        return;
+     }
+   ERR("cb_mouse_in() dev:%s, seat:%s", evas_device_description_get(ev->dev), evas_device_description_get(seat_dev));
+
+   seat->ptr.ec = ec;
+   ec->seat = seat;
+
    if (e_comp_wl->drag)
      {
         e_comp_wl_data_device_send_enter(ec);
@@ -996,29 +1018,30 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
 
    if (e_config->use_cursor_timer)
      {
-        if (e_comp_wl->ptr.hide_tmr)
+        if (seat->ptr.hide_tmr)
           {
-             ecore_timer_del(e_comp_wl->ptr.hide_tmr);
+             ecore_timer_del(seat->ptr.hide_tmr);
              cursor_timer_ec = ec;
-             e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
+             seat->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
           }
         else
           {
-             if (e_pointer_is_hidden(e_comp->pointer))
+             if (e_pointer_is_hidden(seat->pointer))
                return;
           }
      }
 
-   if (!eina_list_count(e_comp_wl->ptr.resources)) return;
+   if (!eina_list_count(seat->ptr.resources)) return;
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
 
         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, ev->timestamp);
 
+        ERR("cb_mouse_in() send_enter");
         wl_pointer_send_enter(res, serial, ec->comp_data->surface,
                               wl_fixed_from_int(ev->canvas.x - ec->client.x),
                               wl_fixed_from_int(ev->canvas.y - ec->client.y));
@@ -1036,6 +1059,8 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
    Eina_List *l;
    uint32_t serial;
    Eina_Bool inside_check;
+   const Evas_Device *seat_dev = NULL;
+   E_Comp_Wl_Seat *seat = NULL;
 
    ev = event;
 
@@ -1045,21 +1070,38 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
    if (ec->cur_mouse_action && inside_check) return;
    if (e_object_is_del(E_OBJECT(e_comp))) return;
 
+   if ((seat_dev = evas_device_parent_get(ev->dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_mouse_out() seat NULL! return");
+        return;
+     }
+
+   ERR("cb_mouse_out() dev:%s, seat:%s", evas_device_description_get(ev->dev), evas_device_description_get(seat_dev));
+
    /* FIXME? this is a hack to just reset the cursor whenever we mouse out. not sure if accurate */
    {
       Evas_Object *o;
 
       ecore_evas_cursor_get(e_comp->ee, &o, NULL, NULL, NULL);
-      if ((e_comp->pointer->o_ptr != o) && (e_comp->wl_comp_data->ptr.enabled))
+      if ((seat->pointer && seat->pointer->o_ptr != o) && (seat->ptr.enabled))
         {
-           if ((!e_config->use_cursor_timer) || (!e_pointer_is_hidden(e_comp->pointer)))
-             e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
+           if ((!e_config->use_cursor_timer) || (!e_pointer_is_hidden(seat->pointer)))
+             e_pointer_object_set(seat->pointer, NULL, 0, 0);
         }
    }
 
-   if (e_comp_wl->ptr.ec == ec)
-     e_comp_wl->ptr.ec = NULL;
-   if (e_object_is_del(E_OBJECT(ec))) return;
+   if (seat->ptr.ec == ec)
+     seat->ptr.ec = NULL;
+   ec->seat = NULL;
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     {
+        ERR("_cb_mouse_out() e_object_is_del return\n");
+        return;
+     }
 
    if (!ec->comp_data->surface) return;
 
@@ -1069,17 +1111,17 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
         return;
      }
 
-   if (e_config->use_cursor_timer && !e_comp_wl->ptr.hide_tmr)
+   if (e_config->use_cursor_timer && !seat->ptr.hide_tmr)
      {
-        if (e_pointer_is_hidden(e_comp->pointer))
+        if (e_pointer_is_hidden(seat->pointer))
           return;
      }
 
-   if (!eina_list_count(e_comp_wl->ptr.resources)) return;
+   if (!eina_list_count(seat->ptr.resources)) return;
 
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
@@ -1087,12 +1129,13 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
 
         _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, ev->timestamp);
 
+        ERR("cb_mouse_out() send_leave");
         wl_pointer_send_leave(res, serial, ec->comp_data->surface);
         ec->pointer_enter_sent = EINA_FALSE;
      }
 }
-
 static void
+
 _e_comp_wl_send_touch(E_Client *ec, int idx, int canvas_x, int canvas_y, uint32_t timestamp, Eina_Bool pressed)
 {
    Eina_List *l;
@@ -1110,7 +1153,8 @@ _e_comp_wl_send_touch(E_Client *ec, int idx, int canvas_x, int canvas_y, uint32_
         y = wl_fixed_from_int(canvas_y - ec->client.y);
      }
 
-   EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
+   if (!ec->seat) return;
+   EINA_LIST_FOREACH(ec->seat->touch.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (!e_comp_wl_input_touch_check(res)) continue;
@@ -1136,7 +1180,8 @@ _e_comp_wl_send_touch_move(E_Client *ec, int idx, int canvas_x, int canvas_y, ui
    x = wl_fixed_from_int(canvas_x - ec->client.x);
    y = wl_fixed_from_int(canvas_y - ec->client.y);
 
-   EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
+   if (!ec->seat) return;
+   EINA_LIST_FOREACH(ec->seat->touch.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (!e_comp_wl_input_touch_check(res)) continue;
@@ -1151,8 +1196,9 @@ _e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp, E
    struct wl_client *wc;
    Eina_List *l;
 
+   if (!ec->seat) return;
    wc = wl_resource_get_client(ec->comp_data->surface);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
@@ -1162,35 +1208,38 @@ _e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp, E
      }
 
    /* e pointer move for touch coodination */
-   if (cursor_control) e_pointer_mouse_move(e_comp->pointer, x, y);
+   if (cursor_control) e_pointer_mouse_move(ec->seat->pointer, x, y);
 }
 
 static void
 _e_comp_wl_cursor_move_timer_control(E_Client *ec)
 {
+   E_Comp_Wl_Seat *seat;
+
    if (!e_config->use_cursor_timer) return;
+   if (!(seat = ec->seat)) return;
 
-   if (e_pointer_is_hidden(e_comp->pointer))
+   if (e_pointer_is_hidden(seat->pointer))
      _e_comp_wl_cursor_reload(ec);
 
-   if (e_comp_wl->ptr.hide_tmr)
+   if (seat->ptr.hide_tmr)
      {
         if (cursor_timer_ec == ec)
           {
-             ecore_timer_interval_set(e_comp_wl->ptr.hide_tmr, e_config->cursor_timer_interval);
-             ecore_timer_reset(e_comp_wl->ptr.hide_tmr);
+             ecore_timer_interval_set(seat->ptr.hide_tmr, e_config->cursor_timer_interval);
+             ecore_timer_reset(seat->ptr.hide_tmr);
           }
         else
           {
-             ecore_timer_del(e_comp_wl->ptr.hide_tmr);
+             ecore_timer_del(seat->ptr.hide_tmr);
              cursor_timer_ec = ec;
-             e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
+             seat->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
           }
      }
    else
      {
         cursor_timer_ec = ec;
-        e_comp_wl->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
+        seat->ptr.hide_tmr = ecore_timer_add(e_config->cursor_timer_interval, _e_comp_wl_cursor_timer, ec);
      }
 }
 
@@ -1200,13 +1249,12 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    E_Client *ec;
    Evas_Event_Mouse_Move *ev;
    Evas_Device *dev = NULL;
+   const Evas_Device*seat_dev;
    const char *dev_name;
+   E_Comp_Wl_Seat *seat = NULL;
 
    ev = event;
 
-   e_comp->wl_comp_data->ptr.x = wl_fixed_from_int(ev->cur.canvas.x);
-   e_comp->wl_comp_data->ptr.y = wl_fixed_from_int(ev->cur.canvas.y);
-
    if (!(ec = data)) return;
    if (ec->cur_mouse_action) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1219,11 +1267,22 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
        (!e_client_has_xwindow(e_comp_wl->drag_client)))
      {
         dev = ev->dev;
+        if ((seat_dev = evas_device_parent_get(dev)))
+          seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+        if (!seat)
+          {
+             ERR("_e_comp_wl_evas_cb_mouse_move() seat NULL! return");
+             return;
+          }
+        ec->seat = seat;
+        seat->ptr.x = wl_fixed_from_int(ev->cur.canvas.x);
+        seat->ptr.y = wl_fixed_from_int(ev->cur.canvas.y);
+
         dev_name = evas_device_description_get(dev);
 
         if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
           {
-             if (e_comp_wl->touch.pressed & (1 << 0))
+             if (seat && seat->touch.pressed & (1 << 0))
                {
                   _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
                   if (dev_name)
@@ -1232,7 +1291,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
                   _e_comp_wl_send_touch_move(ec, 0, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
                }
              /* e pointer move for 1st finger touch coodination */
-             e_pointer_touch_move(e_comp->pointer, ev->cur.canvas.x, ev->cur.canvas.y);
+             e_pointer_touch_move(seat->pointer, ev->cur.canvas.x, ev->cur.canvas.y);
           }
         else
           {
@@ -1251,8 +1310,9 @@ _e_comp_wl_evas_handle_mouse_button_to_touch(E_Client *ec, uint32_t timestamp, i
    if (e_object_is_del(E_OBJECT(ec))) return;
    if (!ec->comp_data->surface) return;
    if (ec->ignored) return;
+   if (!ec->seat) return;
 
-   e_comp_wl->ptr.button = BTN_LEFT;
+   ec->seat->ptr.button = BTN_LEFT;
 
    _e_comp_wl_send_touch(ec, 0, canvas_x, canvas_y, timestamp, flag);
 }
@@ -1265,9 +1325,10 @@ _e_comp_wl_send_mouse_out(E_Client *ec)
    uint32_t serial;
    Eina_List *l;
 
+   if (!ec->seat) return;
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
@@ -1281,8 +1342,10 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    E_Client *ec = data;
    Evas_Event_Mouse_Down *ev = event;
    Evas_Device *dev = NULL;
+   const Evas_Device *seat_dev;
    const char *dev_name;
    E_Client *focused;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1290,6 +1353,16 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    dev = ev->dev;
    dev_name = evas_device_description_get(dev);
 
+    if ((seat_dev = evas_device_parent_get(dev)))
+      seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_mouse_down() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
    _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
 
    if (dev &&  (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
@@ -1297,8 +1370,8 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
         if (dev_name)
           _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
                                         ec, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
+        seat->touch.pressed |= (1 << 0);
         _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_TRUE);
-        e_comp_wl->touch.pressed |= (1 << 0);
      }
    else
      e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
@@ -1327,8 +1400,10 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
    E_Client *ec = data;
    Evas_Event_Mouse_Up *ev = event;
    Evas_Device *dev = NULL;
+   const Evas_Device *seat_dev;
    const char *dev_name;
    Evas_Event_Flags flags;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1344,6 +1419,16 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
    dev = ev->dev;
    dev_name = evas_device_description_get(dev);
 
+   if ((seat_dev = evas_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_mouse_up() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
    _e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
 
    if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
@@ -1351,8 +1436,8 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
         if (dev_name)
           _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
                                         ec, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
+        seat->touch.pressed &= ~(1 << 0);
         _e_comp_wl_evas_handle_mouse_button_to_touch(ec, ev->timestamp, ev->canvas.x, ev->canvas.y, EINA_FALSE);
-        e_comp_wl->touch.pressed &= ~(1 << 0);
      }
    else
      e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
@@ -1381,7 +1466,8 @@ _e_comp_wl_mouse_wheel_send(E_Client *ec, int direction, int z, int timestamp)
      dir = wl_fixed_from_int(z);
 
    wc = wl_resource_get_client(ec->comp_data->surface);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   if (!ec->seat) return;
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
@@ -1394,6 +1480,8 @@ _e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *
 {
    E_Client *ec;
    Evas_Event_Mouse_Wheel *ev;
+   const Evas_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    ev = event;
    if (!(ec = data)) return;
@@ -1403,7 +1491,17 @@ _e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *
 
    if (!ec->comp_data->surface) return;
 
-   if (!eina_list_count(e_comp_wl->ptr.resources))
+   if ((seat_dev = evas_device_parent_get(ev->dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_mouse_wheel() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
+   if (!eina_list_count(seat->ptr.resources))
      return;
 
    _e_comp_wl_device_send_event_device(ec, ev->dev, ev->timestamp);
@@ -1417,8 +1515,10 @@ _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    E_Client *ec = data;
    Evas_Event_Multi_Down *ev = event;
    Evas_Device *dev = NULL;
+   const Evas_Device *seat_dev;
    const char *dev_name;
    Evas_Device_Class dev_class;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1428,6 +1528,17 @@ _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    if (ev->device == 0) return;
 
    dev = ev->dev;
+
+   if ((seat_dev = evas_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_multi_down() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
    if (dev && (dev_name = evas_device_description_get(dev)))
      {
         dev_class = evas_device_class_get(dev);
@@ -1435,8 +1546,8 @@ _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
         _e_comp_wl_device_handle_axes(dev_name, dev_class, ec, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
      }
 
+   seat->touch.pressed |= (1 << ev->device);
    _e_comp_wl_send_touch(ec, ev->device, ev->canvas.x, ev->canvas.y, ev->timestamp, EINA_TRUE);
-   e_comp_wl->touch.pressed |= (1 << ev->device);
 }
 
 static void
@@ -1445,8 +1556,10 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
    E_Client *ec = data;
    Evas_Event_Multi_Up *ev = event;
    Evas_Device *dev = NULL;
+   const Evas_Device *seat_dev;
    const char *dev_name;
    Evas_Device_Class dev_class;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1456,6 +1569,17 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
    if (ev->device == 0) return;
 
    dev = ev->dev;
+
+   if ((seat_dev = evas_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_multi_up() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
    if (dev && (dev_name = evas_device_description_get(dev)))
      {
         dev_class = evas_device_class_get(dev);
@@ -1463,8 +1587,8 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
         _e_comp_wl_device_handle_axes(dev_name, dev_class, ec, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
      }
 
+   seat->touch.pressed &= ~(1 << ev->device);
    _e_comp_wl_send_touch(ec, ev->device, 0, 0, ev->timestamp, EINA_FALSE);
-   e_comp_wl->touch.pressed &= ~(1 << ev->device);
 }
 
 static void
@@ -1473,8 +1597,10 @@ _e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    E_Client *ec = data;
    Evas_Event_Multi_Move *ev = event;
    Evas_Device *dev = NULL;
+   const Evas_Device *seat_dev;
    const char *dev_name;
    Evas_Device_Class dev_class;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1483,9 +1609,19 @@ _e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    /* Do not deliver emulated single touch events to client */
    if (ev->device == 0) return;
 
-   if (e_comp_wl->touch.pressed & (1 << ev->device))
+   dev = ev->dev;
+   if ((seat_dev = evas_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(evas_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("_e_comp_wl_evas_cb_multi_move() seat NULL! return");
+        return;
+     }
+   ec->seat = seat;
+
+   if (seat && seat->touch.pressed & (1 << ev->device))
      {
-        dev = ev->dev;
         if (dev && (dev_name = evas_device_description_get(dev)))
           {
              dev_class = evas_device_class_get(dev);
@@ -1574,15 +1710,15 @@ _e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
 
    ec->comp_data->on_focus_timer = NULL;
 
-   if (!e_comp_wl->kbd.focused) return EINA_FALSE;
+   if (!ec->seat) return EINA_FALSE;
+   if (!ec->seat->kbd.focused) return EINA_FALSE;
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    t = ecore_time_unix_get();
-
-   EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
+   EINA_LIST_FOREACH(ec->seat->kbd.focused, l, res)
      {
-        wl_array_for_each(k, &e_comp_wl->kbd.keys)
+        wl_array_for_each(k, &ec->seat->kbd.keys)
           {
-             _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
+             _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial, ec->seat);
              wl_keyboard_send_key(res, serial, t,
                                   k->key, WL_KEYBOARD_KEY_STATE_PRESSED);
           }
@@ -1609,19 +1745,24 @@ _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
    /* raise client priority */
    _e_comp_wl_client_priority_raise(ec);
 
+   if (!ec->seat) return;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
+
+   EINA_LIST_FOREACH(ec->seat->kbd.resources, l, res)
       if (wl_resource_get_client(res) == wc)
-        e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
-   if (!e_comp_wl->kbd.focused) return;
+        ec->seat->kbd.focused = eina_list_append(ec->seat->kbd.focused, res);
+   if (!ec->seat->kbd.focused) return;
+
    e_comp_wl_input_keyboard_enter_send(ec);
-   e_comp_wl_data_device_keyboard_focus_set();
+   e_comp_wl_data_device_keyboard_focus_set(ec->seat);
+
    ec->comp_data->on_focus_timer =
       ecore_timer_add(((e_config->xkb.delay_held_key_input_to_focus)/1000.0),
                       (Ecore_Task_Cb)_e_comp_wl_evas_cb_focus_in_timer, ec);
    int rotation = ec->e.state.rot.ang.curr;
-   if (e_comp->pointer->rotation != rotation)
-     e_pointer_rotation_set(e_comp->pointer, rotation);
+   if (ec->seat->pointer->rotation != rotation)
+     e_pointer_rotation_set(ec->seat->pointer, rotation);
 }
 
 static void
@@ -1644,30 +1785,31 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
    if (!e_object_is_del(data))
      _e_comp_wl_client_priority_normal(ec);
 
+   if (!ec->seat) return;
 
    /* update keyboard modifier state */
-   wl_array_for_each(k, &e_comp_wl->kbd.keys)
-      e_comp_wl_input_keyboard_state_update(k->key, EINA_FALSE);
+   wl_array_for_each(k, &ec->seat->kbd.keys)
+      e_comp_wl_input_keyboard_state_update(ec->seat, k->key, EINA_FALSE);
 
    if (!ec->comp_data->surface) return;
 
-   if (!eina_list_count(e_comp_wl->kbd.resources)) return;
+   if (!eina_list_count(ec->seat->kbd.resources)) return;
 
    /* send keyboard_leave to all keyboard resources */
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    t = ecore_time_unix_get();
 
-   EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
+   EINA_LIST_FOREACH_SAFE(ec->seat->kbd.focused, l, ll, res)
      {
-        wl_array_for_each(k, &e_comp_wl->kbd.keys)
+        wl_array_for_each(k, &ec->seat->kbd.keys)
           {
-             _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
+             _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial, ec->seat);
               wl_keyboard_send_key(res, serial, t,
                                    k->key, WL_KEYBOARD_KEY_STATE_RELEASED);
           }
         wl_keyboard_send_leave(res, serial, ec->comp_data->surface);
-        e_comp_wl->kbd.focused =
-           eina_list_remove_list(e_comp_wl->kbd.focused, l);
+        ec->seat->kbd.focused =
+           eina_list_remove_list(ec->seat->kbd.focused, l);
      }
 }
 
@@ -1973,8 +2115,9 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev
 static Eina_Bool
 _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
 {
-   e_comp_wl->ptr.x = wl_fixed_from_int(ev->x);
-   e_comp_wl->ptr.y = wl_fixed_from_int(ev->y);
+   const Ecore_Device *seat_dev = NULL;
+   E_Comp_Wl_Seat *seat = NULL;
+
    if (e_comp_wl->selection.target &&
        (!e_client_has_xwindow(e_comp_wl->selection.target)) &&
        e_comp_wl->drag)
@@ -1997,6 +2140,18 @@ _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mou
        e_comp_wl->drag_client &&
        e_client_has_xwindow(e_comp_wl->drag_client))
      {
+        if ((seat_dev = ecore_device_parent_get(ev->dev)))
+          seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+
+        if (!seat)
+          {
+             ERR("_e_comp_wl_cb_mouse_move() seat NULL! return");
+             return ECORE_CALLBACK_RENEW;
+          }
+        e_comp_wl->drag_client->seat = seat;
+        seat->ptr.x = wl_fixed_from_int(ev->x);
+        seat->ptr.y = wl_fixed_from_int(ev->y);
+
         _e_comp_wl_send_mouse_move(e_comp_wl->drag_client, ev->x, ev->y, ev->timestamp, EINA_TRUE);
 
         _e_comp_wl_cursor_move_timer_control(NULL);
@@ -2008,8 +2163,11 @@ _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mou
 static Eina_Bool
 _e_comp_wl_cb_mouse_button_cancel(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Button *ev)
 {
-   if (e_comp_wl->ptr.ec)
-     _e_comp_wl_send_touch_cancel(e_comp_wl->ptr.ec);
+   E_Comp_Wl_Seat *seat;
+
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (seat->ptr.ec)
+     _e_comp_wl_send_touch_cancel(seat->ptr.ec);
 
    return ECORE_CALLBACK_PASS_ON;
 }
@@ -2017,12 +2175,15 @@ _e_comp_wl_cb_mouse_button_cancel(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_
 static Eina_Bool
 _e_comp_wl_cb_zone_display_state_change(void *d EINA_UNUSED, int t EINA_UNUSED, E_Event_Zone_Display_State_Change *ev EINA_UNUSED)
 {
-   if (e_comp_wl->ptr.ec && need_send_released)
+   E_Comp_Wl_Seat *seat;
+
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (seat->ptr.ec && need_send_released)
      {
-        _e_comp_wl_send_touch_cancel(e_comp_wl->ptr.ec);
+        _e_comp_wl_send_touch_cancel(seat->ptr.ec);
 
         need_send_released = EINA_FALSE;
-      }
+     }
 
     return ECORE_CALLBACK_PASS_ON;
  }
@@ -2037,8 +2198,9 @@ _e_comp_wl_cb_client_rot_change_end(void *d EINA_UNUSED, int t EINA_UNUSED, E_Ev
    if (!focused_ec) return ECORE_CALLBACK_PASS_ON;
 
    rotation = focused_ec->e.state.rot.ang.curr;
-   if (e_comp->pointer->rotation != rotation)
-     e_pointer_rotation_set(e_comp->pointer, rotation);
+   if (!focused_ec->seat) return ECORE_CALLBACK_PASS_ON;
+   if (focused_ec->seat->pointer->rotation != rotation)
+     e_pointer_rotation_set(focused_ec->seat->pointer, rotation);
 
    return ECORE_CALLBACK_PASS_ON;
 }
@@ -2934,18 +3096,21 @@ _e_comp_wl_surface_destroy(struct wl_resource *resource)
 {
    E_Client *ec;
    struct wl_resource *res;
-   Eina_List *l, *ll;
+   Eina_List *l, *ll, *lll;
 
    if (!(ec = wl_resource_get_user_data(resource))) return;
-
    if (ec == e_client_focused_get())
      {
-        EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
+        E_Comp_Wl_Seat *seat = NULL;
+        EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
           {
-             if (wl_resource_get_client(res) ==
-                 wl_resource_get_client(ec->comp_data->surface))
-               e_comp_wl->kbd.focused =
-                  eina_list_remove_list(e_comp_wl->kbd.focused, l);
+             EINA_LIST_FOREACH_SAFE(seat->kbd.focused, ll, lll, res)
+               {
+                  if (wl_resource_get_client(res) ==
+                      wl_resource_get_client(ec->comp_data->surface))
+                    seat->kbd.focused =
+                       eina_list_remove_list(seat->kbd.focused, ll);
+               }
           }
      }
 
@@ -4163,7 +4328,7 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
 
    if (cursor_timer_ec == ec)
      {
-        E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
+        E_FREE_FUNC(ec->seat->ptr.hide_tmr, ecore_timer_del);
         cursor_timer_ec = NULL;
      }
 
@@ -4189,6 +4354,8 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
 static void
 _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
 {
+   E_Comp_Wl_Seat *seat;
+
    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
    /* send configure */
@@ -4198,12 +4365,19 @@ _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
           _e_comp_wl_configure_send(ec, 0, 0);
      }
 
-   e_comp_wl->kbd.focus = ec->comp_data->surface;
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (seat)
+     {
+        ec->seat = seat;
+        ec->seat->kbd.focus = ec->comp_data->surface;
+     }
 }
 
 static void
 _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
 {
+   E_Comp_Wl_Seat *seat;
+
    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
    /* send configure */
@@ -4215,8 +4389,14 @@ _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
 
    _e_comp_wl_focus_check();
 
-   if (e_comp_wl->kbd.focus == ec->comp_data->surface)
-     e_comp_wl->kbd.focus = NULL;
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (seat)
+     {
+        ec->seat = seat;
+
+        if (ec->seat->kbd.focus == ec->comp_data->surface)
+          ec->seat->kbd.focus = NULL;
+     }
 }
 
 static void
@@ -4651,10 +4831,13 @@ _e_comp_wl_compositor_create(void)
      }
 
    /* try to init input */
-   if (!e_comp_wl_input_init())
+   if (e_comp_wl_input_init())
      {
-        ERR("Could not initialize input");
-        goto input_err;
+        if (!e_comp_wl_input_add("default"))
+          {
+             ERR("Could not initialize input");
+             goto input_err;
+          }
      }
 
    if (e_comp_gl_get())
@@ -5294,7 +5477,7 @@ e_comp_wl_output_remove(const char *id)
 }
 
 static void
-_e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_List *key_list, Eina_Bool focused)
+_e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_List *key_list, Eina_Bool focused, E_Comp_Wl_Seat *seat)
 {
    struct wl_resource *res;
    Eina_List *l;
@@ -5316,12 +5499,12 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, enum wl_keyboard_key_state state, Eina_
           {
              _e_comp_wl_client_destroy_listener_add(wc);
              eina_hash_direct_add(_last_keydev_hash, wc, ev->dev);
-             _e_comp_wl_send_event_device(ev->data, ev->timestamp, ev->dev, serial);
+             _e_comp_wl_send_event_device(ev->data, ev->timestamp, ev->dev, serial, seat);
           }
         else if (last_dev != ev->dev)
           {
              eina_hash_modify(_last_keydev_hash, wc, ev->dev);
-             _e_comp_wl_send_event_device(ev->data, ev->timestamp, ev->dev, serial);
+             _e_comp_wl_send_event_device(ev->data, ev->timestamp, ev->dev, serial, seat);
           }
 
         wl_keyboard_send_key(res, serial, ev->timestamp,
@@ -5337,6 +5520,8 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
    struct wl_client *wc = NULL;
    uint32_t keycode;
    E_Comp_Wl_Key_Data *end, *k;
+   const Ecore_Device *seat_dev = NULL;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win))
      {
@@ -5359,6 +5544,14 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
      }
 #endif
 
+   if (ev->dev && (seat_dev = ecore_device_parent_get(ev->dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+   if (!seat)
+     {
+        ERR("e_comp_wl_key_down() seat is NULL!\n");
+        return EINA_FALSE;
+     }
+
    ec = e_client_focused_get();
    wc = (ec ? ec->comp_data->surface ? wl_resource_get_client(ec->comp_data->surface) : NULL : NULL);
 
@@ -5366,14 +5559,14 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
      {
         if (wc != ev->data)
           {
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.resources, EINA_FALSE);
+             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, seat->kbd.resources, EINA_FALSE, seat);
           }
         else
           {
              ec = NULL;
-             end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*k));
+             end = (E_Comp_Wl_Key_Data *)seat->kbd.routed_keys.data + (seat->kbd.routed_keys.size / sizeof(*k));
 
-             for (k = e_comp_wl->kbd.routed_keys.data; k < end; k++)
+             for (k = seat->kbd.routed_keys.data; k < end; k++)
                {
                   /* ignore server-generated key repeats */
                   if (k->key == keycode)
@@ -5385,13 +5578,13 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
              if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
                {
                   ec = e_client_focused_get();
-                  if (ec && ec->comp_data->surface && e_comp_wl->kbd.focused)
+                  if (ec && ec->comp_data->surface && seat->kbd.focused)
                     {
-                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, EINA_TRUE);
+                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, seat->kbd.focused, EINA_TRUE, seat);
 
                        /* A key only sent to clients is added to the list */
-                       e_comp_wl->kbd.routed_keys.size = (const char *)end - (const char *)e_comp_wl->kbd.routed_keys.data;
-                       if (!(k = wl_array_add(&e_comp_wl->kbd.routed_keys, sizeof(*k))))
+                       seat->kbd.routed_keys.size = (const char *)end - (const char *)seat->kbd.routed_keys.data;
+                       if (!(k = wl_array_add(&seat->kbd.routed_keys, sizeof(*k))))
                          {
                             DBG("wl_array_add: Out of memory\n");
                             return EINA_FALSE;
@@ -5402,7 +5595,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
                }
 
              /* update modifier state */
-             e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
+             e_comp_wl_input_keyboard_state_update(seat, keycode, EINA_TRUE);
           }
 
         return !!ec;
@@ -5410,9 +5603,9 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
 
    ec = NULL;
 
-   end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.keys.data + (e_comp_wl->kbd.keys.size / sizeof(*k));
+   end = (E_Comp_Wl_Key_Data *)seat->kbd.keys.data + (seat->kbd.keys.size / sizeof(*k));
 
-   for (k = e_comp_wl->kbd.keys.data; k < end; k++)
+   for (k = seat->kbd.keys.data; k < end; k++)
      {
         /* ignore server-generated key repeats */
         if (k->key == keycode)
@@ -5424,14 +5617,14 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
    if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
      {
         ec = e_client_focused_get();
-        if (ec && ec->comp_data->surface && e_comp_wl->kbd.focused)
+        if (ec && ec->comp_data->surface && seat->kbd.focused)
           {
              ev->data = wc;
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, EINA_TRUE);
+             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_PRESSED, seat->kbd.focused, EINA_TRUE, seat);
 
              /* A key only sent to clients is added to the list */
-             e_comp_wl->kbd.keys.size = (const char *)end - (const char *)e_comp_wl->kbd.keys.data;
-             if (!(k = wl_array_add(&e_comp_wl->kbd.keys, sizeof(*k))))
+             seat->kbd.keys.size = (const char *)end - (const char *)seat->kbd.keys.data;
+             if (!(k = wl_array_add(&seat->kbd.keys, sizeof(*k))))
                {
                   DBG("wl_array_add: Out of memory\n");
                   return EINA_FALSE;
@@ -5442,7 +5635,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev)
      }
 
    /* update modifier state */
-   e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
+   e_comp_wl_input_keyboard_state_update(seat, keycode, EINA_TRUE);
 
    return !!ec;
 }
@@ -5454,6 +5647,8 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
    struct wl_client *wc = NULL;
    uint32_t keycode, delivered_key;
    E_Comp_Wl_Key_Data *end, *k;
+   const Ecore_Device *seat_dev = NULL;
+   E_Comp_Wl_Seat *seat = NULL;
 
    if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) ||
        (ev->window != e_comp->ee_win))
@@ -5468,13 +5663,21 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
         return EINA_FALSE;
      }
 
+   if (ev->dev && (seat_dev = ecore_device_parent_get(ev->dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+   if (!seat)
+     {
+        ERR("e_comp_wl_key_up() seat is NULL!\n");
+        return EINA_FALSE;
+     }
+
    ec = e_client_focused_get();
    wc = (ec ? ec->comp_data->surface ? wl_resource_get_client(ec->comp_data->surface) : NULL : NULL);
 
    if (ev->data)
      {
-        end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.routed_keys.data + (e_comp_wl->kbd.routed_keys.size / sizeof(*k));
-        for (k = e_comp_wl->kbd.routed_keys.data; k < end; k++)
+        end = (E_Comp_Wl_Key_Data *)seat->kbd.routed_keys.data + (seat->kbd.routed_keys.size / sizeof(*k));
+        for (k = seat->kbd.routed_keys.data; k < end; k++)
           {
              if (k->key == keycode)
                {
@@ -5482,12 +5685,12 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
                   delivered_key = 1;
                }
           }
-        e_comp_wl->kbd.routed_keys.size =
-          (const char *)end - (const char *)e_comp_wl->kbd.routed_keys.data;
+        seat->kbd.routed_keys.size =
+          (const char *)end - (const char *)seat->kbd.routed_keys.data;
 
         if (wc != ev->data)
           {
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.resources, EINA_FALSE);
+             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, seat->kbd.resources, EINA_FALSE, seat);
           }
         else
           {
@@ -5498,22 +5701,22 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
                {
                   ec = e_client_focused_get();
 
-                  if (e_comp_wl->kbd.focused)
+                  if (seat->kbd.focused)
                     {
-                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, EINA_FALSE);
+                       _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, seat->kbd.focused, EINA_FALSE, seat);
                     }
                }
 
              /* update modifier state */
-             e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
+             e_comp_wl_input_keyboard_state_update(seat, keycode, EINA_FALSE);
           }
         return !!ec;
      }
 
    ec = NULL;
 
-   end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.keys.data + (e_comp_wl->kbd.keys.size / sizeof(*k));
-   for (k = e_comp_wl->kbd.keys.data; k < end; k++)
+   end = (E_Comp_Wl_Key_Data *)seat->kbd.keys.data + (seat->kbd.keys.size / sizeof(*k));
+   for (k = seat->kbd.keys.data; k < end; k++)
      {
         if (k->key == keycode)
           {
@@ -5522,8 +5725,8 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
           }
      }
 
-   e_comp_wl->kbd.keys.size =
-     (const char *)end - (const char *)e_comp_wl->kbd.keys.data;
+   seat->kbd.keys.size =
+     (const char *)end - (const char *)seat->kbd.keys.data;
 
    /* If a key down event have been sent to clients, send a key up event to client for garantee key event sequence pair. (down/up) */
    if ((delivered_key) ||
@@ -5531,15 +5734,15 @@ e_comp_wl_key_up(Ecore_Event_Key *ev)
      {
         ec = e_client_focused_get();
 
-        if (e_comp_wl->kbd.focused)
+        if (seat->kbd.focused)
           {
              ev->data = wc;
-             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, EINA_TRUE);
+             _e_comp_wl_key_send(ev, WL_KEYBOARD_KEY_STATE_RELEASED, seat->kbd.focused, EINA_TRUE, seat);
           }
      }
 
    /* update modifier state */
-   e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
+   e_comp_wl_input_keyboard_state_update(seat, keycode, EINA_FALSE);
 
    return !!ec;
 }
@@ -5565,17 +5768,18 @@ e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t bu
       default: btn = button_id;  break;
      }
 
-   e_comp_wl->ptr.button = btn;
-
    if (!ec->comp_data->surface) return EINA_FALSE;
 
-   if (!eina_list_count(e_comp_wl->ptr.resources))
+   if (!ec->seat) return EINA_FALSE;
+   ec->seat->ptr.button = btn;
+
+   if (!eina_list_count(ec->seat->ptr.resources))
      return EINA_TRUE;
 
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (!e_comp_wl_input_pointer_check(res)) continue;
@@ -5631,18 +5835,21 @@ e_comp_wl_shell_surface_ready(E_Client *ec)
 E_API void
 e_comp_wl_input_cursor_timer_enable_set(Eina_Bool enabled)
 {
+   E_Comp_Wl_Seat *seat;
+
    e_config->use_cursor_timer = !!enabled;
 
-   if (e_config->use_cursor_timer == EINA_FALSE && e_pointer_is_hidden(e_comp->pointer))
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (e_config->use_cursor_timer == EINA_FALSE && e_pointer_is_hidden(seat->pointer))
      {
-        _e_comp_wl_cursor_reload(e_comp_wl->ptr.ec);
+        _e_comp_wl_cursor_reload(seat->ptr.ec);
      }
-   else if (e_config->use_cursor_timer == EINA_FALSE && !e_pointer_is_hidden(e_comp->pointer))
+   else if (e_config->use_cursor_timer == EINA_FALSE && !e_pointer_is_hidden(seat->pointer))
      {
-        if (e_comp_wl->ptr.hide_tmr)
+        if (seat->ptr.hide_tmr)
           {
-             ecore_timer_del(e_comp_wl->ptr.hide_tmr);
-             e_comp_wl->ptr.hide_tmr = NULL;
+             ecore_timer_del(seat->ptr.hide_tmr);
+             seat->ptr.hide_tmr = NULL;
           }
         cursor_timer_ec = NULL;
      }
@@ -5670,10 +5877,10 @@ e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, Ecore_Device *d
    if (pressed) state = WL_KEYBOARD_KEY_STATE_PRESSED;
    else state = WL_KEYBOARD_KEY_STATE_RELEASED;
 
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
-        if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
+        if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial, NULL);
         else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_KEYBOARD, time);
         wl_keyboard_send_key(res, serial, time,
                              wl_keycode, state);
@@ -5688,6 +5895,8 @@ e_comp_wl_touch_send(E_Client *ec, int idx, int x, int y, Eina_Bool pressed, Eco
    struct wl_client *wc;
    uint32_t serial;
    E_Comp_Wl_Input_Device *device = NULL;
+   const Ecore_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
@@ -5695,13 +5904,22 @@ e_comp_wl_touch_send(E_Client *ec, int idx, int x, int y, Eina_Bool pressed, Eco
 
    if (!dev) device = _e_comp_wl_device_last_device_get(ECORE_DEVICE_CLASS_TOUCH);
 
+   if (dev && (seat_dev = ecore_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+   if (!seat)
+     {
+        ERR("e_comp_wl_touch_send() seat NULL! return");
+        return EINA_FALSE;
+     }
+   ec->seat = seat;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
    if (!time) time = (uint32_t)(ecore_time_get() * 1000);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
    if (dev)
      {
-        _e_comp_wl_send_event_device(wc, time, dev, serial);
+        _e_comp_wl_send_event_device(wc, time, dev, serial, seat);
         _e_comp_wl_device_handle_axes(ecore_device_identifier_get(dev), ECORE_DEVICE_CLASS_TOUCH, ec, radius_x, radius_y, pressure, angle);
      }
    else if (device)
@@ -5721,6 +5939,8 @@ e_comp_wl_touch_update_send(E_Client *ec, int idx, int x, int y, Ecore_Device *d
    E_Comp_Wl_Input_Device *device;
    uint32_t serial;
    struct wl_client *wc;
+   const Ecore_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
@@ -5728,13 +5948,22 @@ e_comp_wl_touch_update_send(E_Client *ec, int idx, int x, int y, Ecore_Device *d
 
    if (!dev) device = _e_comp_wl_device_last_device_get(ECORE_DEVICE_CLASS_TOUCH);
 
+   if (dev && (seat_dev = ecore_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+   if (!seat)
+     {
+        ERR("e_comp_wl_touch_update_send() seat NULL! return");
+        return EINA_FALSE;
+     }
+   ec->seat = seat;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
    if (!time) time = (uint32_t)(ecore_time_get() * 1000);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
    if (dev)
      {
-        _e_comp_wl_send_event_device(wc, time, dev, serial);
+        _e_comp_wl_send_event_device(wc, time, dev, serial, seat);
         _e_comp_wl_device_handle_axes(ecore_device_identifier_get(dev), ECORE_DEVICE_CLASS_TOUCH, ec, radius_x, radius_y, pressure, angle);
      }
    else if (device)
@@ -5765,16 +5994,28 @@ e_comp_wl_mouse_button_send(E_Client *ec, int buttons, Eina_Bool pressed, Ecore_
 {
    uint32_t serial;
    struct wl_client *wc;
+   const Ecore_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
 
+   if ((seat_dev = ecore_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("e_comp_wl_mouse_button_send() seat NULL! return");
+        return EINA_FALSE;
+     }
+   ec->seat = seat;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
    if (!time) time = (uint32_t)(ecore_time_get() * 1000);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
-   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
+   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial, seat);
    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
 
    if (pressed)
@@ -5792,16 +6033,28 @@ e_comp_wl_mouse_move_send(E_Client *ec, int x, int y, Ecore_Device *dev, uint32_
 {
    uint32_t serial;
    struct wl_client *wc;
+   const Ecore_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
 
+   if ((seat_dev = ecore_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("e_comp_wl_mouse_move_send() seat NULL! return");
+        return EINA_FALSE;
+     }
+   ec->seat = seat;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
    if (!time) time = (uint32_t)(ecore_time_get() * 1000);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
-   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
+   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial, seat);
    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
 
    _e_comp_wl_send_mouse_move(ec, x, y, time, EINA_FALSE);
@@ -5814,16 +6067,28 @@ e_comp_wl_mouse_wheel_send(E_Client *ec, int direction, int z, Ecore_Device *dev
 {
    uint32_t serial;
    struct wl_client *wc;
+   const Ecore_Device *seat_dev;
+   E_Comp_Wl_Seat *seat = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
 
+   if ((seat_dev = ecore_device_parent_get(dev)))
+     seat = e_comp_wl_input_seat_get(ecore_device_description_get(seat_dev));
+
+   if (!seat)
+     {
+        ERR("e_comp_wl_mouse_wheel_send() seat NULL! return");
+        return EINA_FALSE;
+     }
+   ec->seat = seat;
+
    wc = wl_resource_get_client(ec->comp_data->surface);
    if (!time) time = (uint32_t)(ecore_time_get() * 1000);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
 
-   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
+   if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial, seat);
    else _e_comp_wl_device_send_last_event_device(ec, ECORE_DEVICE_CLASS_MOUSE, time);
 
    _e_comp_wl_mouse_wheel_send(ec, direction, z, time);
@@ -5839,22 +6104,23 @@ e_comp_wl_cursor_hide(E_Client *ec)
    Eina_List *l;
    uint32_t serial;
 
-   e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
+   if (!ec) return EINA_FALSE;
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+   if (!ec->comp_data->surface) return EINA_FALSE;
+   if (!ec->seat) return EINA_FALSE;
+
+   e_pointer_object_set(ec->seat->pointer, NULL, 0, 0);
 
-   if (e_comp_wl->ptr.hide_tmr)
+   if (ec->seat->ptr.hide_tmr)
      {
-        ecore_timer_del(e_comp_wl->ptr.hide_tmr);
-        e_comp_wl->ptr.hide_tmr = NULL;
+        ecore_timer_del(ec->seat->ptr.hide_tmr);
+        ec->seat->ptr.hide_tmr = NULL;
      }
    cursor_timer_ec = NULL;
 
-   if (!ec) return EINA_FALSE;
-   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
-
-   if (!ec->comp_data->surface) return EINA_FALSE;
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(ec->seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != wc) continue;
index 909e145ceca0c495956eb7ec5afc4d70ac63d28c..e497687ddf99a6034ead647611e7e296e73e5bfc 100755 (executable)
@@ -45,6 +45,8 @@ typedef struct _E_Comp_Wl_Data E_Comp_Wl_Data;
 typedef struct _E_Comp_Wl_Output E_Comp_Wl_Output;
 typedef struct _E_Comp_Wl_Input_Device E_Comp_Wl_Input_Device;
 typedef struct _E_Comp_Wl_Hook E_Comp_Wl_Hook;
+typedef struct _E_Comp_Wl_Seat E_Comp_Wl_Seat;
+typedef struct _e_devicemgr_input_device_user_data e_devicemgr_input_device_user_data;
 
 typedef enum _E_Comp_Wl_Buffer_Type
 {
@@ -154,14 +156,71 @@ struct _E_Comp_Wl_Subsurf_Data
      } remote_surface;
 };
 
+struct _e_devicemgr_input_device_user_data
+{
+   E_Comp_Wl_Input_Device *dev;
+   struct wl_resource *dev_mgr_res;
+   struct wl_resource *seat_res;
+};
+
 struct _E_Comp_Wl_Input_Device
 {
    Eina_List *resources;
    const char *name;
    const char *identifier;
+   const char *seatname;
    Ecore_Device_Class clas;
 };
 
+struct _E_Comp_Wl_Seat
+{
+   struct wl_global *global;
+   Eina_List *resources;
+   uint32_t version;
+   char *name;
+   Eina_List *device_list;
+   E_Pointer *pointer;
+
+   struct
+     {
+        Eina_List *resources;
+        Eina_Bool enabled : 1;
+        Eina_List *focused;
+        xkb_mod_index_t mod_shift, mod_caps;
+        xkb_mod_index_t mod_ctrl, mod_alt;
+        xkb_mod_index_t mod_super;
+        xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
+        xkb_layout_index_t mod_group;
+        struct wl_array keys;
+        struct wl_array routed_keys;
+        struct wl_resource *focus;
+        int mod_changed;
+        int repeat_delay;
+        int repeat_rate;
+        unsigned int num_devices;
+     } kbd;
+
+   struct
+     {
+        Eina_List *resources;
+        Eina_Bool enabled : 1;
+        wl_fixed_t x, y;
+        wl_fixed_t grab_x, grab_y;
+        uint32_t button;
+        Ecore_Timer *hide_tmr;
+        E_Client *ec;
+        unsigned int num_devices;
+     } ptr;
+
+   struct
+     {
+        Eina_List *resources;
+        Eina_Bool enabled : 1;
+        unsigned int pressed;
+        unsigned int num_devices;
+     } touch;
+};
+
 struct _E_Comp_Wl_Data
 {
    struct
@@ -209,7 +268,6 @@ struct _E_Comp_Wl_Data
      {
         struct wl_global *global;
         Eina_List *resources;
-        Eina_List *device_list;
         E_Comp_Wl_Input_Device *last_device_ptr;
         E_Comp_Wl_Input_Device *last_device_touch;
         E_Comp_Wl_Input_Device *last_device_kbd;
@@ -222,7 +280,7 @@ struct _E_Comp_Wl_Data
           } multi;
      } input_device_manager;
 
-   struct
+   /*struct
      {
         Eina_List *resources;
         Eina_List *focused;
@@ -260,7 +318,7 @@ struct _E_Comp_Wl_Data
         unsigned int num_devices;
         unsigned int pressed;
      } touch;
-
+*/
    struct
      {
         struct wl_global *global;
@@ -347,6 +405,7 @@ struct _E_Comp_Wl_Data
      } screenshooter;
 
    Eina_List *outputs;
+   Eina_List *seats;
 
    Ecore_Fd_Handler *fd_hdlr;
    Ecore_Idler *idler;
index defcc8c93c9479e8bbe1775c8b919aedf03861d4..cb1b7144b967f69038ab81ee0260fb9c19e3ac32 100644 (file)
@@ -152,6 +152,7 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
 {
    E_Comp_Wl_Data_Source *source;
    struct wl_resource *data_device_res = NULL, *focus = NULL;
+   E_Comp_Wl_Seat *seat;
 
    DBG("Data Device Destroy Selection Source");
    if (!(source = (E_Comp_Wl_Data_Source*)data))
@@ -159,8 +160,9 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
 
    e_comp_wl->selection.data_source = NULL;
 
-   if (e_comp_wl->kbd.enabled)
-     focus = e_comp_wl->kbd.focus;
+   seat = e_comp_wl_input_seat_get(NULL);
+   if (seat->kbd.enabled)
+     focus = seat->kbd.focus;
 
    if (focus)
      {
@@ -257,8 +259,9 @@ _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Sour
    e_comp_wl->clipboard.xwl_owner = NULL;
    e_comp_wl->selection.serial = serial;
 
-   if (e_comp_wl->kbd.enabled)
-     focus = e_comp_wl->kbd.focus;
+   E_Comp_Wl_Seat *seat = e_comp_wl_input_seat_get(NULL);
+   if (seat->kbd.enabled)
+     focus = seat->kbd.focus;
 
    //if source is from cbhm_client do not crate data offer for cbhm
    if ((cbhm_client) && (source_client != cbhm_client))
@@ -340,7 +343,9 @@ _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resourc
 
    DBG("Data Device Drag Start");
 
-   if ((e_comp_wl->kbd.focus) && (e_comp_wl->kbd.focus != origin_resource)) return;
+   E_Comp_Wl_Seat *seat = e_comp_wl_input_seat_get(NULL);
+   if (!seat) return;
+   if ((seat->kbd.focus) && (seat->kbd.focus != origin_resource)) return;
 
    if (!(source = wl_resource_get_user_data(source_resource))) return;
    e_comp_wl->drag_source = source;
@@ -364,11 +369,11 @@ _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resourc
           }
      }
 
-   EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
+   EINA_LIST_FOREACH(seat->ptr.resources, l, res)
      {
         if (!e_comp_wl_input_pointer_check(res)) continue;
         if (wl_resource_get_client(res) != client) continue;
-        wl_pointer_send_leave(res, serial, e_comp_wl->kbd.focus);
+        wl_pointer_send_leave(res, serial, seat->kbd.focus);
      }
 
    evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
@@ -378,8 +383,8 @@ _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resourc
    if (ec)
      e_drag_object_set(e_comp_wl->drag, ec->frame);
    e_drag_start(e_comp_wl->drag, x, y);
-   if (e_comp_wl->ptr.ec)
-     e_comp_wl_data_device_send_enter(e_comp_wl->ptr.ec);
+   if (seat->ptr.ec)
+     e_comp_wl_data_device_send_enter(seat->ptr.ec);
    e_comp_canvas_feed_mouse_up(0);
 }
 
@@ -684,8 +689,9 @@ e_comp_wl_data_device_send_enter(E_Client *ec)
    e_comp_wl->selection.target = ec;
    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
 
-   x = wl_fixed_to_int(e_comp_wl->ptr.x) - e_comp_wl->selection.target->client.x;
-   y = wl_fixed_to_int(e_comp_wl->ptr.y) - e_comp_wl->selection.target->client.y;
+   if (!ec->seat) return;
+   x = wl_fixed_to_int(ec->seat->ptr.x) - e_comp_wl->selection.target->client.x;
+   y = wl_fixed_to_int(ec->seat->ptr.y) - e_comp_wl->selection.target->client.y;
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    wl_data_device_send_enter(data_device_res, serial, ec->comp_data->surface,
                              wl_fixed_from_int(x), wl_fixed_from_int(y), offer_res);
@@ -721,18 +727,18 @@ e_comp_wl_data_device_send_offer(E_Client *ec)
 }
 
 E_API void
-e_comp_wl_data_device_keyboard_focus_set(void)
+e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Seat *seat)
 {
    struct wl_resource *data_device_res, *offer_res = NULL, *focus;
    E_Comp_Wl_Data_Source *source;
 
-   if (!e_comp_wl->kbd.enabled)
+   if (!seat->kbd.enabled)
      {
         ERR("Keyboard not enabled");
         return;
      }
 
-   if (!(focus = e_comp_wl->kbd.focus))
+   if (!(focus = seat->kbd.focus))
      {
         ERR("No focused resource");
         return;
index a997d7534e8c9721786191ea3587126e60daeadb..bed26d334427b09adf4e544d0b40e35502905019 100644 (file)
@@ -57,7 +57,7 @@ struct _E_Comp_Wl_Clipboard_Offer
 E_API void e_comp_wl_data_device_send_enter(E_Client *ec);
 E_API void e_comp_wl_data_device_send_leave(E_Client *ec);
 EINTERN void *e_comp_wl_data_device_send_offer(E_Client *ec);
-E_API void e_comp_wl_data_device_keyboard_focus_set(void);
+E_API void e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Seat *seat);
 EINTERN Eina_Bool e_comp_wl_data_manager_init(void);
 EINTERN void e_comp_wl_data_manager_shutdown(void);
 E_API struct wl_resource *e_comp_wl_data_find_for_client(struct wl_client *client);
index b362871db353e41ae8e1fef2e71cedb0e9c01623..8bd7bdb32168cdff9e05248ef1b62f6276c29603 100644 (file)
@@ -4,25 +4,28 @@
 #include <Ecore_Drm.h>
 
 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
+E_API int E_EVENT_SEAT_BOUND = 1;
 static Eina_Bool dont_set_ecore_drm_keymap = EINA_FALSE;
 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
 static Eina_Bool use_cache_keymap = EINA_FALSE;
 
 static void
-_e_comp_wl_input_update_seat_caps(void)
+_e_comp_wl_input_update_seat_caps(E_Comp_Wl_Seat *seat)
 {
    Eina_List *l;
    struct wl_resource *res;
    enum wl_seat_capability caps = 0;
 
-   if (e_comp_wl->ptr.enabled)
+   EINA_SAFETY_ON_NULL_RETURN(seat);
+
+   if (seat->ptr.enabled)
      caps |= WL_SEAT_CAPABILITY_POINTER;
-   if (e_comp_wl->kbd.enabled)
+   if (seat->kbd.enabled)
      caps |= WL_SEAT_CAPABILITY_KEYBOARD;
-   if (e_comp_wl->touch.enabled)
+   if (seat->touch.enabled)
      caps |= WL_SEAT_CAPABILITY_TOUCH;
 
-   EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
+   EINA_LIST_FOREACH(seat->resources, l, res)
         wl_seat_send_capabilities(res, caps);
 }
 
@@ -34,8 +37,9 @@ _e_comp_wl_input_pointer_map(struct wl_resource *resource)
 
    if (!(ec = wl_resource_get_user_data(resource))) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (!ec->seat) return;
 
-   if ((ptr = e_comp->pointer))
+   if ((ec->seat) && (ptr = ec->seat->pointer))
      e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
 }
 
@@ -59,10 +63,11 @@ _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struc
 }
 
 static void
-_e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
+_e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
 {
    E_Client *ec;
    Eina_Bool got_mouse = EINA_FALSE;
+   E_Comp_Wl_Seat *seat;
 
    E_CLIENT_FOREACH(ec)
      {
@@ -77,9 +82,12 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
          }
      }
    if (!got_mouse) return;
+
+   seat = wl_resource_get_user_data(resource);
+   if (!seat) return;
    if (!surface_resource)
      {
-        e_pointer_object_set(e_comp->pointer, NULL, x, y);
+        e_pointer_object_set(seat->pointer, NULL, x, y);
         return;
      }
    ec = wl_resource_get_user_data(surface_resource);
@@ -106,7 +114,9 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
 
    /* ignore cursor changes during resize/move I guess */
    if (e_client_action_get()) return;
-   e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
+
+   ec->seat = seat;
+   e_pointer_object_set(ec->seat->pointer, ec->frame, x, y);
 }
 
 static const struct wl_pointer_interface _e_pointer_interface =
@@ -128,30 +138,38 @@ static const struct wl_touch_interface _e_touch_interface =
 static void
 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
 {
-   e_comp_wl->ptr.resources =
-     eina_list_remove(e_comp_wl->ptr.resources, resource);
+   E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
+
+   seat->ptr.resources =
+     eina_list_remove(seat->ptr.resources, resource);
 }
 
 static void
 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
 {
    struct wl_resource *res;
+   E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
 
    /* try to create pointer resource */
    res = wl_resource_create(client, &wl_pointer_interface,
                             wl_resource_get_version(resource), id);
+
    if (!res)
      {
         ERR("Could not create pointer on seat %s: %m",
-            e_comp_wl->seat.name);
+            seat->name);
         wl_client_post_no_memory(client);
         return;
      }
 
-   e_comp_wl->ptr.resources =
-     eina_list_append(e_comp_wl->ptr.resources, res);
+   seat->ptr.resources =
+     eina_list_append(seat->ptr.resources, res);
    wl_resource_set_implementation(res, &_e_pointer_interface,
-                                  e_comp->wl_comp_data,
+                                  seat,
                                  _e_comp_wl_input_cb_pointer_unbind);
 }
 
@@ -160,13 +178,16 @@ _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
 {
    Eina_List *l, *ll;
    struct wl_resource *res;
+   E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
 
-   e_comp_wl->kbd.resources =
-     eina_list_remove(e_comp_wl->kbd.resources, resource);
-   EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
+   seat->kbd.resources =
+     eina_list_remove(seat->kbd.resources, resource);
+   EINA_LIST_FOREACH_SAFE(seat->kbd.focused, l, ll, res)
      if (res == resource)
-       e_comp_wl->kbd.focused =
-         eina_list_remove_list(e_comp_wl->kbd.focused, l);
+       seat->kbd.focused =
+         eina_list_remove_list(seat->kbd.focused, l);
 }
 
 void
@@ -177,22 +198,21 @@ e_comp_wl_input_keyboard_enter_send(E_Client *ec)
    uint32_t serial;
 
    if (!ec->comp_data->surface) return;
+   if (!ec->seat) return;
 
-   if (!e_comp_wl->kbd.focused) return;
-
-   e_comp_wl_input_keyboard_modifiers_serialize();
+   e_comp_wl_input_keyboard_modifiers_serialize(ec->seat);
 
+   if (!ec->seat->kbd.focused) return;
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-
-   EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
+   EINA_LIST_FOREACH(ec->seat->kbd.focused, l, res)
      {
         wl_keyboard_send_enter(res, serial, ec->comp_data->surface,
-                               &e_comp_wl->kbd.keys);
+                               &ec->seat->kbd.keys);
         wl_keyboard_send_modifiers(res, serial,
-                                   e_comp_wl->kbd.mod_depressed,
-                                   e_comp_wl->kbd.mod_latched,
-                                   e_comp_wl->kbd.mod_locked,
-                                   e_comp_wl->kbd.mod_group);
+                                   ec->seat->kbd.mod_depressed,
+                                   ec->seat->kbd.mod_latched,
+                                   ec->seat->kbd.mod_locked,
+                                   ec->seat->kbd.mod_group);
      }
 }
 
@@ -201,6 +221,9 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r
 {
    E_Client *focused;
    struct wl_resource *res;
+   E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
 
    /* try to create keyboard resource */
    res = wl_resource_create(client, &wl_keyboard_interface,
@@ -208,16 +231,17 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r
    if (!res)
      {
         ERR("Could not create keyboard on seat %s: %m",
-            e_comp_wl->seat.name);
+            seat->name);
         wl_client_post_no_memory(client);
         return;
      }
 
-   e_comp_wl->kbd.resources =
-     eina_list_append(e_comp_wl->kbd.resources, res);
+   seat->kbd.resources =
+     eina_list_append(seat->kbd.resources, res);
    wl_resource_set_implementation(res, &_e_keyboard_interface,
-                                  e_comp->wl_comp_data,
+                                  seat,
                                   _e_comp_wl_input_cb_keyboard_unbind);
+   ERR("_e_comp_wl_input_cb_keyboard_get client:%p, seat:%s, resources_num:%d", client, seat->name ? : "NULL", eina_list_count(seat->kbd.resources));
 
    /* send current repeat_info */
    if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
@@ -236,7 +260,7 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r
        (!focused->comp_data) || (!focused->comp_data->surface)) return;
 
    if (client != wl_resource_get_client(focused->comp_data->surface)) return;
-   e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
+   seat->kbd.focused = eina_list_append(seat->kbd.focused, res);
 
    e_comp_wl_input_keyboard_enter_send(focused);
 }
@@ -244,14 +268,21 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r
 static void
 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
 {
-   e_comp_wl->touch.resources =
-     eina_list_remove(e_comp_wl->touch.resources, resource);
+   E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
+
+   seat->touch.resources =
+     eina_list_remove(seat->touch.resources, resource);
 }
 
 static void
 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
 {
     struct wl_resource *res;
+    E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
 
     /* try to create pointer resource */
     res = wl_resource_create(client, &wl_touch_interface,
@@ -259,15 +290,15 @@ _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_re
     if (!res)
       {
          ERR("Could not create touch on seat %s: %m",
-             e_comp_wl->seat.name);
+             seat->name);
          wl_client_post_no_memory(client);
          return;
       }
 
-    e_comp_wl->touch.resources =
-     eina_list_append(e_comp_wl->touch.resources, res);
+    seat->touch.resources =
+     eina_list_append(seat->touch.resources, res);
     wl_resource_set_implementation(res, &_e_touch_interface,
-                                   e_comp->wl_comp_data,
+                                   seat,
                                   _e_comp_wl_input_cb_touch_unbind);
 }
 
@@ -281,15 +312,31 @@ static const struct wl_seat_interface _e_seat_interface =
 static void
 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
 {
-   e_comp_wl->seat.resources =
-     eina_list_remove(e_comp_wl->seat.resources, resource);
+    E_Comp_Wl_Seat *seat;
+
+   if (!(seat = wl_resource_get_user_data(resource))) return;
+   seat->resources =
+     eina_list_remove(seat->resources, resource);
+}
+
+static void
+_e_seat_bound_event_free(void *data EINA_UNUSED, void *event)
+{
+   E_Event_Seat_Bound *ev = event;
+   e_object_unref(E_OBJECT(ev->client));
+   e_object_unref(E_OBJECT(ev->seat));
+   free(ev);
 }
 
 static void
-_e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
+_e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 {
    struct wl_resource *res;
+   E_Comp_Wl_Seat *seat;
+   E_Event_Seat_Bound *ev;
 
+   ERR("_e_comp_wl_input_cb_bind_seat()");
+   if (!(seat = data)) return;
    res = wl_resource_create(client, &wl_seat_interface, version, id);
    if (!res)
      {
@@ -298,17 +345,25 @@ _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED,
      }
 
    /* store version of seat interface for reuse in updating capabilities */
-   e_comp_wl->seat.version = version;
-   e_comp_wl->seat.resources =
-     eina_list_append(e_comp_wl->seat.resources, res);
+   seat->version = version;
+   seat->resources =
+     eina_list_append(seat->resources, res);
 
    wl_resource_set_implementation(res, &_e_seat_interface,
-                                  e_comp->wl_comp_data,
+                                  seat,
                                   _e_comp_wl_input_cb_unbind_seat);
-
-   _e_comp_wl_input_update_seat_caps();
-   if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
-     wl_seat_send_name(res, e_comp_wl->seat.name);
+   wl_resource_set_user_data(res, seat);
+
+   _e_comp_wl_input_update_seat_caps(seat);
+   if (seat->version >= WL_SEAT_NAME_SINCE_VERSION)
+     wl_seat_send_name(res, seat->name);
+
+   ev = E_NEW(E_Event_Seat_Bound, 1);
+   ev->client = client;
+   e_object_ref(E_OBJECT(client));
+   ev->seat = seat;
+   e_object_ref(E_OBJECT(seat));
+   ecore_event_add(E_EVENT_SEAT_BOUND, ev, (Ecore_End_Cb)_e_seat_bound_event_free, NULL);
 }
 
 static void
@@ -401,6 +456,7 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_pat
    xkb_mod_mask_t latched = 0, locked = 0, group = 0;
    struct wl_resource *res;
    Eina_List *l;
+   E_Comp_Wl_Seat *seat;
 
    /* unreference any existing keymap */
    if (e_comp_wl->xkb.keymap)
@@ -438,17 +494,20 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_pat
    /* increment keymap reference */
    e_comp_wl->xkb.keymap = keymap;
 
+   EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
+     {
    /* fetch updated modifiers */
-   e_comp_wl->kbd.mod_shift =
+   seat->kbd.mod_shift =
      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
-   e_comp_wl->kbd.mod_caps =
+   seat->kbd.mod_caps =
      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
-   e_comp_wl->kbd.mod_ctrl =
+   seat->kbd.mod_ctrl =
      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
-   e_comp_wl->kbd.mod_alt =
+   seat->kbd.mod_alt =
      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
-   e_comp_wl->kbd.mod_super =
+   seat->kbd.mod_super =
      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
+     }
 
    if (!(tmp = xkb_map_get_as_string(keymap)))
      {
@@ -483,76 +542,157 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_pat
 
    /* send updated keymap */
    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
+
+   Eina_List *ll;
+
+   EINA_LIST_FOREACH(e_comp_wl->seats, ll, seat)
+     {
+   EINA_LIST_FOREACH(seat->kbd.resources, l, res)
      wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
                              e_comp_wl->xkb.fd,
                              e_comp_wl->xkb.size);
-   TRACE_INPUT_END();
-
    /* update modifiers */
-   e_comp_wl_input_keyboard_modifiers_update();
+   e_comp_wl_input_keyboard_modifiers_update(seat);
+     }
+
+   TRACE_INPUT_END();
 }
 
 EINTERN Eina_Bool
-e_comp_wl_input_init(void)
+e_comp_wl_input_add(const char *seatname)
 {
+   E_Comp_Wl_Seat *seat;
+
    /* set default seat name */
-   if (!e_comp_wl->seat.name)
-     e_comp_wl->seat.name = "default";
+   seat = E_NEW(E_Comp_Wl_Seat, 1);
+   if(!seat) return EINA_FALSE;
 
-   e_comp_wl->xkb.fd = -1;
-   dont_set_ecore_drm_keymap = getenv("NO_ECORE_DRM_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
-   dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
+   ERR("e_comp_wl_input_init() seatname:%s", seatname ? : "NULL");
+
+   if (!seatname) seat->name = "default";
+   else
+     {
+        seat->name = malloc(strlen(seatname) + 1);
+        strcpy(seat->name, seatname);
+     }
 
    /* get default keyboard repeat rate/delay from configuration */
-   e_comp_wl->kbd.repeat_delay = e_config->keyboard.repeat_delay;
-   e_comp_wl->kbd.repeat_rate = e_config->keyboard.repeat_rate;
+   seat->kbd.repeat_delay = e_config->keyboard.repeat_delay;
+   seat->kbd.repeat_rate = e_config->keyboard.repeat_rate;
 
    /* check for valid repeat_delay and repeat_rate value */
    /* if invalid, set the default value of repeat delay and rate value */
-   if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_delay = 400;
-   if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_rate = 25;
+   if (seat->kbd.repeat_delay < 0) seat->kbd.repeat_delay = 400;
+   if (seat->kbd.repeat_delay < 0) seat->kbd.repeat_rate = 25;
 
    /* create the global resource for input seat */
-   e_comp_wl->seat.global =
+   seat->global =
      wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
-                      e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
-   if (!e_comp_wl->seat.global)
+                      seat, _e_comp_wl_input_cb_bind_seat);
+   if (!seat->global)
      {
         ERR("Could not create global for seat: %m");
         return EINA_FALSE;
      }
 
-   wl_array_init(&e_comp_wl->kbd.keys);
-   wl_array_init(&e_comp_wl->kbd.routed_keys);
+   wl_array_init(&seat->kbd.keys);
+   wl_array_init(&seat->kbd.routed_keys);
 
-   E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
+   seat->resources = NULL;
+   seat->kbd.resources = NULL;
+   seat->ptr.resources = NULL;
+   seat->touch.resources = NULL;
+   seat->kbd.num_devices = 0;
+   seat->ptr.num_devices = 0;
+   seat->touch.num_devices = 0;
+
+   seat->device_list = NULL;
+   if ((seat->pointer = e_pointer_canvas_new(e_comp->ee, EINA_TRUE)))
+     {
+        e_pointer_hide(seat->pointer);
+     }
+
+   e_comp_wl->seats = eina_list_append(e_comp_wl->seats, seat);
 
    return EINA_TRUE;
 }
 
-EINTERN void
-e_comp_wl_input_shutdown(void)
+EINTERN Eina_Bool
+e_comp_wl_input_del(const char *seatname)
 {
    struct wl_resource *res;
+   E_Comp_Wl_Seat *seat;
+   E_Comp_Wl_Input_Device *dev;
+   e_devicemgr_input_device_user_data *device_user_data;
+
+   seat = e_comp_wl_input_seat_get(seatname);
+   if (!seat) return EINA_FALSE;
 
    /* destroy pointer resources */
-   EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
+   EINA_LIST_FREE(seat->ptr.resources, res)
      wl_resource_destroy(res);
 
    /* destroy keyboard resources */
-   EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
+   EINA_LIST_FREE(seat->kbd.resources, res)
      wl_resource_destroy(res);
-   e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
+   seat->kbd.resources = eina_list_free(seat->kbd.resources);
 
    /* destroy touch resources */
-   EINA_LIST_FREE(e_comp_wl->touch.resources, res)
+   EINA_LIST_FREE(seat->touch.resources, res)
      wl_resource_destroy(res);
 
    /* destroy e_comp_wl->kbd.keys array */
-   wl_array_release(&e_comp_wl->kbd.keys);
-   wl_array_release(&e_comp_wl->kbd.routed_keys);
+   wl_array_release(&seat->kbd.keys);
+   wl_array_release(&seat->kbd.routed_keys);
 
+   /* destroy the global seat resource */
+   if (seat->global)
+     wl_global_destroy(seat->global);
+   seat->global = NULL;
+
+   EINA_LIST_FREE(seat->device_list, dev)
+     {
+        if (dev->name) eina_stringshare_del(dev->name);
+        if (dev->identifier) eina_stringshare_del(dev->identifier);
+        EINA_LIST_FREE(dev->resources, res)
+          {
+             device_user_data = wl_resource_get_user_data(res);
+             if (device_user_data)
+               {
+                  device_user_data->dev = NULL;
+                  device_user_data->dev_mgr_res = NULL;
+                  device_user_data->seat_res = NULL;
+                  E_FREE(device_user_data);
+               }
+
+             wl_resource_set_user_data(res, NULL);
+          }
+
+        free(dev);
+     }
+   E_FREE_FUNC(seat->pointer, e_object_del);
+
+   free(seat);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_comp_wl_input_init(void)
+{
+   e_comp_wl->xkb.fd = -1;
+   dont_set_ecore_drm_keymap = getenv("NO_ECORE_DRM_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
+   dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
+
+   E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
+   E_EVENT_SEAT_BOUND = ecore_event_type_new();
+
+    return EINA_TRUE;
+}
+
+EINTERN void
+e_comp_wl_input_shutdown(void)
+{
    /* unmap any existing keyboard area */
    if (e_comp_wl->xkb.area)
      munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
@@ -570,11 +710,6 @@ e_comp_wl_input_shutdown(void)
    if (e_comp_wl->xkb.context)
      xkb_context_unref(e_comp_wl->xkb.context);
 
-   /* destroy the global seat resource */
-   if (e_comp_wl->seat.global)
-     wl_global_destroy(e_comp_wl->seat.global);
-   e_comp_wl->seat.global = NULL;
-
    dont_set_ecore_drm_keymap = EINA_FALSE;
    dont_use_xkb_cache = EINA_FALSE;
 }
@@ -594,7 +729,7 @@ e_comp_wl_input_keyboard_check(struct wl_resource *res)
 }
 
 EINTERN Eina_Bool
-e_comp_wl_input_keyboard_modifiers_serialize(void)
+e_comp_wl_input_keyboard_modifiers_serialize(E_Comp_Wl_Seat *seat)
 {
    Eina_Bool changed = EINA_FALSE;
    xkb_mod_mask_t mod;
@@ -602,48 +737,48 @@ e_comp_wl_input_keyboard_modifiers_serialize(void)
 
    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
                               XKB_STATE_DEPRESSED);
-   changed |= mod != e_comp_wl->kbd.mod_depressed;
-   e_comp_wl->kbd.mod_depressed = mod;
+   changed |= mod != seat->kbd.mod_depressed;
+   seat->kbd.mod_depressed = mod;
 
    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
                               XKB_STATE_MODS_LATCHED);
-   changed |= mod != e_comp_wl->kbd.mod_latched;
-   e_comp_wl->kbd.mod_latched = mod;
+   changed |= mod != seat->kbd.mod_latched;
+   seat->kbd.mod_latched = mod;
 
    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
                               XKB_STATE_MODS_LOCKED);
-   changed |= mod != e_comp_wl->kbd.mod_locked;
-   e_comp_wl->kbd.mod_locked = mod;
+   changed |= mod != seat->kbd.mod_locked;
+   seat->kbd.mod_locked = mod;
 
    grp = xkb_state_serialize_layout(e_comp_wl->xkb.state,
                                 XKB_STATE_LAYOUT_EFFECTIVE);
-   changed |= grp != e_comp_wl->kbd.mod_group;
-   e_comp_wl->kbd.mod_group = grp;
+   changed |= grp != seat->kbd.mod_group;
+   seat->kbd.mod_group = grp;
    return changed;
 }
 
 EINTERN void
-e_comp_wl_input_keyboard_modifiers_update(void)
+e_comp_wl_input_keyboard_modifiers_update(E_Comp_Wl_Seat *seat)
 {
    uint32_t serial;
    struct wl_resource *res;
    Eina_List *l;
 
-   if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
+   if (!e_comp_wl_input_keyboard_modifiers_serialize(seat)) return;
 
-   if (!e_comp_wl->kbd.focused) return;
+   if (!seat->kbd.focused) return;
 
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
+   EINA_LIST_FOREACH(seat->kbd.focused, l, res)
      wl_keyboard_send_modifiers(res, serial,
-                                e_comp_wl->kbd.mod_depressed,
-                                e_comp_wl->kbd.mod_latched,
-                                e_comp_wl->kbd.mod_locked,
-                                e_comp_wl->kbd.mod_group);
+                                seat->kbd.mod_depressed,
+                                seat->kbd.mod_latched,
+                                seat->kbd.mod_locked,
+                                seat->kbd.mod_group);
 }
 
 EINTERN void
-e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
+e_comp_wl_input_keyboard_state_update(E_Comp_Wl_Seat *seat, uint32_t keycode, Eina_Bool pressed)
 {
    enum xkb_key_direction dir;
 
@@ -652,38 +787,38 @@ e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
    if (pressed) dir = XKB_KEY_DOWN;
    else dir = XKB_KEY_UP;
 
-   e_comp_wl->kbd.mod_changed =
+   seat->kbd.mod_changed =
      xkb_state_update_key(e_comp_wl->xkb.state, keycode + 8, dir);
 
-   e_comp_wl_input_keyboard_modifiers_update();
+   e_comp_wl_input_keyboard_modifiers_update(seat);
 }
 
 E_API void
-e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
+e_comp_wl_input_pointer_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled)
 {
    /* check for valid compositor data */
-   if (!e_comp->wl_comp_data)
+   if (!seat)
      {
-        ERR("No compositor data");
+        ERR("No seat");
         return;
      }
 
-   e_comp_wl->ptr.enabled = !!enabled;
-   _e_comp_wl_input_update_seat_caps();
+   seat->ptr.enabled = !!enabled;
+   _e_comp_wl_input_update_seat_caps(seat);
 }
 
 E_API void
-e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
+e_comp_wl_input_keyboard_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled)
 {
    /* check for valid compositor data */
-   if (!e_comp->wl_comp_data)
+   if (!seat)
      {
-        ERR("No compositor data");
+        ERR("No seat");
         return;
      }
 
-   e_comp_wl->kbd.enabled = !!enabled;
-   _e_comp_wl_input_update_seat_caps();
+   seat->kbd.enabled = !!enabled;
+   _e_comp_wl_input_update_seat_caps(seat);
 }
 
 E_API Eina_Bool
@@ -768,7 +903,7 @@ e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *lay
    Eina_Bool use_dflt_xkb = EINA_FALSE;
    const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
 
-   /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
+    INF("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); 
    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
 
    if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
@@ -925,17 +1060,17 @@ e_comp_wl_input_keymap_default_options_get(void)
 }
 
 E_API void
-e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
+e_comp_wl_input_touch_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled)
 {
    /* check for valid compositor data */
-   if (!e_comp->wl_comp_data)
+   if (!seat)
      {
-        ERR("No compositor data");
+        ERR("No seat");
         return;
      }
 
-   e_comp_wl->touch.enabled = !!enabled;
-   _e_comp_wl_input_update_seat_caps();
+   seat->touch.enabled = !!enabled;
+   _e_comp_wl_input_update_seat_caps(seat);
 }
 
 EINTERN Eina_Bool
@@ -944,3 +1079,19 @@ e_comp_wl_input_touch_check(struct wl_resource *res)
    return wl_resource_instance_of(res, &wl_touch_interface,
                                   &_e_touch_interface);
 }
+
+E_API E_Comp_Wl_Seat *
+e_comp_wl_input_seat_get(const char *seatname)
+{
+   E_Comp_Wl_Seat *seat;
+   Eina_List *l;
+
+//   EINA_SAFETY_ON_NULL_RETURN_VAL(seatname, NULL);
+   if (!seatname) seatname = "default";
+
+   EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
+     if (eina_streq(seat->name, seatname))
+       return seat;
+
+   return NULL;
+}
index f7658f048982930e606f9844ced4320b0f326e77..94c62e23fc0283edb0d9bd44dded652ed6e57ab9 100644 (file)
@@ -4,28 +4,39 @@
 #  define E_COMP_WL_INPUT_H
 
 E_API extern int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE;
+E_API extern int E_EVENT_SEAT_BOUND;
 
 typedef struct _E_Event_Text_Input_Panel_Visibility_Change E_Event_Text_Input_Panel_Visibility_Change;
+typedef struct _E_Event_Seat_Bound E_Event_Seat_Bound;
 
 struct _E_Event_Text_Input_Panel_Visibility_Change
 {
    Eina_Bool visible;
 };
 
+struct _E_Event_Seat_Bound
+{
+   struct wl_client *client;
+   E_Comp_Wl_Seat *seat;
+};
+
 EINTERN Eina_Bool e_comp_wl_input_init(void);
 EINTERN void e_comp_wl_input_shutdown(void);
+EINTERN Eina_Bool e_comp_wl_input_add(const char *seatname);
+EINTERN Eina_Bool e_comp_wl_input_del(const char *seatname);
 EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
 EINTERN Eina_Bool e_comp_wl_input_keyboard_check(struct wl_resource *res);
 EINTERN Eina_Bool e_comp_wl_input_touch_check(struct wl_resource *res);
 
-EINTERN Eina_Bool e_comp_wl_input_keyboard_modifiers_serialize(void);
-EINTERN void e_comp_wl_input_keyboard_modifiers_update(void);
-EINTERN void e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed);
+EINTERN Eina_Bool e_comp_wl_input_keyboard_modifiers_serialize(E_Comp_Wl_Seat *seat);
+EINTERN void e_comp_wl_input_keyboard_modifiers_update(E_Comp_Wl_Seat *seat);
+EINTERN void e_comp_wl_input_keyboard_state_update(E_Comp_Wl_Seat *seat, uint32_t keycode, Eina_Bool pressed);
 EINTERN void e_comp_wl_input_keyboard_enter_send(E_Client *client);
+E_API E_Comp_Wl_Seat *e_comp_wl_input_seat_get(const char *seatname);
 
-E_API void e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled);
-E_API void e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled);
-E_API void e_comp_wl_input_touch_enabled_set(Eina_Bool enabled);
+E_API void e_comp_wl_input_pointer_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled);
+E_API void e_comp_wl_input_keyboard_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled);
+E_API void e_comp_wl_input_touch_enabled_set(E_Comp_Wl_Seat *seat, Eina_Bool enabled);
 
 E_API Eina_Bool e_comp_wl_input_keymap_cache_file_use_get(void);
 E_API Eina_Stringshare *e_comp_wl_input_keymap_path_get(struct xkb_rule_names names);
index 9d785b7e9ce463b3357cefe7f25a3f0a41633aac..186439b173e3045ca3c73c485f9b328f7a4ed87b 100644 (file)
@@ -99,22 +99,6 @@ static E_Comp_Wl_Remote_Manager *_rsm = NULL;
 static void _e_comp_wl_remote_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer);
 static void _remote_surface_region_clear(E_Comp_Wl_Remote_Surface *remote_surface);
 
-static Ecore_Device *
-_device_get_by_identifier(const char *identifier)
-{
-   Ecore_Device *dev = NULL;
-   const Eina_List *devices, *l;
-
-   devices = ecore_device_list();
-   EINA_LIST_FOREACH(devices, l, dev)
-     {
-        if (!e_util_strcmp(identifier, ecore_device_identifier_get(dev)))
-          return dev;
-     }
-
-   return NULL;
-}
-
 static void
 _remote_region_mirror_clear(E_Comp_Wl_Remote_Region *region)
 {
@@ -706,7 +690,7 @@ _remote_surface_cb_mouse_event_transfer(struct wl_client *client, struct wl_reso
      }
 
    /* find ecore device*/
-   edev = _device_get_by_identifier(identifier);
+   edev = ecore_device_find(identifier, eclas);
    if (edev)
      {
         eclas = ecore_device_class_get(edev);
@@ -814,7 +798,6 @@ _remote_surface_cb_mouse_wheel_transfer(struct wl_client *client, struct wl_reso
    if (e_object_is_del(E_OBJECT(ec))) return;
 
    /* identify class */
-   edev = _device_get_by_identifier(identifier);
 
    if (remote_surface->visible)
      e_client_mouse_wheel_send(ec, direction, z, edev, time);
@@ -852,7 +835,7 @@ _remote_surface_cb_touch_event_transfer(struct wl_client *client, struct wl_reso
      }
 
    /* find ecore device*/
-   edev = _device_get_by_identifier(identifier);
+   edev = ecore_device_find(identifier, eclas);
    if (edev)
      {
         eclas = ecore_device_class_get(edev);
@@ -960,7 +943,7 @@ _remote_surface_cb_key_event_transfer(struct wl_client *client, struct wl_resour
      }
 
    /* find ecore device*/
-   edev = _device_get_by_identifier(identifier);
+   edev = ecore_device_find(identifier, eclas);
    if (edev)
      {
         eclas = ecore_device_class_get(edev);
index b54010564ec9042e41754846f94c3d9e806c8170..baef95a7b9bc8105b5f934433b357b3f1c0e24b7 100644 (file)
@@ -57,7 +57,7 @@ typedef struct output_mode_info
 #define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiibbbiis"
 #define VALUE_TYPE_REQUEST_RESLIST "ui"
 #define VALUE_TYPE_REPLY_RESLIST "ssi"
-#define VALUE_TYPE_FOR_INPUTDEV "ssi"
+#define VALUE_TYPE_FOR_INPUTDEV "sssi"
 
 static E_Info_Client e_info_client;
 
@@ -191,11 +191,13 @@ _cb_input_device_info_get(const Eldbus_Message *msg)
      {
         char *dev_name;
         char *identifier;
+        char *seatname;
         int clas;
         res = eldbus_message_iter_arguments_get(eldbus_msg,
                                                 VALUE_TYPE_FOR_INPUTDEV,
                                                 &dev_name,
                                                 &identifier,
+                                                &seatname,
                                                 &clas);
         if (!res)
           {
@@ -206,6 +208,7 @@ _cb_input_device_info_get(const Eldbus_Message *msg)
         dev = E_NEW(E_Comp_Wl_Input_Device, 1);
         dev->name = strdup(dev_name);
         dev->identifier = strdup(identifier);
+        dev->seatname = strdup(seatname);
         dev->clas = clas;
 
         e_info_client.input_dev = eina_list_append(e_info_client.input_dev, dev);
@@ -486,7 +489,7 @@ _e_info_client_proc_input_device_info(int argc, char **argv)
      return;
 
    printf("--------------------------------------[ input devices ]----------------------------------------------------------\n");
-   printf(" No                               Name                        identifier            Cap\n");
+   printf(" No                               Name                        identifier            Seatname            Cap\n");
    printf("-----------------------------------------------------------------------------------------------------------------\n");
 
    if (!e_info_client.input_dev)
@@ -498,7 +501,7 @@ _e_info_client_proc_input_device_info(int argc, char **argv)
    EINA_LIST_FOREACH(e_info_client.input_dev, l, dev)
      {
         i++;
-        printf("%3d %50s %20s         ", i, dev->name, dev->identifier);
+        printf("%3d %50s %20s %20s        ", i, dev->name, dev->identifier, dev->seatname);
         if (dev->clas == ECORE_DEVICE_CLASS_MOUSE) printf("Mouse | ");
         else if (dev->clas == ECORE_DEVICE_CLASS_KEYBOARD) printf("Keyboard | ");
         else if (dev->clas == ECORE_DEVICE_CLASS_TOUCH) printf("Touch | ");
index b672be282370e3cab80b2ac813fea8d94f3b27c0..a35623f3de3a233be94cc088b905474f4eb36444 100644 (file)
@@ -70,7 +70,7 @@ static Eina_List *module_hook = NULL;
 #define VALUE_TYPE_FOR_TOPVWINS "uuisiiiiibbiibbbiis"
 #define VALUE_TYPE_REQUEST_RESLIST "ui"
 #define VALUE_TYPE_REPLY_RESLIST "ssi"
-#define VALUE_TYPE_FOR_INPUTDEV "ssi"
+#define VALUE_TYPE_FOR_INPUTDEV "sssi"
 
 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 keep_ratio);
 static E_Info_Transform *_e_info_transform_find(E_Client *ec, int id);
@@ -176,24 +176,26 @@ static void
 _input_msg_clients_append(Eldbus_Message_Iter *iter)
 {
    Eldbus_Message_Iter *array_of_input;
-   Eina_List *l;
-   E_Comp_Wl_Data *cdata;
+   Eina_List *l, *ll;
    E_Comp_Wl_Input_Device *dev;
+   E_Comp_Wl_Seat *seat;
 
    eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_INPUTDEV")", &array_of_input);
 
-   cdata = e_comp->wl_comp_data;
-   EINA_LIST_FOREACH(cdata->input_device_manager.device_list, l, dev)
+   EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
      {
-        Eldbus_Message_Iter *struct_of_input;
+        EINA_LIST_FOREACH(seat->device_list, ll, dev)
+          {
+             Eldbus_Message_Iter *struct_of_input;
 
-        eldbus_message_iter_arguments_append(array_of_input, "("VALUE_TYPE_FOR_INPUTDEV")", &struct_of_input);
+             eldbus_message_iter_arguments_append(array_of_input, "("VALUE_TYPE_FOR_INPUTDEV")", &struct_of_input);
 
-        eldbus_message_iter_arguments_append
-                     (struct_of_input, VALUE_TYPE_FOR_INPUTDEV,
-                      dev->name, dev->identifier, dev->clas);
+             eldbus_message_iter_arguments_append
+                          (struct_of_input, VALUE_TYPE_FOR_INPUTDEV,
+                           dev->name, dev->identifier, dev->seatname, dev->clas);
 
-        eldbus_message_iter_container_close(array_of_input, struct_of_input);
+             eldbus_message_iter_container_close(array_of_input, struct_of_input);
+          }
      }
    eldbus_message_iter_container_close(iter, array_of_input);
 }
index 925a17eefbf63a3a98d994bafe2da20bc42a009c..252b41e0b0580b9e1e708a260c4f189387c38fad 100644 (file)
@@ -175,11 +175,13 @@ EINTERN void
 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
 {
    E_Client *ec;
+   E_Comp_Wl_Seat *seat;
 
    EINA_SAFETY_ON_NULL_RETURN(ptr);
+   seat = e_comp_wl_input_seat_get("default");
 
    /* don't show cursor if in hidden mode */
-   if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
+   if ((!e_config->show_cursor) || (seat && (!seat->ptr.enabled)))
      {
         e_pointer_hide(ptr);
         return;
index 9c79e2a03c3b1dc1e70f7279c29bf79a12d63947..37dcc24faecc644503c5768a930819e8c8b2cef7 100644 (file)
@@ -403,9 +403,14 @@ _volume_wl_touch_resource_get(void)
    struct wl_resource *res;
 
    if (_volume_wl_touch) goto end;
+   if (!_volume_ec->seat)
+     {
+        _volume_ec->seat = e_comp_wl_input_seat_get(NULL);
+        if (!_volume_ec->seat) goto end;
+     }
 
    wc = wl_resource_get_client(_volume_ec->comp_data->surface);
-   EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
+   EINA_LIST_FOREACH(_volume_ec->seat->touch.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
 
index c17bc13331a065b5e438784cb0f95d6f530dbd79..b12afcb3beb9abfd5d53a4f1a6e2e1491f92428b 100644 (file)
@@ -135,11 +135,28 @@ _e_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resourc
      }
 }
 
+static E_Comp_Wl_Seat *
+_e_util_seat_get(struct wl_resource *seat_res)
+{
+   E_Comp_Wl_Seat *seat = NULL;
+   struct wl_resource *res;
+   Eina_List *l, *ll;
+
+   EINA_LIST_FOREACH(e_comp_wl->seats, l, seat)
+     {
+        EINA_LIST_FOREACH(seat->resources, ll, res)
+          if (res == seat_res) return seat;
+     }
+
+   return seat;
+}
+
 static void
-_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED)
+_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED)
 {
    E_Client *ec;
    E_Binding_Event_Mouse_Button ev;
+   E_Comp_Wl_Seat *seat;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -152,7 +169,8 @@ _e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resourc
 
    if ((ec->maximized) || (ec->fullscreen)) return;
 
-   switch (e_comp_wl->ptr.button)
+   seat = _e_util_seat_get(seat_resource);
+   switch (seat->ptr.button)
      {
       case BTN_LEFT:
         ev.button = 1;
@@ -164,23 +182,24 @@ _e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resourc
         ev.button = 3;
         break;
       default:
-        ev.button = e_comp_wl->ptr.button;
+        ev.button = seat->ptr.button;
         break;
      }
 
    e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   wl_fixed_to_int(seat->ptr.x),
+                                   wl_fixed_to_int(seat->ptr.y),
                                    &ev.canvas.x, &ev.canvas.y);
 
    _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE);
 }
 
 static void
-_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges)
+_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED, uint32_t edges)
 {
    E_Client *ec;
    E_Binding_Event_Mouse_Button ev;
+   E_Comp_Wl_Seat *seat;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -196,12 +215,13 @@ _e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resou
 
    if ((ec->maximized) || (ec->fullscreen)) return;
 
+   seat = _e_util_seat_get(seat_resource);
    e_comp_wl->resize.resource = resource;
    e_comp_wl->resize.edges = edges;
-   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
-   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
+   seat->ptr.grab_x = seat->ptr.x - wl_fixed_from_int(ec->client.x);
+   seat->ptr.grab_y = seat->ptr.y - wl_fixed_from_int(ec->client.y);
 
-   switch (e_comp_wl->ptr.button)
+   switch (seat->ptr.button)
      {
       case BTN_LEFT:
         ev.button = 1;
@@ -213,13 +233,13 @@ _e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resou
         ev.button = 3;
         break;
       default:
-        ev.button = e_comp_wl->ptr.button;
+        ev.button = seat->ptr.button;
         break;
      }
 
    e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   wl_fixed_to_int(seat->ptr.x),
+                                   wl_fixed_to_int(seat->ptr.y),
                                    &ev.canvas.x, &ev.canvas.y);
 
    _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE);
@@ -765,10 +785,11 @@ _e_xdg_shell_surface_cb_window_menu_show(struct wl_client *client EINA_UNUSED, s
 }
 
 static void
-_e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED)
+_e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial EINA_UNUSED)
 {
    E_Client *ec;
    E_Binding_Event_Mouse_Button ev;
+   E_Comp_Wl_Seat *seat;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -781,19 +802,21 @@ _e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_res
 
    if ((ec->maximized) || (ec->fullscreen)) return;
 
+   seat = _e_util_seat_get(seat_resource);
+
    TRACE_DS_BEGIN(SHELL:SURFACE MOVE REQUEST CB);
 
-   switch (e_comp_wl->ptr.button)
+   switch (seat->ptr.button)
      {
       case BTN_LEFT:   ev.button = 1; break;
       case BTN_MIDDLE: ev.button = 2; break;
       case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
+      default:         ev.button = seat->ptr.button; break;
      }
 
    e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   wl_fixed_to_int(seat->ptr.x),
+                                   wl_fixed_to_int(seat->ptr.y),
                                    &ev.canvas.x,
                                    &ev.canvas.y);
 
@@ -807,6 +830,7 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r
 {
    E_Client *ec;
    E_Binding_Event_Mouse_Button ev;
+   E_Comp_Wl_Seat *seat;
 
    /* get the client for this resource */
    if (!(ec = wl_resource_get_user_data(resource)))
@@ -822,24 +846,26 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r
 
    if ((ec->maximized) || (ec->fullscreen)) return;
 
+   seat = _e_util_seat_get(seat_resource);
+
    TRACE_DS_BEGIN(SHELL:SURFACE RESIZE REQUEST CB);
 
    e_comp_wl->resize.resource = resource;
    e_comp_wl->resize.edges = edges;
-   e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
-   e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
+   seat->ptr.grab_x = seat->ptr.x - wl_fixed_from_int(ec->client.x);
+   seat->ptr.grab_y = seat->ptr.y - wl_fixed_from_int(ec->client.y);
 
-   switch (e_comp_wl->ptr.button)
+   switch (seat->ptr.button)
      {
       case BTN_LEFT:   ev.button = 1; break;
       case BTN_MIDDLE: ev.button = 2; break;
       case BTN_RIGHT:  ev.button = 3; break;
-      default:         ev.button = e_comp_wl->ptr.button; break;
+      default:         ev.button = seat->ptr.button; break;
      }
 
    e_comp_object_frame_xy_unadjust(ec->frame,
-                                   wl_fixed_to_int(e_comp_wl->ptr.x),
-                                   wl_fixed_to_int(e_comp_wl->ptr.y),
+                                   wl_fixed_to_int(seat->ptr.x),
+                                   wl_fixed_to_int(seat->ptr.y),
                                    &ev.canvas.x,
                                    &ev.canvas.y);