2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2003-01-05 04:55:37 -08:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
|
|
|
/* private calls */
|
|
|
|
|
|
|
|
/* FIXME: this is not optimal, but works. i should have a hash of keys per */
|
|
|
|
/* Evas and then a linked lists of grabs for that key and what */
|
|
|
|
/* modifiers/not_modifers they use */
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
static Evas_Key_Grab *evas_key_grab_new (Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive);
|
2016-06-01 01:44:12 -07:00
|
|
|
static Evas_Key_Grab *evas_key_grab_find (Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
|
2003-01-05 04:55:37 -08:00
|
|
|
|
|
|
|
static Evas_Key_Grab *
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_key_grab_new(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
|
|
|
/* MEM OK */
|
2016-06-01 01:44:12 -07:00
|
|
|
Eina_List *l;
|
2003-01-05 04:55:37 -08:00
|
|
|
Evas_Key_Grab *g;
|
2016-06-01 01:44:12 -07:00
|
|
|
Eina_Bool have_exclusion = EINA_FALSE;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(obj->layer->evas->grabs, l, g)
|
|
|
|
{
|
|
|
|
if ((g->modifiers == modifiers) &&
|
|
|
|
(g->not_modifiers == not_modifiers) &&
|
|
|
|
(!strcmp(g->keyname, keyname)) &&
|
|
|
|
(g->exclusive))
|
|
|
|
{
|
|
|
|
have_exclusion = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (have_exclusion && exclusive) return NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-01-05 04:55:37 -08:00
|
|
|
g = evas_mem_calloc(sizeof(Evas_Key_Grab));
|
2003-10-17 20:34:00 -07:00
|
|
|
if (!g) return NULL;
|
2012-10-08 18:58:41 -07:00
|
|
|
g->object = eo_obj;
|
2003-01-19 21:05:16 -08:00
|
|
|
g->modifiers = modifiers;
|
|
|
|
g->not_modifiers = not_modifiers;
|
|
|
|
g->exclusive = exclusive;
|
2003-01-05 04:55:37 -08:00
|
|
|
g->keyname = strdup(keyname);
|
2003-07-07 23:08:26 -07:00
|
|
|
if (obj->layer->evas->walking_grabs)
|
2011-11-12 00:06:30 -08:00
|
|
|
g->just_added = EINA_TRUE;
|
2016-06-01 01:44:12 -07:00
|
|
|
g->is_active = EINA_TRUE;
|
2003-01-05 04:55:37 -08:00
|
|
|
if (!g->keyname)
|
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
if (!evas_mem_free(strlen(keyname) + 1))
|
|
|
|
{
|
|
|
|
free(g);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
g->keyname = strdup(keyname);
|
|
|
|
if (!g->keyname)
|
|
|
|
{
|
|
|
|
free(g);
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
2016-06-01 01:44:12 -07:00
|
|
|
|
|
|
|
if (exclusive)
|
|
|
|
{
|
|
|
|
Evas_Key_Grab *ge;
|
|
|
|
EINA_LIST_FOREACH(obj->layer->evas->grabs, l, ge)
|
|
|
|
{
|
|
|
|
if ((ge->modifiers == modifiers) &&
|
|
|
|
(ge->not_modifiers == not_modifiers) &&
|
|
|
|
(!strcmp(ge->keyname, keyname)))
|
|
|
|
{
|
|
|
|
ge->is_active = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (have_exclusion) g->is_active = EINA_FALSE;
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
obj->grabs = eina_list_append(obj->grabs, g);
|
2008-10-21 09:31:05 -07:00
|
|
|
obj->layer->evas->grabs = eina_list_append(obj->layer->evas->grabs, g);
|
2003-01-05 04:55:37 -08:00
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Key_Grab *
|
2016-06-01 01:44:12 -07:00
|
|
|
evas_key_grab_find(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
|
|
|
/* MEM OK */
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
|
|
|
Evas_Key_Grab *g;
|
2003-01-19 19:54:00 -08:00
|
|
|
|
2008-10-21 09:31:05 -07:00
|
|
|
EINA_LIST_FOREACH(obj->layer->evas->grabs, l, g)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
if ((g->modifiers == modifiers) &&
|
|
|
|
(g->not_modifiers == not_modifiers) &&
|
|
|
|
(!strcmp(g->keyname, keyname)))
|
|
|
|
{
|
2016-06-01 01:44:12 -07:00
|
|
|
if (eo_obj == g->object) return g;
|
2011-11-12 00:06:30 -08:00
|
|
|
}
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* local calls */
|
|
|
|
|
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_grabs_cleanup(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
2015-10-15 16:27:10 -07:00
|
|
|
if ((!obj->layer) || (!obj->layer->evas)) return;
|
2003-07-17 03:01:13 -07:00
|
|
|
if (obj->layer->evas->walking_grabs)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
Eina_List *l;
|
|
|
|
Evas_Key_Grab *g;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2011-11-12 00:06:30 -08:00
|
|
|
EINA_LIST_FOREACH(obj->grabs, l, g)
|
|
|
|
g->delete_me = EINA_TRUE;
|
2003-07-17 03:01:13 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
while (obj->grabs)
|
|
|
|
{
|
|
|
|
Evas_Key_Grab *g = obj->grabs->data;
|
2013-07-08 00:07:08 -07:00
|
|
|
obj->layer->evas->grabs =
|
|
|
|
eina_list_remove(obj->layer->evas->grabs, g);
|
|
|
|
obj->grabs = eina_list_remove(obj->grabs, g);
|
2011-11-12 00:06:30 -08:00
|
|
|
if (g->keyname) free(g->keyname);
|
|
|
|
free(g);
|
|
|
|
}
|
2003-07-17 03:01:13 -07:00
|
|
|
}
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
|
|
|
|
2003-07-07 23:08:26 -07:00
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_key_grab_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
|
2003-07-07 23:08:26 -07:00
|
|
|
{
|
|
|
|
/* MEM OK */
|
|
|
|
Evas_Key_Grab *g;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2016-06-01 01:44:12 -07:00
|
|
|
g = evas_key_grab_find(eo_obj, obj, keyname, modifiers, not_modifiers);
|
2003-07-07 23:08:26 -07:00
|
|
|
if (!g) return;
|
2014-06-02 06:47:59 -07:00
|
|
|
Evas_Object_Protected_Data *g_object = eo_data_scope_get(g->object, EVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
g_object->grabs = eina_list_remove(g_object->grabs, g);
|
2008-10-21 09:31:05 -07:00
|
|
|
obj->layer->evas->grabs = eina_list_remove(obj->layer->evas->grabs, g);
|
2003-07-07 23:08:26 -07:00
|
|
|
if (g->keyname) free(g->keyname);
|
|
|
|
free(g);
|
|
|
|
}
|
|
|
|
|
2003-01-05 04:55:37 -08:00
|
|
|
/* public calls */
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN Eina_Bool
|
|
|
|
_evas_object_key_grab(Eo *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2003-01-05 04:55:37 -08:00
|
|
|
/* MEM OK */
|
|
|
|
Evas_Key_Grab *g;
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
if (((modifiers == not_modifiers) && (modifiers != 0)) || (!keyname)) return EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
g = evas_key_grab_new(eo_obj, obj, keyname, modifiers, not_modifiers, exclusive);
|
2014-03-11 04:51:35 -07:00
|
|
|
return ((!g) ? EINA_FALSE : EINA_TRUE);
|
2003-01-05 04:55:37 -08:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:51:35 -07:00
|
|
|
EOLIAN void
|
|
|
|
_evas_object_key_ungrab(Eo *eo_obj, Evas_Object_Protected_Data *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
|
2003-01-05 04:55:37 -08:00
|
|
|
{
|
|
|
|
/* MEM OK */
|
|
|
|
Evas_Key_Grab *g;
|
2016-06-01 01:44:12 -07:00
|
|
|
Eina_List *l;
|
2003-01-05 04:55:37 -08:00
|
|
|
|
2003-01-19 22:44:07 -08:00
|
|
|
if (!keyname) return;
|
2016-06-01 01:44:12 -07:00
|
|
|
g = evas_key_grab_find(eo_obj, obj, keyname, modifiers, not_modifiers);
|
2003-01-05 04:55:37 -08:00
|
|
|
if (!g) return;
|
2014-06-02 06:47:59 -07:00
|
|
|
Evas_Object_Protected_Data *g_object = eo_data_scope_get(g->object, EVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
if (g_object->layer->evas->walking_grabs)
|
2003-07-07 23:08:26 -07:00
|
|
|
{
|
2011-11-12 00:06:30 -08:00
|
|
|
if (!g->delete_me)
|
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
g_object->layer->evas->delete_grabs++;
|
2011-11-12 00:06:30 -08:00
|
|
|
g->delete_me = EINA_TRUE;
|
|
|
|
}
|
2003-07-07 23:08:26 -07:00
|
|
|
}
|
|
|
|
else
|
2016-06-01 01:44:12 -07:00
|
|
|
{
|
|
|
|
if (g->exclusive)
|
|
|
|
{
|
|
|
|
Evas_Key_Grab *ge;
|
|
|
|
EINA_LIST_FOREACH(obj->layer->evas->grabs, l, ge)
|
|
|
|
{
|
|
|
|
if ((ge->modifiers == modifiers) &&
|
|
|
|
(ge->not_modifiers == not_modifiers) &&
|
|
|
|
(!strcmp(ge->keyname, keyname)))
|
|
|
|
{
|
|
|
|
if (!ge->is_active) ge->is_active = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-03-11 04:51:35 -07:00
|
|
|
|
2016-06-01 01:44:12 -07:00
|
|
|
evas_key_grab_free(g->object, g_object, keyname, modifiers, not_modifiers);
|
|
|
|
}
|
|
|
|
}
|