Don't enumerate over keys when find_by_keycode.
This commit is contained in:
@ -68,6 +68,7 @@ struct _EekKeyboardPrivate
|
|||||||
GList *pressed_keys;
|
GList *pressed_keys;
|
||||||
GList *locked_keys;
|
GList *locked_keys;
|
||||||
GArray *outline_array;
|
GArray *outline_array;
|
||||||
|
GHashTable *keycodes;
|
||||||
|
|
||||||
/* modifiers dynamically assigned at run time */
|
/* modifiers dynamically assigned at run time */
|
||||||
EekModifierType num_lock_mask;
|
EekModifierType num_lock_mask;
|
||||||
@ -139,6 +140,27 @@ on_symbol_index_changed (EekSection *section,
|
|||||||
g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
|
g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
section_child_added_cb (EekContainer *container,
|
||||||
|
EekElement *element,
|
||||||
|
EekKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
|
g_hash_table_insert (keyboard->priv->keycodes,
|
||||||
|
GUINT_TO_POINTER(keycode),
|
||||||
|
element);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
section_child_removed_cb (EekContainer *container,
|
||||||
|
EekElement *element,
|
||||||
|
EekKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
|
g_hash_table_remove (keyboard->priv->keycodes,
|
||||||
|
GUINT_TO_POINTER(keycode));
|
||||||
|
}
|
||||||
|
|
||||||
static EekSection *
|
static EekSection *
|
||||||
eek_keyboard_real_create_section (EekKeyboard *self)
|
eek_keyboard_real_create_section (EekKeyboard *self)
|
||||||
{
|
{
|
||||||
@ -147,43 +169,17 @@ eek_keyboard_real_create_section (EekKeyboard *self)
|
|||||||
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
||||||
g_return_val_if_fail (section, NULL);
|
g_return_val_if_fail (section, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT(section), "child-added",
|
||||||
|
G_CALLBACK(section_child_added_cb), self);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT(section), "child-removed",
|
||||||
|
G_CALLBACK(section_child_removed_cb), self);
|
||||||
|
|
||||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
EEK_ELEMENT(section));
|
EEK_ELEMENT(section));
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _FindKeyByKeycodeCallbackData {
|
|
||||||
EekKey *key;
|
|
||||||
guint keycode;
|
|
||||||
};
|
|
||||||
typedef struct _FindKeyByKeycodeCallbackData FindKeyByKeycodeCallbackData;
|
|
||||||
|
|
||||||
static gint
|
|
||||||
find_key_by_keycode_section_callback (EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
FindKeyByKeycodeCallbackData *data = user_data;
|
|
||||||
|
|
||||||
data->key = eek_section_find_key_by_keycode (EEK_SECTION(element),
|
|
||||||
data->keycode);
|
|
||||||
if (data->key)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EekKey *
|
|
||||||
eek_keyboard_real_find_key_by_keycode (EekKeyboard *self,
|
|
||||||
guint keycode)
|
|
||||||
{
|
|
||||||
FindKeyByKeycodeCallbackData data;
|
|
||||||
|
|
||||||
data.keycode = keycode;
|
|
||||||
if (eek_container_find (EEK_CONTAINER(self),
|
|
||||||
find_key_by_keycode_section_callback,
|
|
||||||
&data))
|
|
||||||
return data.key;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_keyboard_set_property (GObject *object,
|
eek_keyboard_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -375,6 +371,8 @@ eek_keyboard_finalize (GObject *object)
|
|||||||
g_list_free_full (priv->locked_keys,
|
g_list_free_full (priv->locked_keys,
|
||||||
(GDestroyNotify) eek_modifier_key_free);
|
(GDestroyNotify) eek_modifier_key_free);
|
||||||
|
|
||||||
|
g_hash_table_destroy (priv->keycodes);
|
||||||
|
|
||||||
for (i = 0; i < priv->outline_array->len; i++) {
|
for (i = 0; i < priv->outline_array->len; i++) {
|
||||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
EekOutline *outline = &g_array_index (priv->outline_array,
|
||||||
EekOutline,
|
EekOutline,
|
||||||
@ -427,7 +425,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
|||||||
sizeof (EekKeyboardPrivate));
|
sizeof (EekKeyboardPrivate));
|
||||||
|
|
||||||
klass->create_section = eek_keyboard_real_create_section;
|
klass->create_section = eek_keyboard_real_create_section;
|
||||||
klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode;
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
klass->key_pressed = eek_keyboard_real_key_pressed;
|
klass->key_pressed = eek_keyboard_real_key_pressed;
|
||||||
@ -578,6 +575,7 @@ eek_keyboard_init (EekKeyboard *self)
|
|||||||
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
||||||
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||||
|
self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,8 +607,8 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
|||||||
guint keycode)
|
guint keycode)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||||
return EEK_KEYBOARD_GET_CLASS(keyboard)->
|
return g_hash_table_lookup (keyboard->priv->keycodes,
|
||||||
find_key_by_keycode (keyboard, keycode);
|
GUINT_TO_POINTER(keycode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -150,9 +150,10 @@ on_cancelled (EekKey *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static EekKey *
|
static EekKey *
|
||||||
eek_section_real_create_key (EekSection *self,
|
eek_section_real_create_key (EekSection *self,
|
||||||
gint column,
|
guint keycode,
|
||||||
gint row)
|
gint column,
|
||||||
|
gint row)
|
||||||
{
|
{
|
||||||
EekKey *key;
|
EekKey *key;
|
||||||
gint num_columns, num_rows;
|
gint num_columns, num_rows;
|
||||||
@ -164,6 +165,7 @@ eek_section_real_create_key (EekSection *self,
|
|||||||
g_return_val_if_fail (column < num_columns, NULL);
|
g_return_val_if_fail (column < num_columns, NULL);
|
||||||
|
|
||||||
key = g_object_new (EEK_TYPE_KEY,
|
key = g_object_new (EEK_TYPE_KEY,
|
||||||
|
"keycode", keycode,
|
||||||
"column", column,
|
"column", column,
|
||||||
"row", row,
|
"row", row,
|
||||||
NULL);
|
NULL);
|
||||||
@ -175,23 +177,6 @@ eek_section_real_create_key (EekSection *self,
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
|
||||||
compare_key_by_keycode (EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
if (eek_key_get_keycode (EEK_KEY(element)) == (guint)(long)user_data)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EekKey *
|
|
||||||
eek_section_real_find_key_by_keycode (EekSection *self,
|
|
||||||
guint keycode)
|
|
||||||
{
|
|
||||||
return (EekKey *)eek_container_find (EEK_CONTAINER(self),
|
|
||||||
compare_key_by_keycode,
|
|
||||||
(gpointer)(long)keycode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_level_from_modifiers (EekSection *self)
|
set_level_from_modifiers (EekSection *self)
|
||||||
{
|
{
|
||||||
@ -340,7 +325,6 @@ eek_section_class_init (EekSectionClass *klass)
|
|||||||
klass->add_row = eek_section_real_add_row;
|
klass->add_row = eek_section_real_add_row;
|
||||||
klass->get_row = eek_section_real_get_row;
|
klass->get_row = eek_section_real_get_row;
|
||||||
klass->create_key = eek_section_real_create_key;
|
klass->create_key = eek_section_real_create_key;
|
||||||
klass->find_key_by_keycode = eek_section_real_find_key_by_keycode;
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
klass->key_pressed = eek_section_real_key_pressed;
|
klass->key_pressed = eek_section_real_key_pressed;
|
||||||
@ -563,6 +547,7 @@ eek_section_get_row (EekSection *section,
|
|||||||
/**
|
/**
|
||||||
* eek_section_create_key:
|
* eek_section_create_key:
|
||||||
* @section: an #EekSection
|
* @section: an #EekSection
|
||||||
|
* @keycode: a keycode
|
||||||
* @column: the column index of the key
|
* @column: the column index of the key
|
||||||
* @row: the row index of the key
|
* @row: the row index of the key
|
||||||
*
|
*
|
||||||
@ -571,27 +556,14 @@ eek_section_get_row (EekSection *section,
|
|||||||
* implementation.
|
* implementation.
|
||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_section_create_key (EekSection *section,
|
eek_section_create_key (EekSection *section,
|
||||||
gint column,
|
guint keycode,
|
||||||
gint row)
|
gint column,
|
||||||
|
gint row)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||||
return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row);
|
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
||||||
}
|
keycode,
|
||||||
|
column,
|
||||||
/**
|
row);
|
||||||
* eek_section_find_key_by_keycode:
|
|
||||||
* @section: an #EekSection
|
|
||||||
* @keycode: a keycode
|
|
||||||
*
|
|
||||||
* Find an #EekKey whose keycode is @keycode.
|
|
||||||
* Returns: an #EekKey or NULL (if not found)
|
|
||||||
*/
|
|
||||||
EekKey *
|
|
||||||
eek_section_find_key_by_keycode (EekSection *section,
|
|
||||||
guint keycode)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
|
||||||
return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section,
|
|
||||||
keycode);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,8 +61,6 @@ struct _EekSection
|
|||||||
* @add_row: virtual function for adding a new row to the section
|
* @add_row: virtual function for adding a new row to the section
|
||||||
* @get_row: virtual function for accessing a row in the section
|
* @get_row: virtual function for accessing a row in the section
|
||||||
* @create_key: virtual function for creating key in the section
|
* @create_key: virtual function for creating key in the section
|
||||||
* @find_key_by_keycode: virtual function for accessing a key in the
|
|
||||||
* section by keycode
|
|
||||||
* @key_pressed: class handler for #EekSection::key-pressed signal
|
* @key_pressed: class handler for #EekSection::key-pressed signal
|
||||||
* @key_released: class handler for #EekSection::key-released signal
|
* @key_released: class handler for #EekSection::key-released signal
|
||||||
* @key_locked: class handler for #EekSection::key-locked signal
|
* @key_locked: class handler for #EekSection::key-locked signal
|
||||||
@ -85,12 +83,10 @@ struct _EekSectionClass
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *(* create_key) (EekSection *self,
|
EekKey *(* create_key) (EekSection *self,
|
||||||
|
guint keycode,
|
||||||
gint row,
|
gint row,
|
||||||
gint column);
|
gint column);
|
||||||
|
|
||||||
EekKey *(* find_key_by_keycode) (EekSection *self,
|
|
||||||
guint keycode);
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (* key_pressed) (EekSection *self,
|
void (* key_pressed) (EekSection *self,
|
||||||
EekKey *key);
|
EekKey *key);
|
||||||
@ -124,6 +120,7 @@ void eek_section_get_row (EekSection *section,
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *eek_section_create_key (EekSection *section,
|
EekKey *eek_section_create_key (EekSection *section,
|
||||||
|
guint keycode,
|
||||||
gint column,
|
gint column,
|
||||||
gint row);
|
gint row);
|
||||||
|
|
||||||
|
|||||||
@ -222,10 +222,9 @@ create_key (EekXkbLayout *layout,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key = eek_section_create_key (section, column, row);
|
key = eek_section_create_key (section, keycode, column, row);
|
||||||
eek_element_set_name (EEK_ELEMENT(key), name);
|
eek_element_set_name (EEK_ELEMENT(key), name);
|
||||||
eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
|
eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
|
||||||
eek_key_set_keycode (key, keycode);
|
|
||||||
eek_key_set_symbol_matrix (key, matrix);
|
eek_key_set_symbol_matrix (key, matrix);
|
||||||
eek_symbol_matrix_free (matrix);
|
eek_symbol_matrix_free (matrix);
|
||||||
eek_key_set_oref (key, oref);
|
eek_key_set_oref (key, oref);
|
||||||
|
|||||||
@ -401,31 +401,8 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "key") == 0) {
|
if (g_strcmp0 (element_name, "key") == 0) {
|
||||||
guint column, row;
|
guint keycode;
|
||||||
|
gint column, row;
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
|
||||||
"column");
|
|
||||||
if (attribute == NULL) {
|
|
||||||
g_set_error (error,
|
|
||||||
G_MARKUP_ERROR,
|
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
|
||||||
"no \"column\" attribute for \"key\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
column = strtoul (attribute, NULL, 10);
|
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
|
||||||
"row");
|
|
||||||
if (attribute == NULL) {
|
|
||||||
g_set_error (error,
|
|
||||||
G_MARKUP_ERROR,
|
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
|
||||||
"no \"row\" attribute for \"row\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
row = strtoul (attribute, NULL, 10);
|
|
||||||
|
|
||||||
data->key = eek_section_create_key (data->section, column, row);
|
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"keycode");
|
"keycode");
|
||||||
@ -436,7 +413,31 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
"no \"keycode\" attribute for \"key\"");
|
"no \"keycode\" attribute for \"key\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eek_key_set_keycode (data->key, strtoul (attribute, NULL, 10));
|
keycode = strtoul (attribute, NULL, 10);
|
||||||
|
|
||||||
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
|
"column");
|
||||||
|
if (attribute == NULL) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
|
"no \"column\" attribute for \"key\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
column = strtol (attribute, NULL, 10);
|
||||||
|
|
||||||
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
|
"row");
|
||||||
|
if (attribute == NULL) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
|
"no \"row\" attribute for \"row\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
row = strtol (attribute, NULL, 10);
|
||||||
|
|
||||||
|
data->key = eek_section_create_key (data->section, keycode, column, row);
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"name");
|
"name");
|
||||||
|
|||||||
@ -30,9 +30,9 @@ test_create (void)
|
|||||||
section = eek_keyboard_create_section (keyboard);
|
section = eek_keyboard_create_section (keyboard);
|
||||||
g_assert (EEK_IS_SECTION(section));
|
g_assert (EEK_IS_SECTION(section));
|
||||||
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
key0 = eek_section_create_key (section, 0, 0);
|
key0 = eek_section_create_key (section, 1, 0, 0);
|
||||||
g_assert (EEK_IS_KEY(key0));
|
g_assert (EEK_IS_KEY(key0));
|
||||||
key1 = eek_section_create_key (section, 1, 0);
|
key1 = eek_section_create_key (section, 2, 1, 0);
|
||||||
g_assert (EEK_IS_KEY(key1));
|
g_assert (EEK_IS_KEY(key1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user