key grabs are done... ok not as efficiently as i'd liek so having more than

a dozen key grabs at any time may impact key event handling a little...

oh yeah.. added to the api .. now theres a modifier mask and a not_mask. the
not mas means "grab the key only if NONE of these modifiers are active and
only if one or more of the mask modifiers are active). using this you can
easily select allmodifiers, none, or a certain set of modifiers. if you need
more than that put in multiple grabs then :) to just have that exact set of
modifiers grabbed have not_mask be the inverse of mask. :)


SVN revision: 6546
This commit is contained in:
Carsten Haitzler 2003-01-05 12:55:37 +00:00
parent 093d224dd0
commit 8451b5cc08
7 changed files with 223 additions and 26 deletions

View File

@ -437,8 +437,8 @@ extern "C" {
Evas_Modifier_Mask evas_key_modifier_mask_get (Evas *e, char *keyname);
int evas_object_key_grab (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, int exclusive);
void evas_object_key_ungrab (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers);
int evas_object_key_grab (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
void evas_object_key_ungrab (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
void evas_object_pass_events_set (Evas_Object *obj, int pass);
int evas_object_pass_events_get (Evas_Object *obj);

View File

@ -21,6 +21,7 @@ evas_data.c \
evas_events.c \
evas_focus.c \
evas_key.c \
evas_key_grab.c \
evas_layer.c \
evas_main.c \
evas_name.c \

View File

@ -418,8 +418,6 @@ evas_event_feed_key_down_data(Evas *e, char *keyname, void *data)
MAGIC_CHECK_END();
if (!keyname) return;
if (e->events_frozen > 0) return;
/* FIXME: handle grabs */
if (e->focused)
{
Evas_Event_Key_Down ev;
@ -427,8 +425,27 @@ evas_event_feed_key_down_data(Evas *e, char *keyname, void *data)
ev.data = data;
ev.modifiers = &(e->modifiers);
ev.locks = &(e->locks);
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
}
if (e->grabs)
{
Evas_List *l;
for (l = e->grabs; l; l= l->next)
{
Evas_Key_Grab *g;
g = l->data;
if ((e->modifiers.mask & g->modifiers) &&
(!(e->modifiers.mask & g->not_modifiers)) &&
(!strcmp(keyname, g->keyname)))
{
evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_DOWN, &ev);
if (g->exclusive) return;
}
}
}
if (e->focused)
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
}
}
void
@ -439,9 +456,6 @@ evas_event_feed_key_up_data(Evas *e, char *keyname, void *data)
MAGIC_CHECK_END();
if (!keyname) return;
if (e->events_frozen > 0) return;
if (!e->focused) return;
/* FIXME: handle grabs */
if (e->focused)
{
Evas_Event_Key_Up ev;
@ -449,8 +463,27 @@ evas_event_feed_key_up_data(Evas *e, char *keyname, void *data)
ev.data = data;
ev.modifiers = &(e->modifiers);
ev.locks = &(e->locks);
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
}
if (e->grabs)
{
Evas_List *l;
for (l = e->grabs; l; l= l->next)
{
Evas_Key_Grab *g;
g = l->data;
if ((e->modifiers.mask & g->modifiers) &&
(!(e->modifiers.mask & g->not_modifiers)) &&
(!strcmp(keyname, g->keyname)))
{
evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_UP, &ev);
if (g->exclusive) return;
}
}
}
if (e->focused)
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
}
}
void

View File

@ -233,13 +233,3 @@ evas_key_modifier_mask_get(Evas *e, char *keyname)
if (num < 0) return 0;
return 1 << num;
}
int
evas_object_key_grab(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, int exclusive)
{
}
void
evas_object_key_ungrab(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers)
{
}

View File

@ -0,0 +1,158 @@
#include "evas_common.h"
#include "evas_private.h"
#include "Evas.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 */
static Evas_Key_Grab *evas_key_grab_new (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive);
static void evas_key_grab_free (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
static Evas_Key_Grab *evas_key_grab_find (Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
static Evas_Key_Grab *
evas_key_grab_new(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive)
{
/* MEM OK */
Evas_Key_Grab *g;
g = evas_mem_calloc(sizeof(Evas_Key_Grab));
if (!g) return;
g->keyname = strdup(keyname);
if (!g->keyname)
{
if (!evas_mem_free(strlen(keyname) + 1))
{
free(g);
return NULL;
}
g->keyname = strdup(keyname);
if (!g->keyname)
{
free(g);
return NULL;
}
}
g->object->grabs = evas_list_append(g->object->grabs, g);
if (evas_list_alloc_error())
{
MERR_BAD();
evas_mem_free(sizeof(Evas_List));
g->object->grabs = evas_list_append(g->object->grabs, g);
if (evas_list_alloc_error())
{
MERR_FATAL();
free(g);
free(g->keyname);
return NULL;
}
}
obj->layer->evas->grabs = evas_list_append(obj->layer->evas->grabs, g);
if (evas_list_alloc_error())
{
MERR_BAD();
evas_mem_free(sizeof(Evas_List));
obj->layer->evas->grabs = evas_list_append(obj->layer->evas->grabs, g);
if (evas_list_alloc_error())
{
MERR_FATAL();
g->object->grabs = evas_list_remove(g->object->grabs, g);
free(g);
free(g->keyname);
return NULL;
}
}
g->object = obj;
g->modifiers = modifiers;
g->not_modifiers = not_modifiers;
g->exclusive = exclusive;
return g;
}
static void
evas_key_grab_free(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
{
/* MEM OK */
Evas_Key_Grab *g;
g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers);
if (!g) return;
g->object->grabs = evas_list_remove(g->object->grabs, g);
if (g->keyname) free(g->keyname);
free(g);
}
static Evas_Key_Grab *
evas_key_grab_find(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
{
/* MEM OK */
Evas_List *l;
for (l = obj->layer->evas->grabs; l; l = l->next)
{
Evas_Key_Grab *g;
g = l->data;
if ((g->modifiers == modifiers) &&
(g->not_modifiers == not_modifiers) &&
(!strcmp(g->keyname, keyname)))
{
if ((!obj) || (obj == g->object)) return g;
}
}
return NULL;
}
/* local calls */
void
evas_object_grabs_cleanup(Evas_Object *obj)
{
while (obj->grabs)
{
Evas_Key_Grab *g;
g = obj->grabs->data;
if (g->keyname) free(g->keyname);
free(g);
obj->layer->evas->grabs = evas_list_remove(obj->layer->evas->grabs, g);
obj->grabs = evas_list_remove(obj->grabs, g);
}
}
/* public calls */
int
evas_object_key_grab(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, int exclusive)
{
/* MEM OK */
Evas_Key_Grab *g;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return 0;
MAGIC_CHECK_END();
if (exclusive)
{
g = evas_key_grab_find(NULL, keyname, modifiers, not_modifiers);
if (g) return 0;
}
g = evas_key_grab_new(obj, keyname, modifiers, not_modifiers, exclusive);
if (!g) return 0;
return 1;
}
void
evas_object_key_ungrab(Evas_Object *obj, char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers)
{
/* MEM OK */
Evas_Key_Grab *g;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers);
if (!g) return;
evas_key_grab_free(g->object, keyname, modifiers, not_modifiers);
}

View File

@ -20,6 +20,7 @@ void
evas_object_free(Evas_Object *obj, int clean_layer)
{
evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL);
evas_object_grabs_cleanup(obj);
evas_object_intercept_cleanup(obj);
evas_object_smart_cleanup(obj);
obj->func->free(obj);
@ -414,6 +415,7 @@ evas_object_del(Evas_Object *obj)
obj->layer->evas->focused = NULL;
evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL);
}
evas_object_grabs_cleanup(obj);
evas_object_hide(obj);
while (obj->clip.clipees) evas_object_clip_unset(obj->clip.clipees->data);
if (obj->cur.clipper) evas_object_clip_unset(obj);

View File

@ -46,13 +46,14 @@ typedef struct _Evas_Modifier Evas_Modifier;
typedef struct _Evas_Lock Evas_Lock;
typedef unsigned long long Evas_Modifier_Mask;
typedef struct _Evas_Smart Evas_Smart;
typedef struct _Evas_Intercept_Func Evas_Intercept_Func;
typedef void Evas_Performance;
typedef struct _Evas_Intercept_Func Evas_Intercept_Func;
typedef struct _Evas_Intercept_Func_Basic Evas_Intercept_Func_Basic;
typedef struct _Evas_Intercept_Func_SizePos Evas_Intercept_Func_SizePos;
typedef struct _Evas_Intercept_Func_Obj Evas_Intercept_Func_Obj;
typedef struct _Evas_Intercept_Func_Int Evas_Intercept_Func_Int;
typedef void Evas_Performance;
typedef struct _Evas_Key_Grab Evas_Key_Grab;
#define MAGIC_EVAS 0x70777770
#define MAGIC_OBJ 0x71777770
#define MAGIC_OBJ_RECTANGLE 0x71777771
@ -92,8 +93,6 @@ if (_r) \
#define MERR_FATAL() _evas_alloc_error = EVAS_ALLOC_ERROR_FATAL
#define MERR_BAD() _evas_alloc_error = EVAS_ALLOC_ERROR_RECOVERED
#define MEM_TRY_CALLOC(_ptr, _size)
struct _Evas_Rectangle
{
int x, y, w, h;
@ -123,6 +122,15 @@ struct _Evas_Intercept_Func_Int
void *data;
};
struct _Evas_Key_Grab
{
char *keyname;
Evas_Modifier_Mask modifiers;
Evas_Modifier_Mask not_modifiers;
Evas_Object *object;
int exclusive : 1;
};
struct _Evas_Intercept_Func
{
Evas_Intercept_Func_Basic show;
@ -236,6 +244,8 @@ struct _Evas
int info_magic;
} engine;
Evas_List *grabs;
Evas_List *font_path;
Evas_Object *focused;
@ -315,6 +325,8 @@ struct _Evas_Object
Evas_List *elements;
} data;
Evas_List *grabs;
struct {
Evas_Object_List *in;
Evas_Object_List *out;
@ -537,6 +549,7 @@ int evas_object_intercept_call_lower(Evas_Object *obj);
int evas_object_intercept_call_stack_above(Evas_Object *obj, Evas_Object *above);
int evas_object_intercept_call_stack_below(Evas_Object *obj, Evas_Object *below);
int evas_object_intercept_call_layer_set(Evas_Object *obj, int l);
void evas_object_grabs_cleanup(Evas_Object *obj);
extern int _evas_alloc_error;