Commit 23d5f18d authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

symbols matrix: Remove in favor of a levels vector

parent c8adb45a
......@@ -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);
}
/**
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
......
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* 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];
}
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* 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 */
......@@ -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;
}
......
......@@ -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',
......
......@@ -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
......@@ -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::<Vec<_>>();
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()