From 23d5f18d4ad36510467f80da313f8a8008d7dc08 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Fri, 2 Aug 2019 17:12:10 +0000 Subject: [PATCH] symbols matrix: Remove in favor of a levels vector --- eek/eek-key.c | 91 +++++-------------------------------- eek/eek-key.h | 12 +++-- eek/eek-keyboard.c | 46 +++---------------- eek/eek-renderer.c | 7 ++- eek/eek-symbol-matrix.c | 99 ----------------------------------------- eek/eek-symbol-matrix.h | 62 -------------------------- eek/eek-xml-layout.c | 43 ++++-------------- src/meson.build | 1 - src/symbol.h | 8 ++++ src/symbol.rs | 79 ++++++++++++++++++++++++++++++++ 10 files changed, 124 insertions(+), 324 deletions(-) delete mode 100644 eek/eek-symbol-matrix.c delete mode 100644 eek/eek-symbol-matrix.h diff --git a/eek/eek-key.c b/eek/eek-key.c index 744a8757..ea52e462 100644 --- a/eek/eek-key.c +++ b/eek/eek-key.c @@ -37,7 +37,6 @@ enum { PROP_0, PROP_KEYCODE, - PROP_SYMBOL_MATRIX, PROP_OREF, PROP_LAST }; @@ -53,7 +52,7 @@ static guint signals[LAST_SIGNAL] = { 0, }; typedef struct _EekKeyPrivate { guint keycode; - EekSymbolMatrix *symbol_matrix; + struct squeek_symbols *symbols; gulong oref; // UI outline reference gboolean is_pressed; gboolean is_locked; @@ -89,7 +88,7 @@ eek_key_finalize (GObject *object) EekKey *self = EEK_KEY (object); EekKeyPrivate *priv = eek_key_get_instance_private (self); - eek_symbol_matrix_free (priv->symbol_matrix); + squeek_symbols_free (priv->symbols); G_OBJECT_CLASS (eek_key_parent_class)->finalize (object); } @@ -100,15 +99,10 @@ eek_key_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EekSymbolMatrix *matrix; switch (prop_id) { case PROP_KEYCODE: eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value)); break; - case PROP_SYMBOL_MATRIX: - matrix = g_value_get_boxed (value); - eek_key_set_symbol_matrix (EEK_KEY(object), matrix); - break; case PROP_OREF: eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value)); break; @@ -128,10 +122,6 @@ eek_key_get_property (GObject *object, case PROP_KEYCODE: g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object))); break; - case PROP_SYMBOL_MATRIX: - g_value_set_boxed (value, - eek_key_get_symbol_matrix (EEK_KEY(object))); - break; case PROP_OREF: g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object))); break; @@ -167,18 +157,6 @@ eek_key_class_init (EekKeyClass *klass) G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec); - /** - * EekKey:symbol-matrix: - * - * The symbol matrix of #EekKey. - */ - pspec = g_param_spec_boxed ("symbol-matrix", - "Symbol matrix", - "Symbol matrix of the key", - EEK_TYPE_SYMBOL_MATRIX, - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec); - /** * EekKey:oref: * @@ -232,7 +210,7 @@ static void eek_key_init (EekKey *self) { EekKeyPrivate *priv = eek_key_get_instance_private (self); - priv->symbol_matrix = eek_symbol_matrix_new (0, 0); + priv->symbols = squeek_symbols_new (); } /** @@ -274,25 +252,6 @@ eek_key_get_keycode (EekKey *key) return priv->keycode; } -/** - * eek_key_set_symbol_matrix: - * @key: an #EekKey - * @matrix: an #EekSymbolMatrix - * - * Set the symbol matrix of @key to @matrix. - */ -void -eek_key_set_symbol_matrix (EekKey *key, - EekSymbolMatrix *matrix) -{ - g_return_if_fail (EEK_IS_KEY(key)); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - eek_symbol_matrix_free (priv->symbol_matrix); - priv->symbol_matrix = eek_symbol_matrix_copy (matrix); -} - /** * eek_key_get_symbol_matrix: * @key: an #EekKey @@ -300,14 +259,14 @@ eek_key_set_symbol_matrix (EekKey *key, * Get the symbol matrix of @key. * Returns: (transfer none): #EekSymbolMatrix or %NULL */ -EekSymbolMatrix * +struct squeek_symbols * eek_key_get_symbol_matrix (EekKey *key) { g_return_val_if_fail (EEK_IS_KEY(key), NULL); EekKeyPrivate *priv = eek_key_get_instance_private (key); - return priv->symbol_matrix; + return priv->symbols; } /** @@ -388,46 +347,18 @@ eek_key_get_symbol_with_fallback (EekKey *key, * Get the symbol at (@group, @level) in the symbol matrix of @key. * Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL */ -EekSymbol * +struct squeek_symbol* eek_key_get_symbol_at_index (EekKey *key, gint group, gint level, - gint fallback_group, - gint fallback_level) + guint fallback_group, + guint fallback_level) { - EekKeyPrivate *priv = eek_key_get_instance_private (key); - gint num_symbols; - - g_return_val_if_fail (fallback_group >= 0, NULL); - g_return_val_if_fail (fallback_level >= 0, NULL); - - if (group < 0) - group = fallback_group; - if (level < 0) - level = fallback_level; - - if (!priv->symbol_matrix) - return NULL; - - num_symbols = priv->symbol_matrix->num_groups * - priv->symbol_matrix->num_levels; - if (num_symbols == 0) - return NULL; - - if (group >= priv->symbol_matrix->num_groups) { - if (fallback_group < 0) - return NULL; - group = fallback_group; - } - - if (level >= priv->symbol_matrix->num_levels) { - if (fallback_level < 0) - return NULL; + struct squeek_symbols *symbols = eek_key_get_symbol_matrix(key); + if (level < 0) { level = fallback_level; } - - return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels + - level]; + return squeek_symbols_get(symbols, level); } /** diff --git a/eek/eek-key.h b/eek/eek-key.h index bcd8e4b4..91398e8e 100644 --- a/eek/eek-key.h +++ b/eek/eek-key.h @@ -26,7 +26,6 @@ #define EEK_KEY_H 1 #include "eek-element.h" -#include "eek-symbol-matrix.h" G_BEGIN_DECLS @@ -59,19 +58,18 @@ GType eek_key_get_type (void) G_GNUC_CONST; void eek_key_set_keycode (EekKey *key, guint keycode); guint eek_key_get_keycode (EekKey *key); -void eek_key_set_symbol_matrix (EekKey *key, - EekSymbolMatrix *matrix); -EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key); +struct squeek_symbols * +eek_key_get_symbol_matrix (EekKey *key); EekSymbol *eek_key_get_symbol (EekKey *key); EekSymbol *eek_key_get_symbol_with_fallback (EekKey *key, gint fallback_group, gint fallback_level); -EekSymbol *eek_key_get_symbol_at_index (EekKey *key, +struct squeek_symbol *eek_key_get_symbol_at_index (EekKey *key, gint group, gint level, - gint fallback_group, - gint fallback_level); + guint fallback_group, + guint fallback_level); void eek_key_set_oref (EekKey *key, guint oref); diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index b610ce10..7e3c763b 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -770,47 +770,13 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard) g_free(line); g_free(current); - /* Find the symbols associated with the key. */ - EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key); - EekSymbol *syms[4]; - int i, j; - - /* Get the symbols for all the levels defined for the key, then - pad it out with the first symbol for all levels up to the fourth. */ - for (i = 0; i < matrix->num_levels; ++i) - syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i); - - while (i < 4) { - syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0); - i++; - } - - /* The four levels are split into two groups in the keymap. - Generate strings for each of these groups, where an empty group is - treated specially. */ - - gchar *groups[2]; - for (i = 0, j = 0; i < 2; ++i, j += 2) { - if (syms[j] && syms[j + 1]) { - char *tleft = squeek_symbol_get_name(syms[j]); - char *tright = squeek_symbol_get_name(syms[j + 1]); - groups[i] = g_strjoin(", ", tleft, - tright, - NULL); - } else - groups[i] = ""; - } - - /* Append a key definition to the symbols section. */ + // FIXME: free + char *key_str = squeek_key_to_keymap_entry( + (char*)key_name, + eek_key_get_symbol_matrix(key) + ); current = symbols; - line = g_strdup_printf(" key <%s> { [ %s ], [ %s ] };\n", - (char *)key_name, groups[0], groups[1]); - - g_free(groups[0]); - g_free(groups[1]); - - symbols = g_strconcat(current, line, NULL); - g_free(line); + symbols = g_strconcat(current, key_str, NULL); g_free(current); } diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 6c8cf39e..671db408 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -277,7 +277,12 @@ render_key (EekRenderer *self, eek_renderer_get_foreground_color (self, priv->key_context, &foreground); /* render icon (if any) */ - symbol = eek_key_get_symbol_with_fallback (key, 0, 0); + + EekSection *section = EEK_SECTION(eek_element_get_parent(EEK_ELEMENT(key))); + gint group = eek_element_get_group(EEK_ELEMENT(section)); + gint level = eek_element_get_level(EEK_ELEMENT(section)); + + symbol = eek_key_get_symbol_at_index (key, group, level, 0, 0); if (!symbol) return; diff --git a/eek/eek-symbol-matrix.c b/eek/eek-symbol-matrix.c deleted file mode 100644 index cdfa24fb..00000000 --- a/eek/eek-symbol-matrix.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2011 Daiki Ueno - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include "eek-symbol-matrix.h" - -EekSymbolMatrix * -eek_symbol_matrix_new (gint num_groups, - gint num_levels) -{ - EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix); - - matrix->num_groups = num_groups; - matrix->num_levels = num_levels; - matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) * - num_groups * num_levels); - return matrix; -} - -EekSymbolMatrix * -eek_symbol_matrix_copy (const EekSymbolMatrix *matrix) -{ - EekSymbolMatrix *retval; - guint num_symbols = matrix->num_groups * matrix->num_levels; - - retval = g_slice_dup (EekSymbolMatrix, matrix); - retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols, - matrix->data); - // FIXME: do a deep copy over the data in EekSymbol - return retval; -} - -void -eek_symbol_matrix_free (EekSymbolMatrix *matrix) -{ - guint num_symbols = matrix->num_groups * matrix->num_levels; - g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data); - g_slice_free (EekSymbolMatrix, matrix); -} - -GType -eek_symbol_matrix_get_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = - g_boxed_type_register_static ("EekSymbolMatrix", - (GBoxedCopyFunc)eek_symbol_matrix_copy, - (GBoxedFreeFunc)eek_symbol_matrix_free); - return our_type; -} - -void -eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix, - gint group, - gint level, - EekSymbol *symbol) -{ - g_return_if_fail (group >= 0 && group < matrix->num_groups); - g_return_if_fail (level >= 0 && level < matrix->num_levels); - matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol); -} - -/** - * eek_symbol_matrix_get_symbol: - * @matrix: an #EekSymbolMatrix - * @group: group index of @matrix - * @level: level index of @matrix - * - * Get an #EekSymbol stored in the cell selected by (@group, @level) - * in @matrix. - * - * Return value: (transfer none): an #EekSymbol. - */ -EekSymbol * -eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix, - gint group, - gint level) -{ - g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL); - g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL); - return matrix->data[group * matrix->num_levels + level]; -} diff --git a/eek/eek-symbol-matrix.h b/eek/eek-symbol-matrix.h deleted file mode 100644 index c1ac431a..00000000 --- a/eek/eek-symbol-matrix.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 Daiki Ueno - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef EEK_SYMBOL_MATRIX_H -#define EEK_SYMBOL_MATRIX_H 1 - -#include "eek-symbol.h" - -G_BEGIN_DECLS - -/** - * EekSymbolMatrix: - * @data: array of symbols - * @num_groups: the number of groups (rows) - * @num_levels: the number of levels (columns) - * - * Symbol matrix of a key. - */ -struct _EekSymbolMatrix -{ - /*< public >*/ - gint num_groups; - gint num_levels; - EekSymbol **data; -}; - -#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ()) -GType eek_symbol_matrix_get_type (void) G_GNUC_CONST; -EekSymbolMatrix *eek_symbol_matrix_new (gint num_groups, - gint num_levels); -EekSymbolMatrix *eek_symbol_matrix_copy (const EekSymbolMatrix *matrix); -void eek_symbol_matrix_free (EekSymbolMatrix *matrix); - -void eek_symbol_matrix_set_symbol - (EekSymbolMatrix *matrix, - gint group, - gint level, - EekSymbol *symbol); -EekSymbol *eek_symbol_matrix_get_symbol - (EekSymbolMatrix *matrix, - gint group, - gint level); - -G_END_DECLS - -#endif /* EEK_SYMBOL_MATRIX_H */ diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index 3b308236..a4439ec2 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -602,7 +602,6 @@ struct _SymbolsParseData { EekKeyboard *keyboard; EekKey *key; - GSList *symbols; gchar *label; gchar *icon; gchar *tooltip; @@ -684,7 +683,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext, data->groups = strtol (attribute, NULL, 10); else data->groups = 1; - data->symbols = NULL; goto out; } @@ -744,27 +742,6 @@ symbols_end_element_callback (GMarkupParseContext *pcontext, text = g_strndup (data->text->str, data->text->len); if (g_strcmp0 (element_name, "key") == 0) { - if (!data->key) { - return; - } - - gint num_symbols = g_slist_length (data->symbols); - gint levels = num_symbols / data->groups; - EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups, - levels); - head = data->symbols = g_slist_reverse (data->symbols); - for (i = 0; i < num_symbols; i++) { - if (head && head->data) { - matrix->data[i] = head->data; - head = g_slist_next (head); - } else - matrix->data[i] = NULL; - } - g_slist_free (data->symbols); - data->symbols = NULL; - - eek_key_set_symbol_matrix (data->key, matrix); - eek_symbol_matrix_free (matrix); data->key = NULL; goto out; } @@ -773,17 +750,16 @@ symbols_end_element_callback (GMarkupParseContext *pcontext, g_strcmp0 (element_name, "keysym") == 0 || g_strcmp0 (element_name, "text") == 0) { - data->symbols = g_slist_prepend ( - data->symbols, - squeek_symbol_new( - element_name, - text, - data->keyval, - data->label, - data->icon, - data->tooltip - ) + struct squeek_symbol *symbol = squeek_symbol_new( + element_name, + text, + data->keyval, + data->label, + data->icon, + data->tooltip ); + + squeek_symbols_append(eek_key_get_symbol_matrix(data->key), symbol); data->keyval = 0; g_free(data->label); data->label = NULL; @@ -795,7 +771,6 @@ symbols_end_element_callback (GMarkupParseContext *pcontext, } if (g_strcmp0 (element_name, "invalid") == 0) { - data->symbols = g_slist_prepend (data->symbols, NULL); goto out; } diff --git a/src/meson.build b/src/meson.build index fde961f9..09e96754 100644 --- a/src/meson.build +++ b/src/meson.build @@ -28,7 +28,6 @@ sources = [ '../eek/eek-section.c', '../eek/eek-serializable.c', '../eek/eek-symbol.c', - '../eek/eek-symbol-matrix.c', '../eek/eek-text.c', '../eek/eek-types.c', '../eek/eek-xml-layout.c', diff --git a/src/symbol.h b/src/symbol.h index 5f402df5..9cdbcb32 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -6,6 +6,7 @@ // Defined in Rust struct squeek_symbol; +struct squeek_symbols; struct squeek_symbol* squeek_symbol_new(const char *element_name, const char *text, uint32_t keyval, @@ -19,4 +20,11 @@ const char *squeek_symbol_get_icon_name(struct squeek_symbol* symbol); uint32_t squeek_symbol_get_modifier_mask(struct squeek_symbol* symbol); void squeek_symbol_print(struct squeek_symbol* symbol); + +struct squeek_symbols* squeek_symbols_new(); +void squeek_symbols_free(struct squeek_symbols*); +void squeek_symbols_append(struct squeek_symbols*, struct squeek_symbol *item); +struct squeek_symbol *squeek_symbols_get(struct squeek_symbols*, uint32_t level); + +const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_symbols *symbols); #endif diff --git a/src/symbol.rs b/src/symbol.rs index abca1997..6b73d120 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -209,6 +209,85 @@ pub mod c { let symbol = unsafe { &*symbol }; println!("{:?}", symbol); } + + #[no_mangle] + pub extern "C" + fn squeek_symbols_new() -> *const Vec<*const Symbol> { + Box::into_raw(Box::new(Vec::new())) + } + + #[no_mangle] + pub extern "C" + fn squeek_symbols_append(v: *mut Vec<*const Symbol>, symbol: *const Symbol) { + let v = unsafe { &mut *v }; + v.push(symbol); + } + + #[no_mangle] + pub extern "C" + fn squeek_symbols_get(v: *mut Vec<*const Symbol>, index: u32) -> *const Symbol { + let v = unsafe { &mut *v }; + let index = index as usize; + v[ + if index < v.len() { index } else { 0 } + ] + } + + #[no_mangle] + pub extern "C" + fn squeek_symbols_free(symbols: *mut Vec<*const Symbol>) { + unsafe { Box::from_raw(symbols) }; // Will just get dropped, together with the contents + } + + #[no_mangle] + pub extern "C" + fn squeek_key_to_keymap_entry( + key_name: *const c_char, + symbols: *const Vec<*const Symbol>, + ) -> *const c_char { + let key_name = as_cstr(&key_name) + .expect("Missing key name") + .to_str() + .expect("Bad key name"); + let symbols = unsafe { &*symbols }; + let symbol_names = symbols.iter() + .map(|symbol| { + let symbol: &Symbol = unsafe { &**symbol }; + match &symbol.action { + Action::Submit { text: Some(text), .. } => { + Some( + text.clone() + .into_string().expect("Bad symbol") + ) + }, + _ => None + } + }) + .collect::>(); + + let inner = match symbol_names.len() { + 1 => match &symbol_names[0] { + Some(name) => format!("[ {} ]", name), + _ => format!("[ ]"), + }, + 4 => { + let first = match (&symbol_names[0], &symbol_names[1]) { + (Some(left), Some(right)) => format!("{}, {}", left, right), + _ => format!(""), + }; + let second = match (&symbol_names[2], &symbol_names[3]) { + (Some(left), Some(right)) => format!("{}, {}", left, right), + _ => format!(""), + }; + format!("[ {} ], [ {} ]", first, second) + }, + _ => panic!("Unsupported number of symbols"), + }; + + CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner)) + .expect("Couldn't convert string") + .into_raw() + } } /// Just defines some int->identifier mappings for convenience