Don't enumerate over keys when find_by_keycode.
This commit is contained in:
		@ -68,6 +68,7 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
    GHashTable *keycodes;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 *
 | 
			
		||||
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);
 | 
			
		||||
    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_ELEMENT(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
 | 
			
		||||
eek_keyboard_set_property (GObject      *object,
 | 
			
		||||
                           guint         prop_id,
 | 
			
		||||
@ -375,6 +371,8 @@ eek_keyboard_finalize (GObject *object)
 | 
			
		||||
    g_list_free_full (priv->locked_keys,
 | 
			
		||||
                      (GDestroyNotify) eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_destroy (priv->keycodes);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
                                              EekOutline,
 | 
			
		||||
@ -427,7 +425,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
                              sizeof (EekKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_section = eek_keyboard_real_create_section;
 | 
			
		||||
    klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    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->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -609,8 +607,8 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
			
		||||
                                  guint        keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return EEK_KEYBOARD_GET_CLASS(keyboard)->
 | 
			
		||||
        find_key_by_keycode (keyboard, keycode);
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->keycodes,
 | 
			
		||||
                                GUINT_TO_POINTER(keycode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -150,9 +150,10 @@ on_cancelled (EekKey     *key,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKey *
 | 
			
		||||
eek_section_real_create_key (EekSection  *self,
 | 
			
		||||
                             gint column,
 | 
			
		||||
                             gint row)
 | 
			
		||||
eek_section_real_create_key (EekSection *self,
 | 
			
		||||
                             guint       keycode,
 | 
			
		||||
                             gint        column,
 | 
			
		||||
                             gint        row)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    key = g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                        "keycode", keycode,
 | 
			
		||||
                        "column", column,
 | 
			
		||||
                        "row", row,
 | 
			
		||||
                        NULL);
 | 
			
		||||
@ -175,23 +177,6 @@ eek_section_real_create_key (EekSection  *self,
 | 
			
		||||
    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
 | 
			
		||||
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->get_row = eek_section_real_get_row;
 | 
			
		||||
    klass->create_key = eek_section_real_create_key;
 | 
			
		||||
    klass->find_key_by_keycode = eek_section_real_find_key_by_keycode;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->key_pressed = eek_section_real_key_pressed;
 | 
			
		||||
@ -563,6 +547,7 @@ eek_section_get_row (EekSection     *section,
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_create_key:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 * @column: the column index of the key
 | 
			
		||||
 * @row: the row index of the key
 | 
			
		||||
 *
 | 
			
		||||
@ -571,27 +556,14 @@ eek_section_get_row (EekSection     *section,
 | 
			
		||||
 * implementation.
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_section_create_key (EekSection  *section,
 | 
			
		||||
                        gint         column,
 | 
			
		||||
                        gint         row)
 | 
			
		||||
eek_section_create_key (EekSection *section,
 | 
			
		||||
                        guint       keycode,
 | 
			
		||||
                        gint        column,
 | 
			
		||||
                        gint        row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section, 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);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
			
		||||
                                                       keycode,
 | 
			
		||||
                                                       column,
 | 
			
		||||
                                                       row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -61,8 +61,6 @@ struct _EekSection
 | 
			
		||||
 * @add_row: virtual function for adding a new row to the section
 | 
			
		||||
 * @get_row: virtual function for accessing a row 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_released: class handler for #EekSection::key-released signal
 | 
			
		||||
 * @key_locked: class handler for #EekSection::key-locked signal
 | 
			
		||||
@ -85,12 +83,10 @@ struct _EekSectionClass
 | 
			
		||||
                                     EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
    EekKey *(* create_key)          (EekSection     *self,
 | 
			
		||||
                                     guint           keycode,
 | 
			
		||||
                                     gint            row,
 | 
			
		||||
                                     gint            column);
 | 
			
		||||
 | 
			
		||||
    EekKey *(* find_key_by_keycode) (EekSection     *self,
 | 
			
		||||
                                     guint           keycode);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void    (* key_pressed)         (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
@ -124,6 +120,7 @@ void    eek_section_get_row              (EekSection     *section,
 | 
			
		||||
                                          EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_create_key           (EekSection     *section,
 | 
			
		||||
                                          guint           keycode,
 | 
			
		||||
                                          gint            column,
 | 
			
		||||
                                          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_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    eek_key_set_keycode (key, keycode);
 | 
			
		||||
    eek_key_set_symbol_matrix (key, matrix);
 | 
			
		||||
    eek_symbol_matrix_free (matrix);
 | 
			
		||||
    eek_key_set_oref (key, oref);
 | 
			
		||||
 | 
			
		||||
@ -401,31 +401,8 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "key") == 0) {
 | 
			
		||||
        guint 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);
 | 
			
		||||
        guint keycode;
 | 
			
		||||
        gint column, row;
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "keycode");
 | 
			
		||||
@ -436,7 +413,31 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
                         "no \"keycode\" attribute for \"key\"");
 | 
			
		||||
            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,
 | 
			
		||||
                                   "name");
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user