1 #include "evas_common.h"
2 #include "evas_private.h"
6 /* FIXME: this is not optimal, but works. i should have a hash of keys per */
7 /* Evas and then a linked lists of grabs for that key and what */
8 /* modifiers/not_modifers they use */
10 static Evas_Key_Grab *evas_key_grab_new (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
11 static Evas_Key_Grab *evas_key_grab_find (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
13 static Evas_Key_Grab *
14 evas_key_grab_new(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive)
19 g = evas_mem_calloc(sizeof(Evas_Key_Grab));
22 g->modifiers = modifiers;
23 g->not_modifiers = not_modifiers;
24 g->exclusive = exclusive;
25 g->keyname = strdup(keyname);
26 if (obj->layer->evas->walking_grabs)
30 if (!evas_mem_free(strlen(keyname) + 1))
35 g->keyname = strdup(keyname);
42 g->object->grabs = eina_list_append(g->object->grabs, g);
46 evas_mem_free(sizeof(Eina_List));
47 g->object->grabs = eina_list_append(g->object->grabs, g);
56 obj->layer->evas->grabs = eina_list_append(obj->layer->evas->grabs, g);
60 evas_mem_free(sizeof(Eina_List));
61 obj->layer->evas->grabs = eina_list_append(obj->layer->evas->grabs, g);
65 g->object->grabs = eina_list_remove(g->object->grabs, g);
74 static Evas_Key_Grab *
75 evas_key_grab_find(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive)
81 EINA_LIST_FOREACH(obj->layer->evas->grabs, l, g)
83 if ((g->modifiers == modifiers) &&
84 (g->not_modifiers == not_modifiers) &&
85 (!strcmp(g->keyname, keyname)))
87 if ((exclusive) || (obj == g->object)) return g;
96 evas_object_grabs_cleanup(Evas_Object *obj)
98 if (obj->layer->evas->walking_grabs)
103 EINA_LIST_FOREACH(obj->grabs, l, g)
112 g = obj->grabs->data;
113 if (g->keyname) free(g->keyname);
115 obj->layer->evas->grabs = eina_list_remove(obj->layer->evas->grabs, g);
116 obj->grabs = eina_list_remove(obj->grabs, g);
122 evas_key_grab_free(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
127 g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, 0);
129 g->object->grabs = eina_list_remove(g->object->grabs, g);
130 obj->layer->evas->grabs = eina_list_remove(obj->layer->evas->grabs, g);
131 if (g->keyname) free(g->keyname);
138 * Requests @p keyname key events be directed to @p obj.
140 * Key grabs allow an object to receive key events for specific key
141 * strokes even if another object has focus. If the grab is
142 * non-exclusive then all objects that have grabs on the key will get
143 * the event, however if the grab is exclusive, no other object can
144 * get a grab on the key and only that object will get the event.
146 * @p keyname is a platform dependent symbolic name for the key
147 * pressed. It is sometimes possible to convert the string to an
148 * ASCII value of the key, but not always for example the enter key
149 * may be returned as the string 'Enter'.
151 * Typical platforms are Linux frame buffer (Ecore_FB) and X server
152 * (Ecore_X) when using Evas with Ecore and Ecore_Evas.
154 * For a list of keynames for the Linux frame buffer, please refer to
155 * the Ecore_FB documentation.
157 * @p modifiers and @p not_modifiers are bit masks of all the
158 * modifiers that are required and not required respectively for the
159 * new grab. Modifiers can be things such as shift and ctrl as well
160 * as user defigned types via evas_key_modifier_add.
162 * @see evas_object_key_ungrab
163 * @see evas_object_focus_set
164 * @see evas_object_focus_get
165 * @see evas_focus_get
166 * @see evas_key_modifier_add
168 * @param obj the object to direct @p keyname events to.
169 * @param keyname the key to request events for.
170 * @param modifiers a mask of modifiers that should be present to
172 * @param not_modifiers a mask of modifiers that should not be present
173 * to trigger the event.
174 * @param exclusive request that the @p obj is the only object
175 * receiving the @p keyname events.
176 * @return Boolean indicating whether the grab succeeded
179 evas_object_key_grab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive)
184 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
187 if (!keyname) return 0;
190 g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, exclusive);
193 g = evas_key_grab_new(obj, keyname, modifiers, not_modifiers, exclusive);
199 * Request that the grab on @p obj be removed.
201 * Removes the grab on @p obj if @p keyname, @p modifiers, and @p not_modifiers
204 * @see evas_object_key_grab
205 * @see evas_object_focus_set
206 * @see evas_object_focus_get
207 * @see evas_focus_get
209 * @param obj the object that has an existing grab.
210 * @param keyname the key the grab is for.
211 * @param modifiers a mask of modifiers that should be present to
213 * @param not_modifiers a mask of modifiers that should not be present
214 * to trigger the event.
217 evas_object_key_ungrab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
222 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
225 if (!keyname) return;
226 g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers, 0);
228 if (g->object->layer->evas->walking_grabs)
232 g->object->layer->evas->delete_grabs++;
237 evas_key_grab_free(g->object, keyname, modifiers, not_modifiers);