}
g_rec_mutex_init(&e_comp_input_key->xkb.keymap_mutex);
+ g_rec_mutex_init(&e_comp_input_key->kbd.resources_mutex);
+ g_rec_mutex_init(&e_comp_input_key->kbd.focused_mutex);
e_comp_input = E_NEW(E_Comp_Input, 1);
if (!e_comp_input)
xkb_context_unref(e_comp_input_key->xkb.context);
g_rec_mutex_clear(&e_comp_input_key->xkb.keymap_mutex);
+ g_rec_mutex_clear(&e_comp_input_key->kbd.resources_mutex);
+ g_rec_mutex_clear(&e_comp_input_key->kbd.focused_mutex);
E_FREE(e_comp_input_key);
}
return ((E_Comp_Input_Key_Data *)input_thread_info)->kbd.repeat_rate;
}
+
+E_API void
+e_input_thread_info_kbd_resource_list_lock(E_Input_Thread_Info *input_thread_info)
+{
+ EINA_SAFETY_ON_NULL_RETURN(input_thread_info);
+
+ g_rec_mutex_lock(&((E_Comp_Input_Key_Data *)input_thread_info)->kbd.resources_mutex);
+}
+
+E_API void
+e_input_thread_info_kbd_resource_list_unlock(E_Input_Thread_Info *input_thread_info)
+{
+ EINA_SAFETY_ON_NULL_RETURN(input_thread_info);
+
+ g_rec_mutex_unlock(&((E_Comp_Input_Key_Data *)input_thread_info)->kbd.resources_mutex);
+}
\ No newline at end of file
atomic_int repeat_delay;
atomic_int repeat_rate;
unsigned int num_devices;
+ GRecMutex resources_mutex;
+ GRecMutex focused_mutex;
} kbd;
};
Eina_List *l;
double t;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (!e_comp_input_key->kbd.focused)
{
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
return;
}
k->key, WL_KEYBOARD_KEY_STATE_PRESSED);
}
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
static Eina_Bool
wc = wl_resource_get_client(surface);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
{
if (wl_resource_get_client(res) == wc)
{
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (!eina_list_data_find(e_comp_input_key->kbd.focused, res))
e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (!e_comp_input_key->kbd.focused)
{
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
return;
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
e_comp_input_key->kbd.focus = surface;
e_comp_wl_input_keyboard_enter_send(surface);
if (!surface) return;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
if (!eina_list_count(e_comp_input_key->kbd.resources))
{
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
return;
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
/* send keyboard_leave to all keyboard resources */
serial = wl_display_next_serial(e_comp_wl_display_get());
t = ecore_time_unix_get();
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
{
wl_array_for_each(k, &e_comp_input_key->kbd.keys)
e_comp_input_key->kbd.focused =
eina_list_remove_list(e_comp_input_key->kbd.focused, l);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
static void
if (surface_client &&
(ec == e_client_focused_get()))
{
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
{
if (wl_resource_get_client(res) ==
eina_list_remove_list(e_comp_input_key->kbd.focused, l);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
e_comp_wl_client_surface_set(ec, NULL);
struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
if (ec && ec->comp_data && surface)
{
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (e_comp_input_key->kbd.focused)
{
_e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_input_key->kbd.focused, ec);
if (!(k = wl_array_add(&e_comp_input_key->kbd.keys, sizeof(*k))))
{
DBG("wl_array_add: Out of memory\n");
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
return EINA_FALSE;
}
k->key = keycode;
k->dev = ev->dev;
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
}
{
ec = e_client_focused_get();
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (e_comp_input_key->kbd.focused)
{
_e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_input_key->kbd.focused, ec);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
/* update modifier state */
ELOGF("INPUT", "wl_keyboard_send_key:%s:%d|B|", NULL, (state ? "PRESS" : "RELEASE"), keycode);
}
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
{
if (wl_resource_get_client(res) != wc) continue;
wl_keyboard_send_key(res, serial, time,
wl_keycode, state);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
if (e_config->key_input_ttrace_enable)
{
e_input_thread_request_boost();
e_keyrouter_wl_event_surface_send(surface, wl_keycode, TIZEN_KEYROUTER_MODE_NONE);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
{
if (wl_resource_get_client(res) != wc) continue;
wl_keyboard_send_key(res, serial, time,
cancel_keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
return EINA_TRUE;
}
resource = *(struct wl_resource **)data;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
e_comp_input_key->kbd.resources =
eina_list_remove(e_comp_input_key->kbd.resources, resource);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
if (res == resource)
e_comp_input_key->kbd.focused =
eina_list_remove_list(e_comp_input_key->kbd.focused, l);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
static void
xkb_layout_index_t mod_group;
E_Comp_Wl_Data *comp_wl;
- if (!e_comp_input_key->kbd.focused) return;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
+ if (!e_comp_input_key->kbd.focused)
+ {
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+ return;
+ }
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
e_comp_wl_input_keyboard_modifiers_serialize();
mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
{
wl_keyboard_send_enter(res, serial, surface,
mod_locked,
mod_group);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+}
+
+static enum wl_iterator_result
+_e_comp_wl_input_get_resource(struct wl_resource *resource, void *data)
+{
+ Eina_List *l, *ll;
+ struct wl_resource *res;
+
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
+ e_comp_input_key->kbd.resources = eina_list_remove(e_comp_input_key->kbd.resources, resource);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
+ EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
+ {
+ if (res == resource)
+ e_comp_input_key->kbd.focused = eina_list_remove_list(e_comp_input_key->kbd.focused, l);
+ }
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+
+ return WL_ITERATOR_CONTINUE;
+}
+
+static void
+_e_comp_wl_input_cb_wl_client_destroy(struct wl_listener *l, void *data)
+{
+ struct wl_client *client = data;
+
+ wl_client_for_each_resource(client, _e_comp_wl_input_get_resource, NULL);
+ wl_list_remove(&l->link);
+ E_FREE(l);
}
static void
res = keyboard_get_data->resource;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
e_comp_input_key->kbd.resources =
eina_list_append(e_comp_input_key->kbd.resources, res);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
/* send current repeat_info */
if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
if (!surface) return;
if (keyboard_get_data->client != wl_resource_get_client(surface)) return;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
e_comp_wl_input_keyboard_enter_send(surface);
}
_e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
{
struct wl_resource *res;
+ struct wl_listener *destroy_listener = NULL;
E_Input_Thread_Request_Keyboard_Get_Data keyboard_get_data;
E_Comp_Wl_Data *comp_wl = e_comp_wl_get();
keyboard_get_data.client = client;
_e_comp_wl_input_thread_cb_keyboard_get(&keyboard_get_data);
+
+ destroy_listener = E_NEW(struct wl_listener, 1);
+ if (!destroy_listener)
+ {
+ KLERR("Failed to allocate memory for wl_client destroy listener !");
+ return;
+ }
+
+ destroy_listener->notify = _e_comp_wl_input_cb_wl_client_destroy;
+ wl_client_add_destroy_listener(client, destroy_listener);
}
static void
/* send updated keymap */
TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
e_comp_input_key->xkb.fd,
e_comp_input_key->xkb.size);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
TRACE_INPUT_END();
/* update modifiers */
E_Comp_Wl_Data *comp_wl = e_comp_wl_get();
if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (!e_comp_input_key->kbd.focused)
{
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
return;
}
e_comp_input_key->kbd.mod_latched,
e_comp_input_key->kbd.mod_locked,
e_comp_input_key->kbd.mod_group);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
EINTERN void
atomic_store(&e_comp_input_key->kbd.repeat_delay, delay);
atomic_store(&e_comp_input_key->kbd.repeat_rate, rate);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
{
if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate,
e_comp_input_key->kbd.repeat_delay);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
}
typedef struct _keycode_map{
EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
return e_comp_input_key->kbd.repeat_rate;
}
+
+E_API void
+e_comp_wl_input_kbd_reousrce_list_lock()
+{
+ EINA_SAFETY_ON_NULL_RETURN(e_comp_input_key);
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
+}
+
+E_API void
+e_comp_wl_input_kbd_reousrce_list_unlock()
+{
+ EINA_SAFETY_ON_NULL_RETURN(e_comp_input_key);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+}
if (!focused)
{
+ g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
_e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.resources, EINA_FALSE, client, surface);
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
return EINA_FALSE;
}
struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
if (surface)
{
+ g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
if (e_comp_input_key->kbd.focused)
{
wc = wl_resource_get_client(surface);
_e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.focused, EINA_TRUE, wc, surface);
}
+ g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
}
/* update modifier state */
E_API const Eina_List * e_comp_wl_input_kbd_resources_get();
E_API int e_comp_wl_input_kbd_repeat_delay_get();
E_API int e_comp_wl_input_kbd_repeat_rate_get();
+E_API void e_comp_wl_input_kbd_reousrce_list_lock();
+E_API void e_comp_wl_input_kbd_reousrce_list_unlock();
#endif
E_API Eina_List *e_input_thread_info_kbd_resource_list_get(E_Input_Thread_Info *input_thread_info);
E_API int e_input_thread_info_kbd_repeat_delay_get(E_Input_Thread_Info *input_thread_info);
E_API int e_input_thread_info_kbd_repeat_rate_get(E_Input_Thread_Info *input_thread_info);
-
+E_API void e_input_thread_info_kbd_resource_list_lock(E_Input_Thread_Info *input_thread_info);
+E_API void e_input_thread_info_kbd_resource_list_unlock(E_Input_Thread_Info *input_thread_info);
#endif