static Eina_Bool _ecore_wl_fatal_error = EINA_FALSE;
static Eina_Bool _ecore_wl_server_mode = EINA_FALSE;
// TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
+static Eina_Hash *_keygrabs = NULL;
static int _ecore_wl_keygrab_error = -1;
//
if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
if (!_ecore_wl_disp) return _ecore_wl_init_count;
+ if (_keygrabs)
+ {
+ eina_hash_free(_keygrabs);
+ _keygrabs = NULL;
+ }
+
_ecore_wl_events_shutdown();
_ecore_wl_window_shutdown();
// TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
//Currently this function is only used in sink call, so use global value(_ecore_wl_keygrab_error) and just check the error is ok.
+/* internal functions */
+static Eina_Bool
+_ecore_wl_keygrab_hash_add(void *key, void *data)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!_keygrabs)
+ _keygrabs = eina_hash_int32_new(NULL);
+ ret = eina_hash_add(_keygrabs, key, data);
+ return ret;
+}
+
+static Eina_Bool
+_ecore_wl_keygrab_hash_del(void *key)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ ret = eina_hash_del_by_key(_keygrabs, key);
+
+ return ret;
+}
+
+Eina_Hash *
+_ecore_wl_keygrab_hash_get(void)
+{
+ return _keygrabs;
+}
+
static void
_ecore_wl_cb_keygrab_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t key, uint32_t mode, uint32_t error)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!key) return EINA_FALSE;
- if ((grab_mode < ECORE_WL_WINDOW_KEYGRAB_UNKNOWN) || (grab_mode > ECORE_WL_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE))
+ if ((grab_mode < ECORE_WL_WINDOW_KEYGRAB_UNKNOWN) || (grab_mode > ECORE_WL_WINDOW_KEYGRAB_EXCLUSIVE))
return EINA_FALSE;
INF("win=%p key=%s mod=%d", win, key, grab_mode);
if (!_ecore_wl_keygrab_error)
{
INF("[PID:%d]Succeed to get return value !", getpid());
+ if (_ecore_wl_keygrab_hash_add(&keycode, surface))
+ INF("Succeed to add key to the keygrab hash!");
+ //TODO: deal with if (win == NULL)
+ else
+ WRN("Failed to add key to the keygrab hash!");
ret = EINA_TRUE;
}
else
INF("After keygrab _ecore_wl_keygrab_error = %d", _ecore_wl_keygrab_error);
if (!_ecore_wl_keygrab_error)
{
+ INF("[PID:%d]Succeed to get return value !", getpid());
+ if (_ecore_wl_keygrab_hash_del(&keycode))
+ INF("Succeed to delete key from the keygrab hash!");
+ else
+ WRN("Failed to delete key from the keygrab hash!");
ret = EINA_TRUE;
- INF("[PID:%d] Succeed to get return value ! ", getpid());
}
else
{
char key[256], keyname[256], compose[256];
Ecore_Event_Key *e;
+ struct wl_surface *surface = NULL;
+
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(input = data)) return;
win = input->keyboard_focus;
- if ((!win) || (win->keyboard_device != input) || (!input->xkb.state))
- return;
-
- input->display->serial = serial;
/* xkb rules reflect X broken keycodes, so offset by 8 */
code = keycode + 8;
+ if (!win)
+ {
+ INF("window is not focused");
+ surface = (struct wl_surface *) eina_hash_find(_ecore_wl_keygrab_hash_get(), &code);
+ if (surface)
+ {
+ win = ecore_wl_window_surface_find(surface);
+ INF("keycode(%d) is grabbed in the window(%p)", code, win);
+ }
+ else
+ {
+ //key event callback can be called even though surface is not exist.
+ //TODO: Ecore_Event_Key have event_window info, so if (surface == NULL), we should generate proper window info
+ WRN("surface is not exist");
+ return;
+ }
+ }
+ else
+ {
+ if ((win->keyboard_device != input))
+ {
+ INF("window(%p) is focused, but keyboard device info is wrong", win);
+ return;
+ }
+ }
+
+ if (!input->xkb.state)
+ {
+ WRN("xkb state is wrong");
+ return;
+ }
+
+ input->display->serial = serial;
+
/* get the keysym for this key code */
nsyms = xkb_key_get_syms(input->xkb.state, code, &syms);
if (nsyms == 1) sym = syms[0];