diff --git a/eek/eek-container.c b/eek/eek-container.c deleted file mode 100644 index 0d8c0dc3..00000000 --- a/eek/eek-container.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2010-2011 Daiki Ueno - * Copyright (C) 2010-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 - */ - -/** - * SECTION:eek-container - * @short_description: Base class of a keyboard container - * - * The #EekContainerClass class represents a keyboard container, which - * shall be used to implement #EekKeyboard and #EekSection. - */ - -#include "config.h" - -#include "eek-container.h" - -enum { - CHILD_ADDED, - CHILD_REMOVED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -typedef struct _EekContainerPrivate -{ - GList *head; - GList *last; -} EekContainerPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT) - -static void -eek_container_real_add_child (EekContainer *self, - EekElement *child) -{ - EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self); - - g_return_if_fail (EEK_IS_ELEMENT(child)); - g_object_ref (child); - - if (!priv->head) { - priv->head = priv->last = g_list_prepend (priv->head, child); - } else { - priv->last->next = g_list_prepend (priv->last->next, child); - priv->last = priv->last->next; - } - eek_element_set_parent (child, EEK_ELEMENT(self)); - g_signal_emit (self, signals[CHILD_ADDED], 0, child); -} - -static void -eek_container_real_remove_child (EekContainer *self, - EekElement *child) -{ - EekContainerPrivate *priv = eek_container_get_instance_private (self); - GList *head; - - g_return_if_fail (EEK_IS_ELEMENT(child)); - head = g_list_find (priv->head, child); - g_return_if_fail (head); - g_object_unref (child); - if (head == priv->last) - priv->last = g_list_previous (priv->last); - priv->head = g_list_remove_link (priv->head, head); - eek_element_set_parent (child, NULL); - g_signal_emit (self, signals[CHILD_REMOVED], 0, child); -} - -static void -eek_container_real_foreach_child (EekContainer *self, - EekCallback callback, - gpointer user_data) -{ - EekContainerPrivate *priv = eek_container_get_instance_private (self); - GList *head; - - for (head = priv->head; head; head = g_list_next (head)) - (*callback) (EEK_ELEMENT(head->data), user_data); -} - -static EekElement * -eek_container_real_find (EekContainer *self, - EekCompareFunc func, - gpointer user_data) -{ - EekContainerPrivate *priv = eek_container_get_instance_private (self); - GList *head; - - head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func); - if (head) - return head->data; - return NULL; -} - -static void -eek_container_dispose (GObject *object) -{ - EekContainer *self = EEK_CONTAINER (object); - EekContainerPrivate *priv = eek_container_get_instance_private (self); - GList *head; - - for (head = priv->head; head; head = priv->head) { - g_object_unref (head->data); - priv->head = g_list_next (head); - g_list_free1 (head); - } - G_OBJECT_CLASS(eek_container_parent_class)->dispose (object); -} - -static void -eek_container_class_init (EekContainerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - klass->add_child = eek_container_real_add_child; - klass->remove_child = eek_container_real_remove_child; - klass->foreach_child = eek_container_real_foreach_child; - klass->find = eek_container_real_find; - - /* signals */ - klass->child_added = NULL; - klass->child_removed = NULL; - - gobject_class->dispose = eek_container_dispose; - - /** - * EekContainer::child-added: - * @container: an #EekContainer - * @element: an #EekElement - * - * The ::child-added signal is emitted each time an element is - * added to @container. - */ - signals[CHILD_ADDED] = - g_signal_new (I_("child-added"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(EekContainerClass, child_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - EEK_TYPE_ELEMENT); - - /** - * EekContainer::child-removed: - * @container: an #EekContainer - * @element: an #EekElement - * - * The ::child-removed signal is emitted each time an element is - * removed from @container. - */ - signals[CHILD_REMOVED] = - g_signal_new (I_("child-removed"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(EekContainerClass, child_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - EEK_TYPE_ELEMENT); -} - -static void -eek_container_init (EekContainer *self) -{ - /* void */ -} - -/** - * eek_container_foreach_child: - * @container: an #EekContainer - * @callback: (scope call): an #EekCallback - * @user_data: additional data passed to @callback - * - * Enumerate children of @container and run @callback with each child. - */ -void -eek_container_foreach_child (EekContainer *container, - EekCallback callback, - gpointer user_data) -{ - g_return_if_fail (EEK_IS_CONTAINER(container)); - EEK_CONTAINER_GET_CLASS(container)->foreach_child (container, - callback, - user_data); -} - -/** - * eek_container_find: - * @container: an #EekContainer - * @func: function to be used to compare two children - * @user_data: additional data passed to @func - * - * Find a child which matches the criteria supplied as @func, in @container. - * Returns: an #EekElement or NULL on failure - */ -EekElement * -eek_container_find (EekContainer *container, - EekCompareFunc func, - gpointer user_data) -{ - g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL); - return EEK_CONTAINER_GET_CLASS(container)->find (container, - func, - user_data); -} - -void -eek_container_add_child (EekContainer *container, EekElement *element) -{ - g_return_if_fail (EEK_IS_CONTAINER(container)); - g_return_if_fail (EEK_IS_ELEMENT(element)); - return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element); -} diff --git a/eek/eek-container.h b/eek/eek-container.h deleted file mode 100644 index b246d9e2..00000000 --- a/eek/eek-container.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2010-2011 Daiki Ueno - * Copyright (C) 2010-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 - */ - -#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef EEK_CONTAINER_H -#define EEK_CONTAINER_H 1 - -#include "eek-element.h" - -G_BEGIN_DECLS - -#define EEK_TYPE_CONTAINER (eek_container_get_type()) -G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement) - -/** - * EekCallback: - * @element: an #EekElement - * @user_data: user-supplied data - * - * The type of the callback function used for iterating over the - * children of a container, see eek_container_foreach_child(). - */ -typedef void (*EekCallback) (EekElement *element, gpointer user_data); -typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data); - -/** - * EekContainerClass: - * @foreach_child: virtual function for iterating over the container's children - * @find: virtual function for looking up a child - * @child_added: class handler for #EekContainer::child-added - * @child_removed: class handler for #EekContainer::child-added - */ -struct _EekContainerClass -{ - /*< private >*/ - EekElementClass parent_class; - - void (* add_child) (EekContainer *self, - EekElement *element); - - void (* remove_child) (EekContainer *self, - EekElement *element); - - /*< public >*/ - void (* foreach_child) (EekContainer *self, - EekCallback callback, - gpointer user_data); - EekElement *(* find) (EekContainer *self, - EekCompareFunc func, - gpointer data); - - /* signals */ - void (* child_added) (EekContainer *self, - EekElement *element); - void (* child_removed) (EekContainer *self, - EekElement *element); - /*< private >*/ - /* padding */ - gpointer pdummy[24]; -}; - -GType eek_container_get_type (void) G_GNUC_CONST; - -void eek_container_foreach_child (EekContainer *container, - EekCallback callback, - gpointer user_data); -EekElement *eek_container_find (EekContainer *container, - EekCompareFunc func, - gpointer user_data); -void eek_container_add_child (EekContainer *container, - EekElement *element); - -G_END_DECLS -#endif /* EEK_CONTAINER_H */ diff --git a/eek/eek-element.c b/eek/eek-element.c index dbe97750..3ede68ee 100644 --- a/eek/eek-element.c +++ b/eek/eek-element.c @@ -31,26 +31,16 @@ #include #include "eek-element.h" -#include "eek-container.h" -#include "eek-marshalers.h" enum { PROP_0, - PROP_NAME, PROP_BOUNDS, PROP_LAST }; -enum { - SYMBOL_INDEX_CHANGED, - LAST_SIGNAL -}; - typedef struct _EekElementPrivate { - gchar *name; EekBounds bounds; - EekElement *parent; } EekElementPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT) @@ -58,10 +48,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT) static void eek_element_finalize (GObject *object) { - EekElement *self = EEK_ELEMENT (object); - EekElementPrivate *priv = eek_element_get_instance_private (self); - - g_free (priv->name); G_OBJECT_CLASS (eek_element_parent_class)->finalize (object); } @@ -74,10 +60,6 @@ eek_element_set_property (GObject *object, EekElement *element = EEK_ELEMENT(object); switch (prop_id) { - case PROP_NAME: - eek_element_set_name (element, - g_value_dup_string (value)); - break; case PROP_BOUNDS: eek_element_set_bounds (element, g_value_get_boxed (value)); break; @@ -97,9 +79,6 @@ eek_element_get_property (GObject *object, EekBounds bounds; switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, eek_element_get_name (element)); - break; case PROP_BOUNDS: eek_element_get_bounds (element, &bounds); g_value_set_boxed (value, &bounds); @@ -121,20 +100,6 @@ eek_element_class_init (EekElementClass *klass) gobject_class->get_property = eek_element_get_property; gobject_class->finalize = eek_element_finalize; - /** - * EekElement:name: - * - * The name of #EekElement. - */ - pspec = g_param_spec_string ("name", - "Name", - "Name", - NULL, - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_NAME, - pspec); - /** * EekElement:bounds: * @@ -156,90 +121,6 @@ eek_element_init (EekElement *self) (void)self; } -/** - * eek_element_set_parent: - * @element: an #EekElement - * @parent: (allow-none): an #EekElement or %NULL - * - * Set the parent of @element to @parent. - */ -void -eek_element_set_parent (EekElement *element, - EekElement *parent) -{ - g_return_if_fail (EEK_IS_ELEMENT(element)); - g_return_if_fail (parent == NULL || EEK_IS_ELEMENT(parent)); - - EekElementPrivate *priv = eek_element_get_instance_private (element); - - if (priv->parent == parent) - return; - - if (priv->parent != NULL) { - /* release self-reference acquired when setting parent */ - g_object_unref (element); - } - - if (parent != NULL) { - g_object_ref (element); - } - - priv->parent = parent; -} - -/** - * eek_element_get_parent: - * @element: an #EekElement - * - * Get the parent of @element. - * Returns: an #EekElement if the parent is set - */ -EekElement * -eek_element_get_parent (EekElement *element) -{ - g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL); - - EekElementPrivate *priv = eek_element_get_instance_private (element); - - return priv->parent; -} - -/** - * eek_element_set_name: - * @element: an #EekElement - * @name: name of @element - * - * Set the name of @element to @name. - */ -void -eek_element_set_name (EekElement *element, - const gchar *name) -{ - g_return_if_fail (EEK_IS_ELEMENT(element)); - - EekElementPrivate *priv = eek_element_get_instance_private (element); - - g_free (priv->name); - priv->name = g_strdup (name); -} - -/** - * eek_element_get_name: - * @element: an #EekElement - * - * Get the name of @element. - * Returns: the name of @element or NULL when the name is not set - */ -const gchar * -eek_element_get_name (EekElement *element) -{ - g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL); - - EekElementPrivate *priv = eek_element_get_instance_private (element); - - return priv->name; -} - /** * eek_element_set_bounds: * @element: an #EekElement @@ -280,70 +161,3 @@ eek_element_get_bounds (EekElement *element, memcpy (bounds, &priv->bounds, sizeof(EekBounds)); } - -/** - * eek_element_get_absolute_position: - * @element: an #EekElement - * @x: pointer where the X coordinate of @element will be stored - * @y: pointer where the Y coordinate of @element will be stored - * - * Compute the absolute position of @element. - */ -void -eek_element_get_absolute_position (EekElement *element, - gdouble *x, - gdouble *y) -{ - EekBounds bounds; - gdouble ax = 0.0, ay = 0.0; - - do { - eek_element_get_bounds (element, &bounds); - ax += bounds.x; - ay += bounds.y; - } while ((element = eek_element_get_parent (element)) != NULL); - *x = ax; - *y = ay; -} - -/** - * eek_element_set_position: - * @element: an #EekElement - * @x: X coordinate of top left corner - * @y: Y coordinate of top left corner - * - * Set the relative position of @element. - */ -void -eek_element_set_position (EekElement *element, - gdouble x, - gdouble y) -{ - EekBounds bounds; - - eek_element_get_bounds (element, &bounds); - bounds.x = x; - bounds.y = y; - eek_element_set_bounds (element, &bounds); -} - -/** - * eek_element_set_size: - * @element: an #EekElement - * @width: width of @element - * @height: height of @element - * - * Set the size of @element. - */ -void -eek_element_set_size (EekElement *element, - gdouble width, - gdouble height) -{ - EekBounds bounds; - - eek_element_get_bounds (element, &bounds); - bounds.width = width; - bounds.height = height; - eek_element_set_bounds (element, &bounds); -} diff --git a/eek/eek-element.h b/eek/eek-element.h index 12d19fdd..87e59723 100644 --- a/eek/eek-element.h +++ b/eek/eek-element.h @@ -40,9 +40,6 @@ struct _EekElementClass GType eek_element_get_type (void) G_GNUC_CONST; -void eek_element_set_parent (EekElement *element, - EekElement *parent); -EekElement *eek_element_get_parent (EekElement *element); void eek_element_set_name (EekElement *element, const gchar *name); @@ -54,16 +51,5 @@ void eek_element_set_bounds (EekElement *element, void eek_element_get_bounds (EekElement *element, EekBounds *bounds); -void eek_element_set_position (EekElement *element, - gdouble x, - gdouble y); -void eek_element_set_size (EekElement *element, - gdouble width, - gdouble height); - -void eek_element_get_absolute_position (EekElement *element, - gdouble *x, - gdouble *y); - G_END_DECLS #endif /* EEK_ELEMENT_H */ diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index 1bf39539..be018573 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -34,15 +34,12 @@ #include "eek-renderer.h" #include "eek-keyboard.h" -#include "eek-section.h" -#include "eek-key.h" #include "src/symbol.h" #include "eek-gtk-keyboard.h" enum { PROP_0, - PROP_KEYBOARD, PROP_LAST }; @@ -64,16 +61,16 @@ typedef struct _EekGtkKeyboardPrivate G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA) -static void on_key_pressed (EekKey *key, - EekGtkKeyboard *self, guint level); -static void on_key_released (EekKey *key, +static void on_button_pressed (struct squeek_button *button, struct squeek_view *view, EekGtkKeyboard *self); -static void render_pressed_key (GtkWidget *widget, - EekKey *key, guint level); -static void render_locked_key (GtkWidget *widget, - EekKey *key, guint level); -static void render_released_key (GtkWidget *widget, - EekKey *key); +static void on_button_released (struct squeek_button *button, + struct squeek_view *view, + EekGtkKeyboard *self); +static void render_pressed_button (GtkWidget *widget, struct button_place *place); +static void render_locked_button (GtkWidget *widget, + struct button_place *place); +static void render_released_button (GtkWidget *widget, + struct squeek_button *button); static void eek_gtk_keyboard_real_realize (GtkWidget *self) @@ -112,18 +109,26 @@ eek_gtk_keyboard_real_draw (GtkWidget *self, eek_renderer_render_keyboard (priv->renderer, cr); - uint level = priv->keyboard->level; + struct squeek_view *view = priv->keyboard->views[priv->keyboard->level]; /* redraw pressed key */ - const GList *list = priv->keyboard->pressed_keys; + const GList *list = priv->keyboard->pressed_buttons; for (const GList *head = list; head; head = g_list_next (head)) { - render_pressed_key (self, head->data, level); + struct button_place place = squeek_view_find_key( + view, squeek_button_get_key(head->data) + ); + render_pressed_button (self, &place); } /* redraw locked key */ - list = priv->keyboard->locked_keys; + list = priv->keyboard->locked_buttons; for (const GList *head = list; head; head = g_list_next (head)) { - render_locked_key (self, ((EekModifierKey *)head->data)->key, level); + struct button_place place = squeek_view_find_key( + view, squeek_button_get_key( + ((EekModifierKey *)head->data)->button + ) + ); + render_locked_button (self, &place); } return FALSE; @@ -149,45 +154,45 @@ static void depress(EekGtkKeyboard *self, gdouble x, gdouble y, guint32 time) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); + struct squeek_view *view = level_keyboard_current(priv->keyboard); + struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y); - if (key) { - eek_keyboard_press_key(priv->keyboard, key, time); - guint level = priv->keyboard->level; - on_key_pressed(key, self, level); + if (button) { + eek_keyboard_press_button(priv->keyboard, button, time); + on_button_pressed(button, view, self); } } static void drag(EekGtkKeyboard *self, gdouble x, gdouble y, guint32 time) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y); + struct squeek_view *view = level_keyboard_current(priv->keyboard); + struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y); GList *list, *head; - list = g_list_copy(priv->keyboard->pressed_keys); + list = g_list_copy(priv->keyboard->pressed_buttons); - if (key) { + if (button) { gboolean found = FALSE; for (head = list; head; head = g_list_next (head)) { - if (head->data == key) { + if (head->data == button) { found = TRUE; } else { - eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time); - on_key_released(key, self); + eek_keyboard_release_button(priv->keyboard, head->data, time); + on_button_released(button, view, self); } } g_list_free (list); if (!found) { - eek_keyboard_press_key(priv->keyboard, key, time); - guint level = priv->keyboard->level; - on_key_pressed(key, self, level); + eek_keyboard_press_button(priv->keyboard, button, time); + on_button_pressed(button, view, self); } } else { for (head = list; head; head = g_list_next (head)) { - eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time); - on_key_released(EEK_KEY(head->data), self); + eek_keyboard_release_button(priv->keyboard, head->data, time); + on_button_released(head->data, view, self); } g_list_free (list); } @@ -196,11 +201,13 @@ static void drag(EekGtkKeyboard *self, static void release(EekGtkKeyboard *self, guint32 time) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - GList *list = g_list_copy(priv->keyboard->pressed_keys); + struct squeek_view *view = level_keyboard_current(priv->keyboard); + + GList *list = g_list_copy(priv->keyboard->pressed_buttons); for (GList *head = list; head; head = g_list_next (head)) { - EekKey *key = EEK_KEY(head->data); - eek_keyboard_release_key(priv->keyboard, key, time); - on_key_released(key, self); + struct squeek_button *button = head->data; + eek_keyboard_release_button(priv->keyboard, button, time); + on_button_released(button, view, self); } g_list_free (list); } @@ -283,7 +290,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self) elements, so that the default handler of EekKeyboard::key-released signal can remove elements from its internal copy */ - list = g_list_copy(priv->keyboard->pressed_keys); + list = g_list_copy(priv->keyboard->pressed_buttons); for (head = list; head; head = g_list_next (head)) { g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released"); g_signal_emit_by_name (head->data, "released"); @@ -303,13 +310,13 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget, { EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); + struct squeek_view *view = level_keyboard_current(priv->keyboard); - EekKey *key; - - key = eek_renderer_find_key_by_position (priv->renderer, - (gdouble)x, - (gdouble)y); - if (key) { + struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, + view, + (gdouble)x, + (gdouble)y); + if (button) { //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level); const gchar *text = NULL; // FIXME if (text) { @@ -320,31 +327,13 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget, return FALSE; } -static void -eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self, - LevelKeyboard *keyboard) -{ - EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); - - if (priv->keyboard == keyboard) - return; - - priv->keyboard = keyboard; -} - static void eek_gtk_keyboard_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - LevelKeyboard *keyboard; - switch (prop_id) { - case PROP_KEYBOARD: - keyboard = g_value_get_object (value); - eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -365,7 +354,7 @@ eek_gtk_keyboard_dispose (GObject *object) if (priv->keyboard) { GList *list, *head; - list = g_list_copy(priv->keyboard->pressed_keys); + list = g_list_copy(priv->keyboard->pressed_buttons); for (head = list; head; head = g_list_next (head)) { g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed"); g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard)); @@ -383,7 +372,6 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; widget_class->realize = eek_gtk_keyboard_real_realize; widget_class->unmap = eek_gtk_keyboard_real_unmap; @@ -401,15 +389,6 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass) gobject_class->set_property = eek_gtk_keyboard_set_property; gobject_class->dispose = eek_gtk_keyboard_dispose; - - pspec = g_param_spec_object ("keyboard", - "Keyboard", - "Keyboard", - EEK_TYPE_KEYBOARD, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); - g_object_class_install_property (gobject_class, - PROP_KEYBOARD, - pspec); } static void @@ -448,9 +427,8 @@ eek_gtk_keyboard_new (LevelKeyboard *keyboard) } static void -render_pressed_key (GtkWidget *widget, - EekKey *key, - guint level) +render_pressed_button (GtkWidget *widget, + struct button_place *place) { EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); @@ -460,7 +438,7 @@ render_pressed_key (GtkWidget *widget, GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); - eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE); + eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE); /* eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE); */ @@ -470,9 +448,7 @@ render_pressed_key (GtkWidget *widget, } static void -render_locked_key (GtkWidget *widget, - EekKey *key, - guint level) +render_locked_button (GtkWidget *widget, struct button_place *place) { EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); @@ -482,7 +458,7 @@ render_locked_key (GtkWidget *widget, GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); - eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE); + eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE); gdk_window_end_draw_frame (window, context); @@ -490,9 +466,10 @@ render_locked_key (GtkWidget *widget, } static void -render_released_key (GtkWidget *widget, - EekKey *key) +render_released_button (GtkWidget *widget, + struct squeek_button *button) { + (void)button; EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); @@ -509,9 +486,9 @@ render_released_key (GtkWidget *widget, } static void -on_key_pressed (EekKey *key, - EekGtkKeyboard *self, - guint level) +on_button_pressed (struct squeek_button *button, + struct squeek_view *view, + EekGtkKeyboard *self) { EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); @@ -519,7 +496,14 @@ on_key_pressed (EekKey *key, if (!priv->renderer) return; - render_pressed_key (GTK_WIDGET(self), key, level); + struct button_place place = { + .button = button, + .row = squeek_view_get_row(view, button), + }; + if (!place.row) { + return; + } + render_pressed_button (GTK_WIDGET(self), &place); gtk_widget_queue_draw (GTK_WIDGET(self)); #if HAVE_LIBCANBERRA @@ -532,16 +516,18 @@ on_key_pressed (EekKey *key, } static void -on_key_released (EekKey *key, +on_button_released (struct squeek_button *button, + struct squeek_view *view, EekGtkKeyboard *self) { + (void)view; EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self); /* renderer may have not been set yet if the widget is a popup */ if (!priv->renderer) return; - render_released_key (GTK_WIDGET(self), key); + render_released_button (GTK_WIDGET(self), button); gtk_widget_queue_draw (GTK_WIDGET(self)); #if HAVE_LIBCANBERRA diff --git a/eek/eek-key.c b/eek/eek-key.c deleted file mode 100644 index 0b4b6e3c..00000000 --- a/eek/eek-key.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 2010-2011 Daiki Ueno - * Copyright (C) 2010-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 - */ - -/** - * SECTION:eek-key - * @short_description: Base class of a key - * - * The #EekKeyClass class represents a key. - */ - -#include "config.h" - -#include - -#include "eek-section.h" -#include "eek-keyboard.h" -#include "src/keyboard.h" -#include "src/symbol.h" - -#include "eek-key.h" - -enum { - PROP_0, - PROP_OREF, - PROP_LAST -}; - -enum { - LOCKED, - UNLOCKED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -typedef struct _EekKeyPrivate -{ - gulong oref; // UI outline reference - struct squeek_key *state; - gboolean is_locked; -} EekKeyPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT) - -static void -eek_key_real_locked (EekKey *self) -{ - EekKeyPrivate *priv = eek_key_get_instance_private (self); - - priv->is_locked = TRUE; -#if DEBUG - g_debug ("locked %X", eek_key_get_keycode (self)); -#endif -} - -static void -eek_key_real_unlocked (EekKey *self) -{ - EekKeyPrivate *priv = eek_key_get_instance_private (self); - - priv->is_locked = FALSE; -#if DEBUG - g_debug ("unlocked %X", eek_key_get_keycode (self)); -#endif -} - -static void -eek_key_finalize (GObject *object) -{ - EekKey *self = EEK_KEY (object); - EekKeyPrivate *priv = eek_key_get_instance_private (self); - - squeek_key_free (priv->state); - - G_OBJECT_CLASS (eek_key_parent_class)->finalize (object); -} - -static void -eek_key_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_OREF: - eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eek_key_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_OREF: - g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eek_key_class_init (EekKeyClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->set_property = eek_key_set_property; - gobject_class->get_property = eek_key_get_property; - gobject_class->finalize = eek_key_finalize; - - /* signals */ - klass->locked = eek_key_real_locked; - klass->unlocked = eek_key_real_unlocked; - - /** - * EekKey:oref: - * - * The outline id of #EekKey. - */ - pspec = g_param_spec_ulong ("oref", - "Oref", - "Outline id of the key", - 0, G_MAXULONG, 0, - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_OREF, pspec); - - /** - * EekKey::locked: - * @key: an #EekKey - * - * The ::locked signal is emitted each time @key is shifted to - * the locked state. The class handler runs before signal - * handlers to allow signal handlers to read the status of @key - * with eek_key_is_locked(). - */ - signals[LOCKED] = - g_signal_new (I_("locked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(EekKeyClass, locked), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * EekKey::unlocked: - * @key: an #EekKey - * - * The ::unlocked signal is emitted each time @key is shifted to - * the unlocked state. - */ - signals[UNLOCKED] = - g_signal_new (I_("unlocked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekKeyClass, unlocked), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -eek_key_init (EekKey *self) -{ - EekKeyPrivate *priv = eek_key_get_instance_private (self); - priv->state = squeek_key_new (0); -} - -void eek_key_share_state(EekKey *self, struct squeek_key *state) { - EekKeyPrivate *priv = eek_key_get_instance_private (self); - priv->state = state; -} -/** - * eek_key_set_keycode: - * @key: an #EekKey - * @keycode: keycode - * - * Set the keycode of @key to @keycode. Since typically the keycode - * value is used to find a key in a keyboard by calling - * eek_keyboard_find_key_by_keycode, it is not necessarily the same as - * the X keycode but it should be unique in the keyboard @key belongs - * to. - */ -void -eek_key_set_keycode (EekKey *key, - guint keycode) -{ - g_return_if_fail (EEK_IS_KEY (key)); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - squeek_key_set_keycode(priv->state, keycode); -} - -/** - * eek_key_get_keycode: - * @key: an #EekKey - * - * Get keycode of @key. - * Returns: keycode or %EEK_INVALID_KEYCODE on failure - */ -guint -eek_key_get_keycode (EekKey *key) -{ - g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - return squeek_key_get_keycode(priv->state); -} - -/** - * eek_key_get_symbol_at_index: - * @key: an #EekKey - * @group: group index of the symbol matrix - * @level: level index of the symbol matrix - * @fallback_group: fallback group index - * @fallback_level: fallback level index - * - * Get the symbol at (@group, @level) in the symbol matrix of @key. - * Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL - */ -struct squeek_symbol* -eek_key_get_symbol_at_index (EekKey *key, - gint group, - guint level) -{ - EekKeyPrivate *priv = eek_key_get_instance_private (key); - return squeek_key_get_symbol(priv->state, level); -} - -/** - * eek_key_set_oref: - * @key: an #EekKey - * @oref: outline id of @key - * - * Set the outline id of @key to @oref. - */ -void -eek_key_set_oref (EekKey *key, - guint oref) -{ - g_return_if_fail (EEK_IS_KEY(key)); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - if (priv->oref != oref) { - priv->oref = oref; - g_object_notify (G_OBJECT(key), "oref"); - } -} - -/** - * eek_key_get_oref: - * @key: an #EekKey - * - * Get the outline id of @key. - * Returns: unsigned integer - */ -guint -eek_key_get_oref (EekKey *key) -{ - g_return_val_if_fail (EEK_IS_KEY (key), 0); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - return priv->oref; -} - -/** - * eek_key_is_pressed: - * @key: an #EekKey - * - * Return %TRUE if key is marked as pressed. - */ -gboolean -eek_key_is_pressed (EekKey *key) -{ - g_return_val_if_fail (EEK_IS_KEY(key), FALSE); - - EekKeyPrivate *priv = (EekKeyPrivate*)eek_key_get_instance_private (key); - - return (bool)squeek_key_is_pressed(priv->state); -} - -/** - * eek_key_is_locked: - * @key: an #EekKey - * - * Return %TRUE if key is marked as locked. - */ -gboolean -eek_key_is_locked (EekKey *key) -{ - g_return_val_if_fail (EEK_IS_KEY(key), FALSE); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - return priv->is_locked; -} - -void eek_key_set_pressed(EekKey *key, gboolean value) -{ - g_return_if_fail (EEK_IS_KEY(key)); - - EekKeyPrivate *priv = eek_key_get_instance_private (key); - - squeek_key_set_pressed(priv->state, value); -} - -struct squeek_key *eek_key_get_state(EekKey *key) { - EekKeyPrivate *priv = eek_key_get_instance_private (key); - return priv->state; -} diff --git a/eek/eek-key.h b/eek/eek-key.h deleted file mode 100644 index a6699333..00000000 --- a/eek/eek-key.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010-2011 Daiki Ueno - * Copyright (C) 2010-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 - */ - -#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef EEK_KEY_H -#define EEK_KEY_H 1 - -#include "eek-element.h" - -G_BEGIN_DECLS - -#define EEK_TYPE_KEY (eek_key_get_type()) -G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement) - -/** - * EekKeyClass: - * @pressed: class handler for #EekKey::pressed signal - * @released: class handler for #EekKey::released signal - * @locked: class handler for #EekKey::locked signal - * @unlocked: class handler for #EekKey::unlocked signal - * @cancelled: class handler for #EekKey::cancelled signal - * @is_pressed: virtual function for getting whether the key is pressed - * @is_locked: virtual function for getting whether the key is locked - */ -struct _EekKeyClass -{ - /*< private >*/ - EekElementClass parent_class; - - /*< public >*/ - /* signals */ - void (* locked) (EekKey *key); - void (* unlocked) (EekKey *key); -}; - -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); -struct squeek_key *eek_key_get_state(EekKey *key); -struct squeek_symbol *eek_key_get_symbol_at_index (EekKey *key, - gint group, - guint level); - -void eek_key_set_oref (EekKey *key, - guint oref); -guint eek_key_get_oref (EekKey *key); - -gboolean eek_key_is_pressed (EekKey *key); -gboolean eek_key_is_locked (EekKey *key); -void eek_key_set_pressed (EekKey *key, - gboolean value); -void eek_key_share_state(EekKey *self, struct squeek_key *state); -G_END_DECLS -#endif /* EEK_KEY_H */ diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 8423fa78..67e3da59 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -1,17 +1,17 @@ -/* +/* * Copyright (C) 2010-2011 Daiki Ueno * Copyright (C) 2010-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 @@ -30,9 +30,6 @@ #include "config.h" #include -#include "eek-marshalers.h" -#include "eek-section.h" -#include "eek-key.h" #include "eek-enumtypes.h" #include "eekboard/key-emitter.h" #include "keymap.h" @@ -41,40 +38,6 @@ #include "eek-keyboard.h" -enum { - PROP_0, - PROP_LAST -}; - -enum { - KEY_RELEASED, - KEY_LOCKED, - KEY_UNLOCKED, - LAST_SIGNAL -}; - -enum { - VIEW_LETTERS_LOWER, - VIEW_LETTERS_UPPER, - VIEW_NUMBERS, - VIEW_SYMBOLS -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -#define EEK_KEYBOARD_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate)) - -struct _EekKeyboardPrivate -{ - char dummy; // won't run otherwise -}; - -G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER); - -G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key, - eek_modifier_key_copy, eek_modifier_key_free); - EekModifierKey * eek_modifier_key_copy (EekModifierKey *modkey) { @@ -84,94 +47,38 @@ eek_modifier_key_copy (EekModifierKey *modkey) void eek_modifier_key_free (EekModifierKey *modkey) { - g_object_unref (modkey->key); g_slice_free (EekModifierKey, modkey); } -static void -on_key_locked (EekSection *section, - EekKey *key, - EekKeyboard *keyboard) -{ - g_signal_emit (keyboard, signals[KEY_LOCKED], 0, key); -} - -static void -on_key_unlocked (EekSection *section, - EekKey *key, - EekKeyboard *keyboard) -{ - g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key); -} - -EekSection * -eek_keyboard_real_create_section (EekKeyboard *self) -{ - EekSection *section; - - section = g_object_new (EEK_TYPE_SECTION, NULL); - g_return_val_if_fail (section, NULL); - - EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), - EEK_ELEMENT(section)); - return section; -} - -static void -eek_keyboard_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eek_keyboard_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - /// Updates the state of locked keys based on the key that was activated /// FIXME: make independent of what the key are named, /// and instead refer to the contained symbols static guint set_key_states (LevelKeyboard *keyboard, - EekKey *key, + struct squeek_button *button, guint new_level) { + struct squeek_key *key = squeek_button_get_key(button); // Keys locking rules hardcoded for the time being... - const gchar *name = eek_element_get_name(EEK_ELEMENT(key)); + const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key)); // Lock the shift whenever it's pressed on the baselevel // TODO: need to lock shift on the destination level if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) { EekModifierKey *modifier_key = g_slice_new (EekModifierKey); modifier_key->modifiers = 0; - modifier_key->key = g_object_ref (key); - keyboard->locked_keys = - g_list_prepend (keyboard->locked_keys, modifier_key); - g_signal_emit_by_name (modifier_key->key, "locked"); + modifier_key->button = button; + keyboard->locked_buttons = + g_list_prepend (keyboard->locked_buttons, modifier_key); + squeek_key_set_locked(key, true); } - if (keyboard->level == 1) { // Only shift is locked in this state, unlock on any key press - for (GList *head = keyboard->locked_keys; head; ) { + for (GList *head = keyboard->locked_buttons; head; ) { EekModifierKey *modifier_key = head->data; GList *next = g_list_next (head); - keyboard->locked_keys = - g_list_remove_link (keyboard->locked_keys, head); - g_signal_emit_by_name (modifier_key->key, "unlocked"); + keyboard->locked_buttons = + g_list_remove_link (keyboard->locked_buttons, head); + squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false); g_list_free1 (head); head = next; } @@ -182,13 +89,13 @@ set_key_states (LevelKeyboard *keyboard, // FIXME: unhardcode, parse some user information as to which key triggers which view (level) static void -set_level_from_press (LevelKeyboard *keyboard, EekKey *key) +set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button) { /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */ guint level = keyboard->level; /* Handle non-emitting keys */ - if (key) { - const gchar *name = eek_element_get_name(EEK_ELEMENT(key)); + if (button) { + const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button))); if (g_strcmp0(name, "show_numbers") == 0) { level = 2; } else if (g_strcmp0(name, "show_letters") == 0) { @@ -200,18 +107,17 @@ set_level_from_press (LevelKeyboard *keyboard, EekKey *key) } } - keyboard->level = set_key_states(keyboard, key, level); + keyboard->level = set_key_states(keyboard, button, level); eek_layout_update_layout(keyboard); } -void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) { - eek_key_set_pressed(key, TRUE); - keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key); +void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) { + struct squeek_key *key = squeek_button_get_key(button); + squeek_key_set_pressed(key, TRUE); + keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button); - struct squeek_symbol *symbol = eek_key_get_symbol_at_index( - key, 0, keyboard->level - ); + struct squeek_symbol *symbol = squeek_key_get_symbol(key); if (!symbol) return; @@ -220,48 +126,35 @@ void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timest // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event - guint keycode = eek_key_get_keycode (key); + guint keycode = squeek_key_get_keycode (key); emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp); } -void eek_keyboard_release_key(LevelKeyboard *keyboard, - EekKey *key, +void eek_keyboard_release_button(LevelKeyboard *keyboard, + struct squeek_button *button, guint32 timestamp) { - for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) { - if (head->data == key) { - keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head); + for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) { + if (head->data == button) { + keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head); g_list_free1 (head); break; } } - struct squeek_symbol *symbol = eek_key_get_symbol_at_index( - key, 0, keyboard->level); + struct squeek_symbol *symbol = squeek_button_get_symbol(button); if (!symbol) return; - set_level_from_press (keyboard, key); + set_level_from_press (keyboard, button); // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event - guint keycode = eek_key_get_keycode (key); + guint keycode = squeek_key_get_keycode (squeek_button_get_key(button)); emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp); } -static void -eek_keyboard_dispose (GObject *object) -{ - G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object); -} - -static void -eek_keyboard_finalize (GObject *object) -{ - G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object); -} - void level_keyboard_deinit(LevelKeyboard *self) { g_hash_table_destroy (self->names); for (guint i = 0; i < self->outline_array->len; i++) { @@ -282,99 +175,18 @@ void level_keyboard_free(LevelKeyboard *self) { g_free(self); } -static void -eek_keyboard_real_child_added (EekContainer *self, - EekElement *element) -{ - g_signal_connect (element, "key-locked", - G_CALLBACK(on_key_locked), self); - g_signal_connect (element, "key-unlocked", - G_CALLBACK(on_key_unlocked), self); -} - -static void -eek_keyboard_real_child_removed (EekContainer *self, - EekElement *element) -{ - g_signal_handlers_disconnect_by_func (element, on_key_locked, self); - g_signal_handlers_disconnect_by_func (element, on_key_unlocked, self); -} - -static void -eek_keyboard_class_init (EekKeyboardClass *klass) -{ - EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - /* signals */ - container_class->child_added = eek_keyboard_real_child_added; - container_class->child_removed = eek_keyboard_real_child_removed; - - gobject_class->get_property = eek_keyboard_get_property; - gobject_class->set_property = eek_keyboard_set_property; - gobject_class->dispose = eek_keyboard_dispose; - gobject_class->finalize = eek_keyboard_finalize; - - /** - * EekKeyboard::key-locked: - * @keyboard: an #EekKeyboard - * @key: an #EekKey - * - * The ::key-locked signal is emitted each time a key in @keyboard - * is shifted to the locked state. - */ - signals[KEY_LOCKED] = - g_signal_new (I_("key-locked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekKeyboardClass, key_locked), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EEK_TYPE_KEY); - - /** - * EekKeyboard::key-unlocked: - * @keyboard: an #EekKeyboard - * @key: an #EekKey - * - * The ::key-unlocked signal is emitted each time a key in @keyboard - * is shifted to the unlocked state. - */ - signals[KEY_UNLOCKED] = - g_signal_new (I_("key-unlocked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekKeyboardClass, key_unlocked), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EEK_TYPE_KEY); -} - -static void -eek_keyboard_init (EekKeyboard *self) -{ - self->priv = EEK_KEYBOARD_GET_PRIVATE(self); - self->scale = 1.0; -} - void level_keyboard_init(LevelKeyboard *self) { self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); } -LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash) { +LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[4], GHashTable *name_button_hash) { LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1); level_keyboard_init(keyboard); for (uint i = 0; i < 4; i++) { keyboard->views[i] = views[i]; } keyboard->manager = manager; - keyboard->names = name_key_hash; + keyboard->names = name_button_hash; return keyboard; } @@ -386,33 +198,13 @@ LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard * * Find an #EekKey whose name is @name. * Return value: (transfer none): #EekKey whose name is @name */ -EekKey * -eek_keyboard_find_key_by_name (LevelKeyboard *keyboard, +struct squeek_button* +eek_keyboard_find_button_by_name (LevelKeyboard *keyboard, const gchar *name) { return g_hash_table_lookup (keyboard->names, name); } -/** - * eek_keyboard_get_size: - * @keyboard: an #EekKeyboard - * @width: width of @keyboard - * @height: height of @keyboard - * - * Get the size of @keyboard. - */ -void -eek_keyboard_get_size (EekKeyboard *keyboard, - gdouble *width, - gdouble *height) -{ - EekBounds bounds; - - eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); - *width = bounds.width; - *height = bounds.height; -} - /** * eek_keyboard_get_outline: * @keyboard: an #EekKeyboard @@ -447,15 +239,16 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard) /* Iterate over the keys in the name-to-key hash table. */ GHashTableIter iter; - gchar *key_name; - gpointer key_ptr; + gchar *button_name; + gpointer button_ptr; g_hash_table_iter_init(&iter, keyboard->names); - while (g_hash_table_iter_next(&iter, (gpointer)&key_name, &key_ptr)) { + while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) { gchar *current, *line; - EekKey *key = EEK_KEY(key_ptr); - guint keycode = eek_key_get_keycode(key); + struct squeek_button *button = button_ptr; + struct squeek_key *key = squeek_button_get_key(button); + guint keycode = squeek_key_get_keycode(key); /* Don't include invalid keycodes in the keymap. */ if (keycode == EEK_INVALID_KEYCODE) @@ -463,7 +256,7 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard) /* Append a key name-to-keycode definition to the keycodes section. */ current = keycodes; - line = g_strdup_printf(" <%s> = %i;\n", (char *)key_name, keycode); + line = g_strdup_printf(" <%s> = %i;\n", (char *)button_name, keycode); keycodes = g_strconcat(current, line, NULL); g_free(line); @@ -471,8 +264,8 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard) // FIXME: free const char *key_str = squeek_key_to_keymap_entry( - (char*)key_name, - eek_key_get_state(key) + (char*)button_name, + key ); current = symbols; symbols = g_strconcat(current, key_str, NULL); @@ -490,7 +283,7 @@ eek_keyboard_get_keymap(LevelKeyboard *keyboard) return keymap; } -EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard) +struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard) { return keyboard->views[keyboard->level]; } diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h index 3508a93c..744cfe7d 100644 --- a/eek/eek-keyboard.h +++ b/eek/eek-keyboard.h @@ -27,109 +27,32 @@ #include #include -#include "eek-container.h" #include "eek-types.h" #include "eek-layout.h" +#include "src/layout.h" G_BEGIN_DECLS -#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type()) -#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard)) -#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass)) -#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD)) -#define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD)) -#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass)) - -typedef struct _EekKeyboardClass EekKeyboardClass; -typedef struct _EekKeyboardPrivate EekKeyboardPrivate; - -/** - * EekKeyboard: - * - * Contains the state of the physical keyboard. - * - * Is also a graphical element... - * - * The #EekKeyboard structure contains only private data and should - * only be accessed using the provided API. - */ -struct _EekKeyboard -{ - /*< private >*/ - EekContainer parent; - - EekKeyboardPrivate *priv; - double scale; -}; - -/** - * EekKeyboardClass: - * @create_section: virtual function for creating a section - * @find_key_by_name: virtual function for finding a key in the - * keyboard by name - * @key_pressed: class handler for #EekKeyboard::key-pressed signal - * @key_released: class handler for #EekKeyboard::key-released signal - * @key_locked: class handler for #EekKeyboard::key-locked signal - * @key_unlocked: class handler for #EekKeyboard::key-unlocked signal - * @key_cancelled: class handler for #EekKeyboard::key-cancelled signal - */ -struct _EekKeyboardClass -{ - /*< private >*/ - EekContainerClass parent_class; - - /* obsolete members moved to EekElement */ - gpointer set_symbol_index; - gpointer get_symbol_index; - - /*< public >*/ - EekKey *(* find_key_by_name) (EekKeyboard *self, - const gchar *name); - - /*< private >*/ - /* obsolete members moved to EekElement */ - gpointer symbol_index_changed; - - /*< public >*/ - /* signals */ - void (* key_locked) (EekKeyboard *self, - EekKey *key); - void (* key_unlocked) (EekKeyboard *self, - EekKey *key); - - /*< private >*/ - /* padding */ - gpointer pdummy[21]; -}; - -/** - * EekModifierKey: - * @modifiers: an #EekModifierType which @key triggers - * @key: an #EekKey - * - * Entry which associates modifier mask to a key. This is returned by - * eek_keyboard_get_locked_keys(). - */ struct _EekModifierKey { /*< public >*/ EekModifierType modifiers; - EekKey *key; + struct squeek_button *button; }; typedef struct _EekModifierKey EekModifierKey; /// Keyboard state holder struct _LevelKeyboard { - EekKeyboard *views[4]; + struct squeek_view *views[4]; guint level; struct xkb_keymap *keymap; int keymap_fd; // keymap formatted as XKB string size_t keymap_len; // length of the data inside keymap_fd GArray *outline_array; - GList *pressed_keys; - GList *locked_keys; + GList *pressed_buttons; // struct squeek_button* + GList *locked_buttons; // struct squeek_button* - /* Map key names to key objects: */ + /* Map button names to button objects: */ GHashTable *names; guint id; // as a key to layout choices @@ -138,28 +61,15 @@ struct _LevelKeyboard { }; typedef struct _LevelKeyboard LevelKeyboard; -LevelKeyboard *eek_keyboard_new(EekboardContextService *manager, - EekLayout *layout, - gdouble initial_width, - gdouble initial_height); -GType eek_keyboard_get_type - (void) G_GNUC_CONST; -void eek_keyboard_get_size - (EekKeyboard *keyboard, - gdouble *width, - gdouble *height); -void eek_keyboard_set_size - (EekKeyboard *keyboard, - gdouble width, - gdouble height); - -EekSection *eek_keyboard_create_section - (EekKeyboard *keyboard); - -EekKey *eek_keyboard_find_key_by_name - (LevelKeyboard *keyboard, +struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard, const gchar *name); +/// Represents the path to the button within a view +struct button_place { + const struct squeek_row *row; + const struct squeek_button *button; +}; + EekOutline *level_keyboard_get_outline (LevelKeyboard *keyboard, guint oref); @@ -168,22 +78,16 @@ EekModifierKey *eek_modifier_key_copy void eek_modifier_key_free (EekModifierKey *modkey); -void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp); -void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp); +void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp); +void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp); gchar * eek_keyboard_get_keymap (LevelKeyboard *keyboard); -EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard); -LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash); +struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard); +LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[], GHashTable *name_button_hash); void level_keyboard_deinit(LevelKeyboard *self); void level_keyboard_free(LevelKeyboard *self); -/* Create an #EekSection instance and append it to @keyboard. This -* function is rarely called by application but called by #EekLayout -* implementation. -*/ -EekSection * -eek_keyboard_real_create_section (EekKeyboard *self); G_END_DECLS #endif /* EEK_KEYBOARD_H */ diff --git a/eek/eek-keysym.c b/eek/eek-keysym.c index 807c8beb..bb55022c 100644 --- a/eek/eek-keysym.c +++ b/eek/eek-keysym.c @@ -51,8 +51,6 @@ struct _EekKeysymEntry { typedef struct _EekKeysymEntry EekKeysymEntry; -#include "eek-special-keysym-entries.h" -#include "eek-unicode-keysym-entries.h" #include "eek-xkeysym-keysym-entries.h" guint32 diff --git a/eek/eek-layout.c b/eek/eek-layout.c index ce84e23c..af27e885 100644 --- a/eek/eek-layout.c +++ b/eek/eek-layout.c @@ -46,7 +46,7 @@ eek_layout_init (EekLayout *self) { } -const double section_spacing = 7.0; +const double row_spacing = 7.0; struct place_data { double desired_width; @@ -56,35 +56,37 @@ struct place_data { }; static void -section_placer(EekElement *element, gpointer user_data) +row_placer(struct squeek_row *row, gpointer user_data) { struct place_data *data = (struct place_data*)user_data; - EekBounds section_bounds = {0}; - eek_element_get_bounds(element, §ion_bounds); - section_bounds.width = data->desired_width; - eek_element_set_bounds(element, §ion_bounds); + EekBounds row_bounds = { + .x = 0, + .y = 0, + .width = data->desired_width, + .height = 0, + }; + squeek_row_set_bounds(row, row_bounds); - // Sections are rows now. Gather up all the keys and adjust their bounds. - eek_section_place_keys(EEK_SECTION(element), data->keyboard); + // Gather up all the keys in a row and adjust their bounds. + squeek_row_place_buttons(row, data->keyboard); - eek_element_get_bounds(element, §ion_bounds); - section_bounds.y = data->current_offset; - eek_element_set_bounds(element, §ion_bounds); - data->current_offset += section_bounds.height + section_spacing; + row_bounds = squeek_row_get_bounds(row); + row_bounds.y = data->current_offset; + squeek_row_set_bounds(row, row_bounds); + data->current_offset += row_bounds.height + row_spacing; } static void -section_counter(EekElement *element, gpointer user_data) { +row_counter(struct squeek_row *row, gpointer user_data) { double *total_height = user_data; - EekBounds section_bounds = {0}; - eek_element_get_bounds(element, §ion_bounds); - *total_height += section_bounds.height + section_spacing; + EekBounds row_bounds = squeek_row_get_bounds(row); + *total_height += row_bounds.height + row_spacing; } void -eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level) +eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level) { /* Order rows */ // This needs to be done after outlines, because outlines define key sizes @@ -92,24 +94,23 @@ eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level) // The keyboard width is given by the user via screen size. The height will be given dynamically. // TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later - EekBounds keyboard_bounds = {0}; - eek_element_get_bounds(EEK_ELEMENT(level), &keyboard_bounds); + EekBounds view_bounds = squeek_view_get_bounds(level); struct place_data placer_data = { - .desired_width = keyboard_bounds.width, + .desired_width = view_bounds.width, .current_offset = 0, .keyboard = keyboard, }; - eek_container_foreach_child(EEK_CONTAINER(level), section_placer, &placer_data); + squeek_view_foreach(level, row_placer, &placer_data); double total_height = 0; - eek_container_foreach_child(EEK_CONTAINER(level), section_counter, &total_height); - keyboard_bounds.height = total_height; - eek_element_set_bounds(EEK_ELEMENT(level), &keyboard_bounds); + squeek_view_foreach(level, row_counter, &total_height); + view_bounds.height = total_height; + squeek_view_set_bounds(level, view_bounds); } void eek_layout_update_layout(LevelKeyboard *keyboard) { - eek_layout_place_sections(keyboard, level_keyboard_current(keyboard)); + eek_layout_place_rows(keyboard, level_keyboard_current(keyboard)); } diff --git a/eek/eek-layout.h b/eek/eek-layout.h index 7ee3195d..83c4976a 100644 --- a/eek/eek-layout.h +++ b/eek/eek-layout.h @@ -27,6 +27,7 @@ #include #include "eek-types.h" +#include "src/layout.h" G_BEGIN_DECLS @@ -55,7 +56,7 @@ struct _EekLayoutClass GType eek_layout_get_type (void) G_GNUC_CONST; -void eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level); +void eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level); void eek_layout_update_layout(LevelKeyboard *keyboard); diff --git a/eek/eek-marshalers.list b/eek/eek-marshalers.list deleted file mode 100644 index 1f953ddf..00000000 --- a/eek/eek-marshalers.list +++ /dev/null @@ -1 +0,0 @@ -VOID:INT,INT diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 85837618..0e96056d 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -24,8 +24,6 @@ #include #include -#include "eek-key.h" -#include "eek-section.h" #include "src/symbol.h" #include "eek-renderer.h" @@ -76,33 +74,32 @@ extern void _eek_rounded_polygon (cairo_t *cr, EekPoint *points, guint num_points); -static void eek_renderer_real_render_key_label (EekRenderer *self, +static void eek_renderer_real_render_button_label (EekRenderer *self, PangoLayout *layout, - EekKey *key, guint level); + const struct squeek_button *button); static void invalidate (EekRenderer *renderer); -static void render_key (EekRenderer *self, - cairo_t *cr, - EekKey *key, guint level, +static void render_button (EekRenderer *self, + cairo_t *cr, struct button_place *place, gboolean active); struct _CreateKeyboardSurfaceCallbackData { cairo_t *cr; EekRenderer *renderer; - uint level; + struct squeek_view *view; + struct squeek_row *row; }; typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData; static void -create_keyboard_surface_key_callback (EekElement *element, +create_keyboard_surface_button_callback (struct squeek_button *button, gpointer user_data) { CreateKeyboardSurfaceCallbackData *data = user_data; - EekBounds bounds; + EekBounds bounds = squeek_button_get_bounds(button); cairo_save (data->cr); - eek_element_get_bounds (element, &bounds); cairo_translate (data->cr, bounds.x, bounds.y); cairo_rectangle (data->cr, 0.0, @@ -110,48 +107,51 @@ create_keyboard_surface_key_callback (EekElement *element, bounds.width + 100, bounds.height + 100); cairo_clip (data->cr); - render_key (data->renderer, data->cr, EEK_KEY(element), data->level, FALSE); + struct button_place place = { + .row = data->row, + .button = button, + }; + render_button (data->renderer, data->cr, &place, FALSE); cairo_restore (data->cr); } static void -create_keyboard_surface_section_callback (EekElement *element, +create_keyboard_surface_row_callback (struct squeek_row *row, gpointer user_data) { CreateKeyboardSurfaceCallbackData *data = user_data; - EekBounds bounds; - gint angle; + + EekBounds bounds = squeek_row_get_bounds(row); cairo_save (data->cr); - - eek_element_get_bounds (element, &bounds); cairo_translate (data->cr, bounds.x, bounds.y); - angle = eek_section_get_angle (EEK_SECTION(element)); + gint angle = squeek_row_get_angle (row); cairo_rotate (data->cr, angle * G_PI / 180); - eek_container_foreach_child (EEK_CONTAINER(element), - create_keyboard_surface_key_callback, + data->row = row; + squeek_row_foreach(row, create_keyboard_surface_button_callback, data); cairo_restore (data->cr); } -void -render_keyboard_surface (EekRenderer *renderer) +static void +render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view) { EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); - EekBounds bounds; - CreateKeyboardSurfaceCallbackData data; EekColor foreground; eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground); - eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds); + EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard)); - data.cr = cairo_create (priv->keyboard_surface); - data.renderer = renderer; + CreateKeyboardSurfaceCallbackData data = { + .cr = cairo_create (priv->keyboard_surface), + .renderer = renderer, + .view = view, + }; /* Paint the background covering the entire widget area */ gtk_render_background (priv->scontext, @@ -173,10 +173,9 @@ render_keyboard_surface (EekRenderer *renderer) foreground.blue, foreground.alpha); - data.level = priv->keyboard->level; - /* draw sections */ - eek_container_foreach_child (EEK_CONTAINER(level_keyboard_current(priv->keyboard)), - create_keyboard_surface_section_callback, + /* draw rows */ + squeek_view_foreach(level_keyboard_current(priv->keyboard), + create_keyboard_surface_row_callback, &data); cairo_restore (data.cr); @@ -184,22 +183,20 @@ render_keyboard_surface (EekRenderer *renderer) } static void -render_key_outline (EekRenderer *renderer, +render_button_outline (EekRenderer *renderer, cairo_t *cr, - EekKey *key, + const struct squeek_button *button, gboolean active) { EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); EekOutline *outline; - EekBounds bounds; - guint oref; - oref = eek_key_get_oref (key); + guint oref = squeek_button_get_oref(button); outline = level_keyboard_get_outline (priv->keyboard, oref); if (outline == NULL) return; - eek_element_get_bounds(EEK_ELEMENT(key), &bounds); + EekBounds bounds = squeek_button_get_bounds(button); gtk_style_context_set_state(priv->key_context, active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL); @@ -212,30 +209,26 @@ render_key_outline (EekRenderer *renderer, } static void -render_key (EekRenderer *self, +render_button (EekRenderer *self, cairo_t *cr, - EekKey *key, - guint level, + struct button_place *place, gboolean active) { EekRendererPrivate *priv = eek_renderer_get_instance_private (self); EekOutline *outline; cairo_surface_t *outline_surface; - EekBounds bounds; - guint oref; - struct squeek_symbol *symbol; GHashTable *outline_surface_cache; PangoLayout *layout; PangoRectangle extents = { 0, }; EekColor foreground; - oref = eek_key_get_oref (key); + guint oref = squeek_button_get_oref (place->button); outline = level_keyboard_get_outline (priv->keyboard, oref); if (outline == NULL) return; /* render outline */ - eek_element_get_bounds (EEK_ELEMENT(key), &bounds); + EekBounds bounds = squeek_button_get_bounds(place->button); if (active) outline_surface_cache = priv->active_outline_surface_cache; @@ -259,8 +252,8 @@ render_key (EekRenderer *self, cairo_paint (cr); cairo_save (cr); - eek_renderer_apply_transformation_for_key (self, cr, key, 1.0, FALSE); - render_key_outline (self, cr, key, active); + eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE); + render_button_outline (self, cr, place->button, active); cairo_restore (cr); cairo_destroy (cr); @@ -275,7 +268,7 @@ render_key (EekRenderer *self, eek_renderer_get_foreground_color (self, priv->key_context, &foreground); /* render icon (if any) */ - symbol = eek_key_get_symbol_at_index (key, 0, level); + struct squeek_symbol *symbol = squeek_button_get_symbol(place->button); if (!symbol) return; @@ -311,7 +304,7 @@ render_key (EekRenderer *self, /* render label */ layout = pango_cairo_create_layout (cr); - eek_renderer_real_render_key_label (self, layout, key, level); + eek_renderer_real_render_button_label (self, layout, place->button); pango_layout_get_extents (layout, NULL, &extents); cairo_save (cr); @@ -347,22 +340,19 @@ render_key (EekRenderer *self, * normal keys for popups. */ void -eek_renderer_apply_transformation_for_key (EekRenderer *self, +eek_renderer_apply_transformation_for_button (EekRenderer *self, cairo_t *cr, - EekKey *key, + struct button_place *place, gdouble scale, gboolean rotate) { - EekElement *section; EekBounds bounds, rotated_bounds; - gint angle; gdouble s; - eek_renderer_get_key_bounds (self, key, &bounds, FALSE); - eek_renderer_get_key_bounds (self, key, &rotated_bounds, TRUE); + eek_renderer_get_button_bounds (self, place, &bounds, FALSE); + eek_renderer_get_button_bounds (self, place, &rotated_bounds, TRUE); - section = eek_element_get_parent (EEK_ELEMENT(key)); - angle = eek_section_get_angle (EEK_SECTION(section)); + gint angle = squeek_row_get_angle (place->row); cairo_scale (cr, scale, scale); if (rotate) { @@ -376,20 +366,18 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self, } static void -eek_renderer_real_render_key_label (EekRenderer *self, +eek_renderer_real_render_button_label (EekRenderer *self, PangoLayout *layout, - EekKey *key, - guint level) + const struct squeek_button *button) { EekRendererPrivate *priv = eek_renderer_get_instance_private (self); - struct squeek_symbol *symbol; + const gchar *label; - EekBounds bounds; PangoFontDescription *font; PangoLayoutLine *line; gdouble scale; - symbol = eek_key_get_symbol_at_index(key, 0, level); + struct squeek_symbol *symbol = squeek_button_get_symbol(button); if (!symbol) return; @@ -414,7 +402,7 @@ eek_renderer_real_render_key_label (EekRenderer *self, pango_font_description_set_size (priv->font, (gint)round(size * 0.6)); } - eek_element_get_bounds (EEK_ELEMENT(key), &bounds); + EekBounds bounds = squeek_button_get_bounds(button); scale = MIN((bounds.width - priv->border_width) / bounds.width, (bounds.height - priv->border_width) / bounds.height); @@ -432,19 +420,6 @@ eek_renderer_real_render_key_label (EekRenderer *self, PANGO_SCALE * bounds.width * scale); } -static void -eek_renderer_real_render_key_outline (EekRenderer *self, - cairo_t *cr, - EekKey *key, - gdouble scale, - gboolean rotate) -{ - cairo_save (cr); - eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate); - render_key_outline (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key)); - cairo_restore (cr); -} - /* * eek_renderer_real_render_key: * @self: The renderer used to render the key @@ -457,17 +432,16 @@ eek_renderer_real_render_key_outline (EekRenderer *self, * Renders a key separately from the normal keyboard rendering. */ static void -eek_renderer_real_render_key (EekRenderer *self, +eek_renderer_real_render_button (EekRenderer *self, cairo_t *cr, - EekKey *key, - guint level, + struct button_place *place, gdouble scale, gboolean rotate) { EekRendererPrivate *priv = eek_renderer_get_instance_private (self); EekBounds bounds; - eek_renderer_get_key_bounds (self, key, &bounds, rotate); + eek_renderer_get_button_bounds (self, place, &bounds, rotate); cairo_save (cr); /* Because this function is called separately from the keyboard rendering @@ -476,8 +450,12 @@ eek_renderer_real_render_key (EekRenderer *self, cairo_scale (cr, priv->scale, priv->scale); cairo_translate (cr, bounds.x, bounds.y); - eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate); - render_key (self, cr, key, level, eek_key_is_pressed (key) || eek_key_is_locked (key)); + eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate); + struct squeek_key *key = squeek_button_get_key(place->button); + render_button ( + self, cr, place, + squeek_key_is_pressed(key) || squeek_key_is_locked (key) + ); cairo_restore (cr); } @@ -503,7 +481,7 @@ eek_renderer_real_render_keyboard (EekRenderer *self, cairo_get_target (cr), 0, 0, priv->allocation_width, priv->allocation_height); - render_keyboard_surface (self); + render_keyboard_surface (self, priv->keyboard->views[priv->keyboard->level]); cairo_set_source_surface (cr, priv->keyboard_surface, 0.0, 0.0); source = cairo_get_source (cr); @@ -591,8 +569,7 @@ eek_renderer_class_init (EekRendererClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; - klass->render_key_outline = eek_renderer_real_render_key_outline; - klass->render_key = eek_renderer_real_render_key; + klass->render_button = eek_renderer_real_render_button; klass->render_keyboard = eek_renderer_real_render_keyboard; gobject_class->set_property = eek_renderer_set_property; @@ -709,7 +686,6 @@ eek_renderer_set_allocation_size (EekRenderer *renderer, gdouble width, gdouble height) { - EekBounds bounds; gdouble scale; g_return_if_fail (EEK_IS_RENDERER(renderer)); @@ -722,7 +698,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer, /* Calculate a scale factor to use when rendering the keyboard into the available space. */ - eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds); + EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard)); gdouble w = (bounds.x * 2) + bounds.width; gdouble h = (bounds.y * 2) + bounds.height; @@ -741,13 +717,11 @@ eek_renderer_get_size (EekRenderer *renderer, gdouble *width, gdouble *height) { - EekBounds bounds; - g_return_if_fail (EEK_IS_RENDERER(renderer)); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); - eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds); + EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard)); if (width) *width = bounds.width; if (height) @@ -755,45 +729,42 @@ eek_renderer_get_size (EekRenderer *renderer, } void -eek_renderer_get_key_bounds (EekRenderer *renderer, - EekKey *key, +eek_renderer_get_button_bounds (EekRenderer *renderer, + struct button_place *place, EekBounds *bounds, gboolean rotate) { - EekElement *section; - EekBounds section_bounds, keyboard_bounds; gint angle = 0; EekPoint points[4], min, max; g_return_if_fail (EEK_IS_RENDERER(renderer)); - g_return_if_fail (EEK_IS_KEY(key)); + g_return_if_fail (place); g_return_if_fail (bounds != NULL); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); - section = eek_element_get_parent (EEK_ELEMENT(key)); - - eek_element_get_bounds (EEK_ELEMENT(key), bounds); - eek_element_get_bounds (section, §ion_bounds); - eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), - &keyboard_bounds); + EekBounds button_bounds = squeek_button_get_bounds(place->button); + EekBounds row_bounds = squeek_row_get_bounds (place->row); + EekBounds view_bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard)); if (!rotate) { - bounds->x += keyboard_bounds.x + section_bounds.x; - bounds->y += keyboard_bounds.y + section_bounds.y; + button_bounds.x += view_bounds.x + row_bounds.x; + button_bounds.y += view_bounds.y + row_bounds.y; + *bounds = button_bounds; return; } - points[0].x = bounds->x; - points[0].y = bounds->y; - points[1].x = points[0].x + bounds->width; + points[0].x = button_bounds.x; + points[0].y = button_bounds.y; + points[1].x = points[0].x + button_bounds.width; points[1].y = points[0].y; points[2].x = points[1].x; - points[2].y = points[1].y + bounds->height; + points[2].y = points[1].y + button_bounds.height; points[3].x = points[0].x; points[3].y = points[2].y; - if (rotate) - angle = eek_section_get_angle (EEK_SECTION(section)); + if (rotate) { + angle = squeek_row_get_angle (place->row); + } min = points[2]; max = points[0]; @@ -808,8 +779,8 @@ eek_renderer_get_key_bounds (EekRenderer *renderer, if (points[i].y > max.y) max.y = points[i].y; } - bounds->x = keyboard_bounds.x + section_bounds.x + min.x; - bounds->y = keyboard_bounds.y + section_bounds.y + min.y; + bounds->x = view_bounds.x + row_bounds.x + min.x; + bounds->y = view_bounds.y + row_bounds.y + min.y; bounds->width = (max.x - min.x); bounds->height = (max.y - min.y); } @@ -843,24 +814,6 @@ eek_renderer_create_pango_layout (EekRenderer *renderer) return pango_layout_new (priv->pcontext); } -void -eek_renderer_render_key_outline (EekRenderer *renderer, - cairo_t *cr, - EekKey *key, - gdouble scale, - gboolean rotate) -{ - g_return_if_fail (EEK_IS_RENDERER(renderer)); - g_return_if_fail (EEK_IS_KEY(key)); - g_return_if_fail (scale >= 0.0); - - EEK_RENDERER_GET_CLASS(renderer)->render_key_outline (renderer, - cr, - key, - scale, - rotate); -} - cairo_surface_t * eek_renderer_get_icon_surface (EekRenderer *renderer, const gchar *icon_name, @@ -896,19 +849,18 @@ eek_renderer_get_icon_surface (EekRenderer *renderer, } void -eek_renderer_render_key (EekRenderer *renderer, +eek_renderer_render_button (EekRenderer *renderer, cairo_t *cr, - EekKey *key, - guint level, + struct button_place *place, gdouble scale, gboolean rotate) { g_return_if_fail (EEK_IS_RENDERER(renderer)); - g_return_if_fail (EEK_IS_KEY(key)); + g_return_if_fail (place); g_return_if_fail (scale >= 0.0); EEK_RENDERER_GET_CLASS(renderer)-> - render_key (renderer, cr, key, level, scale, rotate); + render_button (renderer, cr, place, scale, rotate); } void @@ -965,8 +917,7 @@ struct _FindKeyByPositionCallbackData { EekPoint point; EekPoint origin; gint angle; - EekKey *key; - EekRenderer *renderer; + struct squeek_button *button; }; typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData; @@ -978,17 +929,12 @@ sign (EekPoint *p1, EekPoint *p2, EekPoint *p3) (p2->x - p3->x) * (p1->y - p3->y); } -static gint -find_key_by_position_key_callback (EekElement *element, - gpointer user_data) +uint32_t +eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_t angle) { - FindKeyByPositionCallbackData *data = user_data; - EekBounds bounds; EekPoint points[4]; gboolean b1, b2, b3; - eek_element_get_bounds (element, &bounds); - points[0].x = bounds.x; points[0].y = bounds.y; points[1].x = points[0].x + bounds.width; @@ -999,51 +945,38 @@ find_key_by_position_key_callback (EekElement *element, points[3].y = points[2].y; for (uint i = 0; i < G_N_ELEMENTS(points); i++) { - eek_point_rotate (&points[i], data->angle); - points[i].x += data->origin.x; - points[i].y += data->origin.y; + eek_point_rotate (&points[i], angle); + points[i].x += origin.x; + points[i].y += origin.y; } - b1 = sign (&data->point, &points[0], &points[1]) < 0.0; - b2 = sign (&data->point, &points[1], &points[2]) < 0.0; - b3 = sign (&data->point, &points[2], &points[0]) < 0.0; + b1 = sign (&point, &points[0], &points[1]) < 0.0; + b2 = sign (&point, &points[1], &points[2]) < 0.0; + b3 = sign (&point, &points[2], &points[0]) < 0.0; if (b1 == b2 && b2 == b3) { - data->key = EEK_KEY(element); - return 0; + return 1; } - b1 = sign (&data->point, &points[2], &points[3]) < 0.0; - b2 = sign (&data->point, &points[3], &points[0]) < 0.0; - b3 = sign (&data->point, &points[0], &points[2]) < 0.0; + b1 = sign (&point, &points[2], &points[3]) < 0.0; + b2 = sign (&point, &points[3], &points[0]) < 0.0; + b3 = sign (&point, &points[0], &points[2]) < 0.0; if (b1 == b2 && b2 == b3) { - data->key = EEK_KEY(element); - return 0; + return 1; } - - return -1; + return 0; } -static gint -find_key_by_position_section_callback (EekElement *element, +static void +find_button_by_position_row_callback (struct squeek_row *row, gpointer user_data) { FindKeyByPositionCallbackData *data = user_data; - EekBounds bounds; - EekPoint origin; - - origin = data->origin; - eek_element_get_bounds (element, &bounds); - data->origin.x += bounds.x; - data->origin.y += bounds.y; - data->angle = eek_section_get_angle (EEK_SECTION(element)); - - eek_container_find (EEK_CONTAINER(element), - find_key_by_position_key_callback, - data); - data->origin = origin; - return data->key ? 0 : -1; + if (data->button) { + return; + } + data->button = squeek_row_find_button_by_position(row, data->point, data->origin); } /** @@ -1055,18 +988,18 @@ find_key_by_position_section_callback (EekElement *element, * Return value: the key located at the position x, y in widget coordinates, or * NULL if no key can be found at that location **/ -EekKey * -eek_renderer_find_key_by_position (EekRenderer *renderer, +struct squeek_button * +eek_renderer_find_button_by_position (EekRenderer *renderer, + struct squeek_view *view, gdouble x, gdouble y) { - EekBounds bounds; FindKeyByPositionCallbackData data; g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL); EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); - eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds); + EekBounds bounds = squeek_view_get_bounds (view); /* Transform from widget coordinates to keyboard coordinates */ x = (x - priv->origin_x)/priv->scale - bounds.x; @@ -1082,11 +1015,9 @@ eek_renderer_find_key_by_position (EekRenderer *renderer, data.point.y = y; data.origin.x = 0; data.origin.y = 0; - data.key = NULL; - data.renderer = renderer; + data.button = NULL; - eek_container_find (EEK_CONTAINER(level_keyboard_current(priv->keyboard)), - find_key_by_position_section_callback, + squeek_view_foreach (view, find_button_by_position_row_callback, &data); - return data.key; + return data.button; } diff --git a/eek/eek-renderer.h b/eek/eek-renderer.h index fda2ffad..4a72e763 100644 --- a/eek/eek-renderer.h +++ b/eek/eek-renderer.h @@ -36,16 +36,9 @@ struct _EekRendererClass { GObjectClass parent_class; - void (* render_key_outline) (EekRenderer *self, + void (* render_button) (EekRenderer *self, cairo_t *cr, - EekKey *key, - gdouble scale, - gboolean rotate); - - void (* render_key) (EekRenderer *self, - cairo_t *cr, - EekKey *key, - guint level, + struct button_place *place, gdouble scale, gboolean rotate); @@ -73,8 +66,8 @@ void eek_renderer_set_allocation_size void eek_renderer_get_size (EekRenderer *renderer, gdouble *width, gdouble *height); -void eek_renderer_get_key_bounds (EekRenderer *renderer, - EekKey *key, +void eek_renderer_get_button_bounds (EekRenderer *renderer, + struct button_place *button, EekBounds *bounds, gboolean rotate); @@ -84,20 +77,9 @@ void eek_renderer_set_scale_factor (EekRenderer *renderer, PangoLayout *eek_renderer_create_pango_layout (EekRenderer *renderer); -void eek_renderer_render_key_label (EekRenderer *renderer, - PangoLayout *layout, - EekKey *key); - -void eek_renderer_render_key_outline - (EekRenderer *renderer, +void eek_renderer_render_button (EekRenderer *renderer, cairo_t *cr, - EekKey *key, - gdouble scale, - gboolean rotate); - -void eek_renderer_render_key (EekRenderer *renderer, - cairo_t *cr, - EekKey *key, guint level, + struct button_place *place, gdouble scale, gboolean rotate); @@ -121,14 +103,12 @@ void eek_renderer_get_foreground_color EekColor *color); void eek_renderer_set_border_width (EekRenderer *renderer, gdouble border_width); -EekKey *eek_renderer_find_key_by_position - (EekRenderer *renderer, +struct squeek_button *eek_renderer_find_button_by_position(EekRenderer *renderer, struct squeek_view *view, gdouble x, gdouble y); -void eek_renderer_apply_transformation_for_key +void eek_renderer_apply_transformation_for_button (EekRenderer *renderer, - cairo_t *cr, - EekKey *key, + cairo_t *cr, struct button_place *place, gdouble scale, gboolean rotate); diff --git a/eek/eek-section.c b/eek/eek-section.c index ee12f48b..d1dcf951 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -18,416 +18,11 @@ * 02110-1301 USA */ -/** - * SECTION:eek-section - * @short_description: Base class of a section - * @see_also: #EekKey - * - * The #EekSectionClass class represents a section, which consists - * of one or more keys of the #EekKeyClass class. - */ - #include "config.h" -#include - -#include "eek-keyboard.h" -#include "eek-key.h" - #include "eek-section.h" -enum { - PROP_0, - PROP_ANGLE, - PROP_LAST -}; - -enum { - KEY_LOCKED, - KEY_UNLOCKED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -struct _EekRow -{ - gint num_columns; - EekOrientation orientation; -}; - -typedef struct _EekRow EekRow; - -typedef struct _EekSectionPrivate -{ - gint angle; - EekRow row; - EekModifierType modifiers; -} EekSectionPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER) - -static gint -eek_section_real_get_n_rows (EekSection *self) -{ -return 1; -} - -static void -eek_section_real_add_row (EekSection *self, - gint num_columns, - EekOrientation orientation) -{ - EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self); - priv->row.num_columns = num_columns; - priv->row.orientation = orientation; -/* - row = g_slice_new (EekRow); - row->num_columns = num_columns; - row->orientation = orientation; - priv->rows = g_slist_append (priv->rows, row);*/ -} - -static void -eek_section_real_get_row (EekSection *self, - gint index, - gint *num_columns, - EekOrientation *orientation) -{ - EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self); - EekRow *row = &priv->row; - if (num_columns) { - *num_columns = row->num_columns; - } - if (orientation) { - *orientation = row->orientation; - } -} - -static void -on_locked (EekKey *key, - EekSection *section) -{ - g_signal_emit (section, signals[KEY_LOCKED], 0, key); -} - -static void -on_unlocked (EekKey *key, - EekSection *section) -{ - g_signal_emit (section, signals[KEY_UNLOCKED], 0, key); -} - -static EekKey * -eek_section_real_create_key (EekSection *self, - const gchar *name, - gint keycode, - guint oref) -{ - EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self); - - EekRow *row = &priv->row; - row->num_columns++; - - EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY, - "name", name, - NULL); - g_return_val_if_fail (key, NULL); - eek_key_set_keycode(key, keycode); - eek_key_set_oref(key, oref); - - EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), - EEK_ELEMENT(key)); - - return key; -} - -EekKey *eek_section_create_button(EekSection *self, - const gchar *name, - struct squeek_key *state) { - EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self); - - EekRow *row = &priv->row; - row->num_columns++; - - EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY, - "name", name, - NULL); - g_return_val_if_fail (key, NULL); - eek_key_share_state(key, state); - - EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), - EEK_ELEMENT(key)); - return key; -} - -static void -eek_section_finalize (GObject *object) -{ - G_OBJECT_CLASS (eek_section_parent_class)->finalize (object); -} - -static void -eek_section_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_ANGLE: - eek_section_set_angle (EEK_SECTION(object), - g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eek_section_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_ANGLE: - g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -eek_section_real_child_added (EekContainer *self, - EekElement *element) -{ - g_signal_connect (element, "locked", G_CALLBACK(on_locked), self); - g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self); -} - -static void -eek_section_real_child_removed (EekContainer *self, - EekElement *element) -{ - g_signal_handlers_disconnect_by_func (element, on_locked, self); - g_signal_handlers_disconnect_by_func (element, on_unlocked, self); -} - -static void -eek_section_class_init (EekSectionClass *klass) -{ - EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - klass->get_n_rows = eek_section_real_get_n_rows; - klass->add_row = eek_section_real_add_row; - klass->get_row = eek_section_real_get_row; - klass->create_key = eek_section_real_create_key; - - /* signals */ - container_class->child_added = eek_section_real_child_added; - container_class->child_removed = eek_section_real_child_removed; - - gobject_class->set_property = eek_section_set_property; - gobject_class->get_property = eek_section_get_property; - gobject_class->finalize = eek_section_finalize; - - /** - * EekSection:angle: - * - * The rotation angle of #EekSection. - */ - pspec = g_param_spec_int ("angle", - "Angle", - "Rotation angle of the section", - -360, 360, 0, - G_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_ANGLE, - pspec); - - /** - * EekSection::key-locked: - * @section: an #EekSection - * @key: an #EekKey - * - * The ::key-locked signal is emitted each time a key in @section - * is shifted to the locked state. - */ - signals[KEY_LOCKED] = - g_signal_new (I_("key-locked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekSectionClass, key_locked), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EEK_TYPE_KEY); - - /** - * EekSection::key-unlocked: - * @section: an #EekSection - * @key: an #EekKey - * - * The ::key-unlocked signal is emitted each time a key in @section - * is shifted to the unlocked state. - */ - signals[KEY_UNLOCKED] = - g_signal_new (I_("key-unlocked"), - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EekSectionClass, key_unlocked), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - EEK_TYPE_KEY); -} - -static void -eek_section_init (EekSection *self) -{ - /* void */ -} - -/** - * eek_section_set_angle: - * @section: an #EekSection - * @angle: rotation angle - * - * Set rotation angle of @section to @angle. - */ -void -eek_section_set_angle (EekSection *section, - gint angle) -{ - g_return_if_fail (EEK_IS_SECTION(section)); - - EekSectionPrivate *priv = eek_section_get_instance_private (section); - - if (priv->angle != angle) { - priv->angle = angle; - g_object_notify (G_OBJECT(section), "angle"); - } -} - -/** - * eek_section_get_angle: - * @section: an #EekSection - * - * Get rotation angle of @section. - */ -gint -eek_section_get_angle (EekSection *section) -{ - g_return_val_if_fail (EEK_IS_SECTION(section), -1); - - EekSectionPrivate *priv = eek_section_get_instance_private (section); - - return priv->angle; -} - -/** - * eek_section_get_n_rows: - * @section: an #EekSection - * - * Get the number of rows in @section. - */ -gint -eek_section_get_n_rows (EekSection *section) -{ - g_return_val_if_fail (EEK_IS_SECTION(section), -1); - return EEK_SECTION_GET_CLASS(section)->get_n_rows (section); -} - -/** - * eek_section_add_row: - * @section: an #EekSection - * @num_columns: the number of column in the row - * @orientation: #EekOrientation of the row - * - * Add a row which has @num_columns columns and whose orientation is - * @orientation to @section. - */ -void -eek_section_add_row (EekSection *section, - gint num_columns, - EekOrientation orientation) -{ - g_return_if_fail (EEK_IS_SECTION(section)); - EEK_SECTION_GET_CLASS(section)->add_row (section, - num_columns, - orientation); -} - -/** - * eek_section_get_row: - * @section: an #EekSection - * @index: the index of row - * @num_columns: pointer where the number of column in the row will be stored - * @orientation: pointer where #EekOrientation of the row will be stored - * - * Get the information about the @index-th row in @section. - */ -void -eek_section_get_row (EekSection *section, - gint index, - gint *num_columns, - EekOrientation *orientation) -{ - g_return_if_fail (EEK_IS_SECTION(section)); - EEK_SECTION_GET_CLASS(section)->get_row (section, - index, - num_columns, - orientation); -} - -/** - * eek_section_create_key: - * @section: an #EekSection - * @name: a name - * @keycode: a keycode - * @column: the column index of the key - * @row: the row index of the key - * - * Create an #EekKey instance and append it to @section. This - * function is rarely called by application but called by #EekLayout - * implementation. - */ -EekKey * -eek_section_create_key (EekSection *section, - const gchar *name, - guint keycode, - guint oref) -{ - g_return_val_if_fail (EEK_IS_SECTION(section), NULL); - return eek_section_real_create_key (section, - name, - keycode, oref); -} - -const double keyspacing = 4.0; - -struct keys_info { - uint count; - double total_width; - double biggest_height; -}; - -static void -keysizer(EekElement *element, gpointer user_data) -{ - EekKey *key = EEK_KEY(element); - - LevelKeyboard *keyboard = user_data; - uint oref = eek_key_get_oref (key); +EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) { EekOutline *outline = level_keyboard_get_outline (keyboard, oref); if (outline && outline->num_points > 0) { double minx = outline->points[0].x; @@ -448,52 +43,14 @@ keysizer(EekElement *element, gpointer user_data) maxy = p.y; } } - EekBounds key_bounds = {0}; - eek_element_get_bounds(element, &key_bounds); - key_bounds.height = maxy - miny; - key_bounds.width = maxx - minx; - eek_element_set_bounds(element, &key_bounds); + EekBounds key_bounds = { + .height = maxy - miny, + .width = maxx - minx, + .x = 0, + .y = 0, + }; + return key_bounds; } -} - -static void -keycounter (EekElement *element, gpointer user_data) -{ - struct keys_info *data = user_data; - data->count++; - EekBounds key_bounds = {0}; - eek_element_get_bounds(element, &key_bounds); - data->total_width += key_bounds.width; - if (key_bounds.height > data->biggest_height) { - data->biggest_height = key_bounds.height; - } -} - -static void -keyplacer(EekElement *element, gpointer user_data) -{ - double *current_offset = user_data; - EekBounds key_bounds = {0}; - eek_element_get_bounds(element, &key_bounds); - key_bounds.x = *current_offset; - key_bounds.y = 0; - eek_element_set_bounds(element, &key_bounds); - *current_offset += key_bounds.width + keyspacing; -} - -void -eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard) -{ - eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard); - - struct keys_info keyinfo = {0}; - eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo); - EekBounds section_bounds = {0}; - eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds); - - double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2; - eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset); - - section_bounds.height = keyinfo.biggest_height; - eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds); + EekBounds bounds = {0, 0, 0, 0}; + return bounds; } diff --git a/eek/eek-section.h b/eek/eek-section.h index 03166e6a..8d9076c7 100644 --- a/eek/eek-section.h +++ b/eek/eek-section.h @@ -25,84 +25,10 @@ #ifndef EEK_SECTION_H #define EEK_SECTION_H 1 +/* Contains row-related functions that couldn't be done in Rust easily. */ + #include -#include "eek-container.h" -#include "eek-types.h" #include "eek-keyboard.h" -#include "src/keyboard.h" +#include "src/layout.h" -G_BEGIN_DECLS - -#define EEK_TYPE_SECTION (eek_section_get_type()) -G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer) - -/** - * EekSectionClass: - * @get_n_rows: virtual function for getting the number of rows in 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 - * @create_key: virtual function for creating key in the section - * @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 - * @key_unlocked: class handler for #EekSection::key-unlocked signal - * @key_cancelled: class handler for #EekSection::key-cancelled signal - */ -struct _EekSectionClass -{ - /*< private >*/ - EekContainerClass parent_class; - - /*< public >*/ - gint (* get_n_rows) (EekSection *self); - void (* add_row) (EekSection *self, - gint num_columns, - EekOrientation orientation); - void (* get_row) (EekSection *self, - gint index, - gint *num_columns, - EekOrientation *orientation); - - EekKey *(* create_key) (EekSection *self, - const gchar *name, - gint keycode, - guint oref); - - /* signals */ - void (* key_locked) (EekSection *self, - EekKey *key); - void (* key_unlocked) (EekSection *self, - EekKey *key); - void (* key_cancelled) (EekSection *self, - EekKey *key); - - /*< private >*/ - /* padding */ - gpointer pdummy[19]; -}; - -GType eek_section_get_type (void) G_GNUC_CONST; - -void eek_section_set_angle (EekSection *section, - gint angle); -gint eek_section_get_angle (EekSection *section); - -gint eek_section_get_n_rows (EekSection *section); -void eek_section_add_row (EekSection *section, - gint num_columns, - EekOrientation orientation); -void eek_section_get_row (EekSection *section, - gint index, - gint *num_columns, - EekOrientation *orientation); - -EekKey *eek_section_create_key (EekSection *section, - const gchar *name, - guint keycode, guint oref); -EekKey *eek_section_create_button(EekSection *self, - const gchar *name, - struct squeek_key *state); -void eek_section_place_keys (EekSection *section, LevelKeyboard *keyboard); - -G_END_DECLS #endif /* EEK_SECTION_H */ diff --git a/eek/eek-serializable.c b/eek/eek-serializable.c deleted file mode 100644 index fed00ae0..00000000 --- a/eek/eek-serializable.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008-2010 Peng Huang - * Copyright (C) 2008-2010 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:eek-serializable - * @short_description: Interface which provides object serialization - * into #GVariant - * - * The #EekSerializableIface interface defines serialize/deserialize - * method. - */ - -#include "config.h" - -#include "eek-serializable.h" - -GType -eek_serializable_get_type (void) -{ - static GType iface_type = 0; - if (iface_type == 0) { - static GTypeInfo info = { - .class_size = sizeof (EekSerializableIface) - }; - iface_type = g_type_register_static (G_TYPE_INTERFACE, - "EekSerializable", - &info, 0); - } - return iface_type; -} - -GVariant * -eek_serializable_serialize (EekSerializable *object) -{ - GVariantBuilder builder; - - g_return_val_if_fail (EEK_IS_SERIALIZABLE (object), FALSE); - - g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); - g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object))); - EEK_SERIALIZABLE_GET_IFACE (object)->serialize (object, &builder); - - return g_variant_builder_end (&builder); -} - -EekSerializable * -eek_serializable_deserialize (GVariant *variant) -{ - gchar *type_name = NULL; - GType type; - EekSerializable *object; - gsize index = 0; - - g_return_val_if_fail (variant != NULL, NULL); - - g_variant_get_child (variant, index++, "&s", &type_name); - type = g_type_from_name (type_name); - - g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL); - - object = g_object_new (type, NULL); - - index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object, - variant, - index); - if (index < 0) { - g_object_unref (object); - g_return_val_if_reached (NULL); - } - - return object; -} diff --git a/eek/eek-serializable.h b/eek/eek-serializable.h deleted file mode 100644 index 20950ce4..00000000 --- a/eek/eek-serializable.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011 Daiki Ueno - * Copyright (C) 2011 Red Hat, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef EEK_SERIALIZABLE_H -#define EEK_SERIALIZABLE_H 1 - -#include - -G_BEGIN_DECLS - -#define EEK_TYPE_SERIALIZABLE (eek_serializable_get_type()) -#define EEK_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SERIALIZABLE, EekSerializable)) -#define EEK_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SERIALIZABLE)) -#define EEK_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SERIALIZABLE, EekSerializableIface)) - -typedef struct _EekSerializable EekSerializable; -typedef struct _EekSerializableIface EekSerializableIface; - -/** - * EekSerializableIface: - * - * @serialize: virtual function for serializing object into #GVariant - * @deserialize: virtual function for deserializing object from #GVariant - */ -struct _EekSerializableIface -{ - /*< private >*/ - GTypeInterface parent_iface; - - void (* serialize) (EekSerializable *object, - GVariantBuilder *builder); - gsize (* deserialize) (EekSerializable *object, - GVariant *variant, - gsize index); - - /*< private >*/ - /* padding */ - gpointer pdummy[24]; -}; - -GType eek_serializable_get_type (void); - -GVariant *eek_serializable_serialize (EekSerializable *object); -EekSerializable *eek_serializable_deserialize (GVariant *variant); - -G_END_DECLS -#endif /* EEK_SERIALIZABLE_H */ diff --git a/eek/eek-text.c b/eek/eek-text.c deleted file mode 100644 index f92742fd..00000000 --- a/eek/eek-text.c +++ /dev/null @@ -1,43 +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 - */ - -/** - * SECTION:eek-text - * @short_description: an #EekText represents a text symbol - */ - -#include "config.h" - -#include "eek-text.h" - -EekSymbol * -eek_text_new (const gchar *text) -{ - EekSymbol *ret = eek_symbol_new(""); - eek_symbol_set_label(ret, text); - ret->text = g_strdup (text); - return ret; -} - -const gchar * -eek_text_get_text (EekSymbol *text) -{ - return text->text; -} diff --git a/eek/eek-text.h b/eek/eek-text.h deleted file mode 100644 index ca4f0940..00000000 --- a/eek/eek-text.h +++ /dev/null @@ -1,38 +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 - */ - -#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef EEK_TEXT_H -#define EEK_TEXT_H 1 - -#include "eek-symbol.h" - -G_BEGIN_DECLS - -GType eek_text_get_type (void) G_GNUC_CONST; -EekSymbol *eek_text_new (const gchar *text); -const gchar *eek_text_get_text (EekSymbol *text); - -G_END_DECLS - -#endif /* EEK_TEXT_H */ diff --git a/eek/eek-types.h b/eek/eek-types.h index 51df26a0..1d37dfc2 100644 --- a/eek/eek-types.h +++ b/eek/eek-types.h @@ -134,10 +134,6 @@ typedef enum #define EEK_INVALID_KEYCODE (0) typedef struct _EekElement EekElement; -typedef struct _EekContainer EekContainer; -typedef struct _EekKey EekKey; -typedef struct _EekSection EekSection; -typedef struct _EekKeyboard EekKeyboard; typedef struct _EekSymbol EekSymbol; typedef struct _EekText EekText; typedef struct _EekTheme EekTheme; @@ -195,12 +191,6 @@ GType eek_bounds_get_type (void) G_GNUC_CONST; EekBounds *eek_bounds_copy (const EekBounds *bounds); void eek_bounds_free (EekBounds *bounds); -G_INLINE_FUNC gdouble -eek_bounds_long_side (EekBounds *bounds) -{ - return bounds->width > bounds->height ? bounds->width : bounds->height; -} - /** * EekOutline: * @corner_radius: radius of corners of rounded polygon diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index 8dc269cc..5dacce55 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -28,8 +28,6 @@ #include #include "eek-keyboard.h" -#include "eek-section.h" -#include "eek-key.h" #include "src/keyboard.h" #include "src/symbol.h" @@ -68,7 +66,7 @@ static GList *parse_prerequisites (const gchar *path, GError **error); static gboolean parse_geometry (const gchar *path, - EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, + struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash, GError **error); static gboolean parse_symbols_with_prerequisites (const gchar *keyboards_dir, @@ -233,10 +231,9 @@ struct _GeometryParseData { GSList *element_stack; EekBounds bounds; - EekKeyboard **views; + struct squeek_view **views; guint view_idx; - EekSection *section; - EekKey *key; + struct squeek_row *row; gint num_rows; EekOrientation orientation; gdouble corner_radius; @@ -250,14 +247,14 @@ struct _GeometryParseData { GArray *outline_array; - GHashTable *name_key_hash; // char* -> EekKey* + GHashTable *name_button_hash; // char* -> struct squeek_button* GHashTable *keyname_oref_hash; // char* -> guint GHashTable *outlineid_oref_hash; // char* -> guint }; typedef struct _GeometryParseData GeometryParseData; static GeometryParseData * -geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray *outline_array) +geometry_parse_data_new (struct squeek_view **views, GHashTable *name_button_hash, GArray *outline_array) { GeometryParseData *data = g_slice_new0 (GeometryParseData); @@ -274,7 +271,7 @@ geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray g_free, NULL); - data->name_key_hash = name_key_hash; + data->name_button_hash = name_button_hash; data->text = g_string_sized_new (BUFSIZE); data->keycode = 8; return data; @@ -370,24 +367,18 @@ geometry_start_element_callback (GMarkupParseContext *pcontext, if (g_strcmp0 (element_name, "view") == 0) { /* Create an empty keyboard to which geometry and symbols information are applied. */ - EekKeyboard *view = g_object_new (EEK_TYPE_KEYBOARD, NULL); - eek_element_set_bounds (EEK_ELEMENT(view), &data->bounds); + struct squeek_view *view = squeek_view_new(data->bounds); data->views[data->view_idx] = view; } if (g_strcmp0 (element_name, "section") == 0) { - data->section = eek_keyboard_real_create_section (data->views[data->view_idx]); - attribute = get_attribute (attribute_names, attribute_values, - "id"); - if (attribute != NULL) - eek_element_set_name (EEK_ELEMENT(data->section), attribute); + gint angle = 0; attribute = get_attribute (attribute_names, attribute_values, "angle"); if (attribute != NULL) { - gint angle; angle = strtol (attribute, NULL, 10); - eek_section_set_angle (data->section, angle); } + data->row = squeek_view_create_row(data->views[data->view_idx], angle); goto out; } @@ -418,15 +409,16 @@ geometry_start_element_callback (GMarkupParseContext *pcontext, g_strdup(name), GUINT_TO_POINTER(oref)); - EekKey *key = g_hash_table_lookup(data->name_key_hash, name); + struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name); // never gets used! this section gets executed before any buttons get defined - if (key) { + if (button) { if (keycode_name != NULL) { // This sets the keycode for all buttons, // since they share state // TODO: get rid of this in the parser; // this belongs after keymap is defined - eek_key_set_keycode(key, strtol (keycode_name, NULL, 10)); + struct squeek_key *key = squeek_button_get_key(button); + squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10)); } } @@ -559,35 +551,31 @@ geometry_end_element_callback (GMarkupParseContext *pcontext, } gchar *name = g_strndup (&text[start], end - start); - EekKey *key = g_hash_table_lookup(data->name_key_hash, name); - if (!key) { + struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name); + if (!button) { // Save button name together with its level, // to account for buttons with the same name in multiple levels guint keycode = data->keycode++; guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name)); // default value gives idx 0, which is guaranteed to be occupied - key = eek_section_create_key (data->section, - name, - keycode, - oref); - g_hash_table_insert (data->name_key_hash, + button = squeek_row_create_button (data->row, keycode, oref); + g_hash_table_insert (data->name_button_hash, g_strdup(name), - key); + button); } else { - EekKey *new_key = eek_section_create_button(data->section, name, eek_key_get_state(key)); - if (!new_key) { + struct squeek_button *new_button = squeek_row_create_button_with_state(data->row, button); + if (!new_button) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE, "Couldn't create a shared button"); return; } - eek_key_set_oref(new_key, eek_key_get_oref(key)); } } - data->section = NULL; + data->row = NULL; data->num_rows = 0; return; } @@ -644,7 +632,7 @@ struct _SymbolsParseData { GString *text; LevelKeyboard *keyboard; - EekKeyboard *view; + struct squeek_view *view; gchar *label; gchar *icon; @@ -736,11 +724,11 @@ symbols_end_element_callback (GMarkupParseContext *pcontext, if (g_strcmp0 (element_name, "symbol") == 0) { gchar *name = text; - EekKey *key = eek_keyboard_find_key_by_name (data->keyboard, + struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard, name); - if (key) { + if (button) { squeek_key_add_symbol( - eek_key_get_state(key), + squeek_button_get_key(button), element_name, text, data->keyval, @@ -887,17 +875,17 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); - // char* -> EekKey* - GHashTable *name_key_hash = + // char* -> struct squeek_button* + GHashTable *name_button_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); // One view for each level - EekKeyboard *views[4] = {0}; + struct squeek_view *views[4] = {0}; GError *error = NULL; - retval = parse_geometry (path, views, outline_array, name_key_hash, &error); + retval = parse_geometry (path, views, outline_array, name_button_hash, &error); g_free (path); if (!retval) { for (uint i = 0; i < 4; i++) { @@ -911,7 +899,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, } - LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_key_hash); + LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash); keyboard->outline_array = outline_array; // FIXME: are symbols shared betwen views? @@ -941,7 +929,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self, for (uint i = 0; i < 4; i++) { if (views[i]) { - eek_layout_place_sections(keyboard, views[i]); + eek_layout_place_rows(keyboard, views[i]); } } @@ -1129,7 +1117,7 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc) } static gboolean -parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, GError **error) +parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash, GError **error) { GeometryParseData *data; GMarkupParseContext *pcontext; @@ -1146,7 +1134,7 @@ parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, G if (input == NULL) return FALSE; - data = geometry_parse_data_new (views, name_key_hash, outline_array); + data = geometry_parse_data_new (views, name_button_hash, outline_array); pcontext = g_markup_parse_context_new (&geometry_parser, 0, data, @@ -1357,7 +1345,7 @@ validate (const gchar **valid_path_list, GSList *element_stack, GError **error) { - gint i; + guint i; gchar *element_path; GSList *head, *p; GString *string; diff --git a/eek/eek.h b/eek/eek.h index 6f0abcb4..965f7a70 100644 --- a/eek/eek.h +++ b/eek/eek.h @@ -23,11 +23,8 @@ #define __EEK_H_INSIDE__ 1 #include "eek-keyboard.h" -#include "eek-section.h" -#include "eek-key.h" #include "eek-layout.h" #include "eek-keysym.h" -#include "eek-serializable.h" void eek_init (void); diff --git a/eek/meson.build b/eek/meson.build index 9e3880d6..ddfd6c18 100644 --- a/eek/meson.build +++ b/eek/meson.build @@ -6,29 +6,8 @@ enum_headers = [ enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers) -marshalers = gnome.genmarshal( - 'eek-marshalers', - sources: ['eek-marshalers.list'], - prefix: '_eek_marshal', - internal: true, -) - python = find_program('python3') -gen_keysym_entries_special = generator( - python, - arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'], - capture: true, - output: 'eek-@BASENAME@.h', -) - -gen_keysym_entries_unicode = generator( - python, - arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'], - capture: true, - output: 'eek-@BASENAME@.h', -) - gen_keysym_entries_xkeysym = generator( python, arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'], @@ -37,7 +16,5 @@ gen_keysym_entries_xkeysym = generator( ) keysym_entries = [ - gen_keysym_entries_special.process('./special-keysym-entries.txt'), - gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'), gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'), ] diff --git a/eek/special-keysym-entries.txt b/eek/special-keysym-entries.txt deleted file mode 100644 index 60a4dda2..00000000 --- a/eek/special-keysym-entries.txt +++ /dev/null @@ -1,62 +0,0 @@ -0x20 "" EEK_SYMBOL_CATEGORY_LETTER -0x8A3 "horiz\nconn" EEK_SYMBOL_CATEGORY_LETTER -0xFE50 "ˋ" EEK_SYMBOL_CATEGORY_LETTER -0xFE51 "ˊ" EEK_SYMBOL_CATEGORY_LETTER -0xFE52 "ˆ" EEK_SYMBOL_CATEGORY_LETTER -0xFE53 "~" EEK_SYMBOL_CATEGORY_LETTER -0xFE54 "ˉ" EEK_SYMBOL_CATEGORY_LETTER -0xFE55 "˘" EEK_SYMBOL_CATEGORY_LETTER -0xFE56 "˙" EEK_SYMBOL_CATEGORY_LETTER -0xFE57 "¨" EEK_SYMBOL_CATEGORY_LETTER -0xFE58 "˚" EEK_SYMBOL_CATEGORY_LETTER -0xFE59 "˝" EEK_SYMBOL_CATEGORY_LETTER -0xFE5A "ˇ" EEK_SYMBOL_CATEGORY_LETTER -0xFE5B "¸" EEK_SYMBOL_CATEGORY_LETTER -0xFE5C "˛" EEK_SYMBOL_CATEGORY_LETTER -0xFF14 "Scroll\nLock" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF20 "Compose" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF55 "Page\nUp" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF56 "Page\nDown" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF7E "AltGr" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF7F "Num\nLock" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF8D "Enter" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF95 "Home" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF96 "Left" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF97 "Up" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF98 "Right" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF99 "Down" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF9C "End" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF9D "Begin" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF9E "Ins" EEK_SYMBOL_CATEGORY_FUNCTION -0xFF9F "Del" EEK_SYMBOL_CATEGORY_FUNCTION -# aliases -0xFE03 "123" EEK_SYMBOL_CATEGORY_KEYNAME -0xFE04 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME -0xFE05 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME -0xFE08 "Next" EEK_SYMBOL_CATEGORY_KEYNAME -0xFE0A "Prev" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF08 "←" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF09 "⇥" EEK_SYMBOL_CATEGORY_KEYNAME -0xFE20 "⇤" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF0D "↵" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF1B "Esc" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE1 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE2 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE3 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE4 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE5 "⇪" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE9 "Alt" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFEA "Alt" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE7 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFE8 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFEB "Super" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFEC "Super" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFED "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME -0xFFEE "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF2A "半" EEK_SYMBOL_CATEGORY_KEYNAME -0xFF21 "漢" EEK_SYMBOL_CATEGORY_KEYNAME -0xff51 "⇠" EEK_SYMBOL_CATEGORY_KEYNAME # 1 -0xff52 "⇡" EEK_SYMBOL_CATEGORY_KEYNAME # 1 -0xff53 "⇢" EEK_SYMBOL_CATEGORY_KEYNAME # 1 -0xff54 "⇣" EEK_SYMBOL_CATEGORY_KEYNAME # 1 -0xff30 "英" EEK_SYMBOL_CATEGORY_KEYNAME diff --git a/eek/unicode-keysym-entries.txt b/eek/unicode-keysym-entries.txt deleted file mode 100644 index bf8ef169..00000000 --- a/eek/unicode-keysym-entries.txt +++ /dev/null @@ -1,826 +0,0 @@ -# This file is derived from gdkkeyuni.c in GTK+. Thanks for the -# team. The original comments are below: - -# Modified by the GTK+ Team and others 1997-2000. See the AUTHORS -# file for a list of people on the GTK+ Team. See the ChangeLog -# files for a list of changes. These files are distributed with -# GTK+ at ftp://ftp.gtk.org/pub/gtk/. - -# Thanks to Markus G. Kuhn for the ksysym<->Unicode -# mapping functions, from the xterm sources. - -# These tables could be compressed by contiguous ranges, but the -# benefit of doing so is smallish. It would save about ~1000 bytes -# total. - -0x01a1 "Ą" EEK_SYMBOL_CATEGORY_LETTER # Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK -0x01a2 "˘" EEK_SYMBOL_CATEGORY_LETTER # breve ˘ BREVE -0x01a3 "Ł" EEK_SYMBOL_CATEGORY_LETTER # Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE -0x01a5 "Ľ" EEK_SYMBOL_CATEGORY_LETTER # Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON -0x01a6 "Ś" EEK_SYMBOL_CATEGORY_LETTER # Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE -0x01a9 "Š" EEK_SYMBOL_CATEGORY_LETTER # Scaron Š LATIN CAPITAL LETTER S WITH CARON -0x01aa "Ş" EEK_SYMBOL_CATEGORY_LETTER # Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA -0x01ab "Ť" EEK_SYMBOL_CATEGORY_LETTER # Tcaron Ť LATIN CAPITAL LETTER T WITH CARON -0x01ac "Ź" EEK_SYMBOL_CATEGORY_LETTER # Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE -0x01ae "Ž" EEK_SYMBOL_CATEGORY_LETTER # Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON -0x01af "Ż" EEK_SYMBOL_CATEGORY_LETTER # Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE -0x01b1 "ą" EEK_SYMBOL_CATEGORY_LETTER # aogonek ą LATIN SMALL LETTER A WITH OGONEK -0x01b2 "˛" EEK_SYMBOL_CATEGORY_LETTER # ogonek ˛ OGONEK -0x01b3 "ł" EEK_SYMBOL_CATEGORY_LETTER # lstroke ł LATIN SMALL LETTER L WITH STROKE -0x01b5 "ľ" EEK_SYMBOL_CATEGORY_LETTER # lcaron ľ LATIN SMALL LETTER L WITH CARON -0x01b6 "ś" EEK_SYMBOL_CATEGORY_LETTER # sacute ś LATIN SMALL LETTER S WITH ACUTE -0x01b7 "ˇ" EEK_SYMBOL_CATEGORY_LETTER # caron ˇ CARON -0x01b9 "š" EEK_SYMBOL_CATEGORY_LETTER # scaron š LATIN SMALL LETTER S WITH CARON -0x01ba "ş" EEK_SYMBOL_CATEGORY_LETTER # scedilla ş LATIN SMALL LETTER S WITH CEDILLA -0x01bb "ť" EEK_SYMBOL_CATEGORY_LETTER # tcaron ť LATIN SMALL LETTER T WITH CARON -0x01bc "ź" EEK_SYMBOL_CATEGORY_LETTER # zacute ź LATIN SMALL LETTER Z WITH ACUTE -0x01bd "˝" EEK_SYMBOL_CATEGORY_LETTER # doubleacute ˝ DOUBLE ACUTE ACCENT -0x01be "ž" EEK_SYMBOL_CATEGORY_LETTER # zcaron ž LATIN SMALL LETTER Z WITH CARON -0x01bf "ż" EEK_SYMBOL_CATEGORY_LETTER # zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE -0x01c0 "Ŕ" EEK_SYMBOL_CATEGORY_LETTER # Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE -0x01c3 "Ă" EEK_SYMBOL_CATEGORY_LETTER # Abreve Ă LATIN CAPITAL LETTER A WITH BREVE -0x01c5 "Ĺ" EEK_SYMBOL_CATEGORY_LETTER # Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE -0x01c6 "Ć" EEK_SYMBOL_CATEGORY_LETTER # Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE -0x01c8 "Č" EEK_SYMBOL_CATEGORY_LETTER # Ccaron Č LATIN CAPITAL LETTER C WITH CARON -0x01ca "Ę" EEK_SYMBOL_CATEGORY_LETTER # Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK -0x01cc "Ě" EEK_SYMBOL_CATEGORY_LETTER # Ecaron Ě LATIN CAPITAL LETTER E WITH CARON -0x01cf "Ď" EEK_SYMBOL_CATEGORY_LETTER # Dcaron Ď LATIN CAPITAL LETTER D WITH CARON -0x01d0 "Đ" EEK_SYMBOL_CATEGORY_LETTER # Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE -0x01d1 "Ń" EEK_SYMBOL_CATEGORY_LETTER # Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE -0x01d2 "Ň" EEK_SYMBOL_CATEGORY_LETTER # Ncaron Ň LATIN CAPITAL LETTER N WITH CARON -0x01d5 "Ő" EEK_SYMBOL_CATEGORY_LETTER # Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -0x01d8 "Ř" EEK_SYMBOL_CATEGORY_LETTER # Rcaron Ř LATIN CAPITAL LETTER R WITH CARON -0x01d9 "Ů" EEK_SYMBOL_CATEGORY_LETTER # Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE -0x01db "Ű" EEK_SYMBOL_CATEGORY_LETTER # Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -0x01de "Ţ" EEK_SYMBOL_CATEGORY_LETTER # Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA -0x01e0 "ŕ" EEK_SYMBOL_CATEGORY_LETTER # racute ŕ LATIN SMALL LETTER R WITH ACUTE -0x01e3 "ă" EEK_SYMBOL_CATEGORY_LETTER # abreve ă LATIN SMALL LETTER A WITH BREVE -0x01e5 "ĺ" EEK_SYMBOL_CATEGORY_LETTER # lacute ĺ LATIN SMALL LETTER L WITH ACUTE -0x01e6 "ć" EEK_SYMBOL_CATEGORY_LETTER # cacute ć LATIN SMALL LETTER C WITH ACUTE -0x01e8 "č" EEK_SYMBOL_CATEGORY_LETTER # ccaron č LATIN SMALL LETTER C WITH CARON -0x01ea "ę" EEK_SYMBOL_CATEGORY_LETTER # eogonek ę LATIN SMALL LETTER E WITH OGONEK -0x01ec "ě" EEK_SYMBOL_CATEGORY_LETTER # ecaron ě LATIN SMALL LETTER E WITH CARON -0x01ef "ď" EEK_SYMBOL_CATEGORY_LETTER # dcaron ď LATIN SMALL LETTER D WITH CARON -0x01f0 "đ" EEK_SYMBOL_CATEGORY_LETTER # dstroke đ LATIN SMALL LETTER D WITH STROKE -0x01f1 "ń" EEK_SYMBOL_CATEGORY_LETTER # nacute ń LATIN SMALL LETTER N WITH ACUTE -0x01f2 "ň" EEK_SYMBOL_CATEGORY_LETTER # ncaron ň LATIN SMALL LETTER N WITH CARON -0x01f5 "ő" EEK_SYMBOL_CATEGORY_LETTER # odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE -0x01f8 "ř" EEK_SYMBOL_CATEGORY_LETTER # rcaron ř LATIN SMALL LETTER R WITH CARON -0x01f9 "ů" EEK_SYMBOL_CATEGORY_LETTER # uring ů LATIN SMALL LETTER U WITH RING ABOVE -0x01fb "ű" EEK_SYMBOL_CATEGORY_LETTER # udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE -0x01fe "ţ" EEK_SYMBOL_CATEGORY_LETTER # tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA -0x01ff "˙" EEK_SYMBOL_CATEGORY_LETTER # abovedot ˙ DOT ABOVE -0x02a1 "Ħ" EEK_SYMBOL_CATEGORY_LETTER # Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE -0x02a6 "Ĥ" EEK_SYMBOL_CATEGORY_LETTER # Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX -0x02a9 "İ" EEK_SYMBOL_CATEGORY_LETTER # Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE -0x02ab "Ğ" EEK_SYMBOL_CATEGORY_LETTER # Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE -0x02ac "Ĵ" EEK_SYMBOL_CATEGORY_LETTER # Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX -0x02b1 "ħ" EEK_SYMBOL_CATEGORY_LETTER # hstroke ħ LATIN SMALL LETTER H WITH STROKE -0x02b6 "ĥ" EEK_SYMBOL_CATEGORY_LETTER # hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX -0x02b9 "ı" EEK_SYMBOL_CATEGORY_LETTER # idotless ı LATIN SMALL LETTER DOTLESS I -0x02bb "ğ" EEK_SYMBOL_CATEGORY_LETTER # gbreve ğ LATIN SMALL LETTER G WITH BREVE -0x02bc "ĵ" EEK_SYMBOL_CATEGORY_LETTER # jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX -0x02c5 "Ċ" EEK_SYMBOL_CATEGORY_LETTER # Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE -0x02c6 "Ĉ" EEK_SYMBOL_CATEGORY_LETTER # Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX -0x02d5 "Ġ" EEK_SYMBOL_CATEGORY_LETTER # Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE -0x02d8 "Ĝ" EEK_SYMBOL_CATEGORY_LETTER # Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX -0x02dd "Ŭ" EEK_SYMBOL_CATEGORY_LETTER # Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE -0x02de "Ŝ" EEK_SYMBOL_CATEGORY_LETTER # Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX -0x02e5 "ċ" EEK_SYMBOL_CATEGORY_LETTER # cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE -0x02e6 "ĉ" EEK_SYMBOL_CATEGORY_LETTER # ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX -0x02f5 "ġ" EEK_SYMBOL_CATEGORY_LETTER # gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE -0x02f8 "ĝ" EEK_SYMBOL_CATEGORY_LETTER # gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX -0x02fd "ŭ" EEK_SYMBOL_CATEGORY_LETTER # ubreve ŭ LATIN SMALL LETTER U WITH BREVE -0x02fe "ŝ" EEK_SYMBOL_CATEGORY_LETTER # scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX -0x03a2 "ĸ" EEK_SYMBOL_CATEGORY_LETTER # kra ĸ LATIN SMALL LETTER KRA -0x03a3 "Ŗ" EEK_SYMBOL_CATEGORY_LETTER # Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA -0x03a5 "Ĩ" EEK_SYMBOL_CATEGORY_LETTER # Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE -0x03a6 "Ļ" EEK_SYMBOL_CATEGORY_LETTER # Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA -0x03aa "Ē" EEK_SYMBOL_CATEGORY_LETTER # Emacron Ē LATIN CAPITAL LETTER E WITH MACRON -0x03ab "Ģ" EEK_SYMBOL_CATEGORY_LETTER # Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA -0x03ac "Ŧ" EEK_SYMBOL_CATEGORY_LETTER # Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE -0x03b3 "ŗ" EEK_SYMBOL_CATEGORY_LETTER # rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA -0x03b5 "ĩ" EEK_SYMBOL_CATEGORY_LETTER # itilde ĩ LATIN SMALL LETTER I WITH TILDE -0x03b6 "ļ" EEK_SYMBOL_CATEGORY_LETTER # lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA -0x03ba "ē" EEK_SYMBOL_CATEGORY_LETTER # emacron ē LATIN SMALL LETTER E WITH MACRON -0x03bb "ģ" EEK_SYMBOL_CATEGORY_LETTER # gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA -0x03bc "ŧ" EEK_SYMBOL_CATEGORY_LETTER # tslash ŧ LATIN SMALL LETTER T WITH STROKE -0x03bd "Ŋ" EEK_SYMBOL_CATEGORY_LETTER # ENG Ŋ LATIN CAPITAL LETTER ENG -0x03bf "ŋ" EEK_SYMBOL_CATEGORY_LETTER # eng ŋ LATIN SMALL LETTER ENG -0x03c0 "Ā" EEK_SYMBOL_CATEGORY_LETTER # Amacron Ā LATIN CAPITAL LETTER A WITH MACRON -0x03c7 "Į" EEK_SYMBOL_CATEGORY_LETTER # Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK -0x03cc "Ė" EEK_SYMBOL_CATEGORY_LETTER # Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE -0x03cf "Ī" EEK_SYMBOL_CATEGORY_LETTER # Imacron Ī LATIN CAPITAL LETTER I WITH MACRON -0x03d1 "Ņ" EEK_SYMBOL_CATEGORY_LETTER # Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA -0x03d2 "Ō" EEK_SYMBOL_CATEGORY_LETTER # Omacron Ō LATIN CAPITAL LETTER O WITH MACRON -0x03d3 "Ķ" EEK_SYMBOL_CATEGORY_LETTER # Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA -0x03d9 "Ų" EEK_SYMBOL_CATEGORY_LETTER # Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK -0x03dd "Ũ" EEK_SYMBOL_CATEGORY_LETTER # Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE -0x03de "Ū" EEK_SYMBOL_CATEGORY_LETTER # Umacron Ū LATIN CAPITAL LETTER U WITH MACRON -0x03e0 "ā" EEK_SYMBOL_CATEGORY_LETTER # amacron ā LATIN SMALL LETTER A WITH MACRON -0x03e7 "į" EEK_SYMBOL_CATEGORY_LETTER # iogonek į LATIN SMALL LETTER I WITH OGONEK -0x03ec "ė" EEK_SYMBOL_CATEGORY_LETTER # eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE -0x03ef "ī" EEK_SYMBOL_CATEGORY_LETTER # imacron ī LATIN SMALL LETTER I WITH MACRON -0x03f1 "ņ" EEK_SYMBOL_CATEGORY_LETTER # ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA -0x03f2 "ō" EEK_SYMBOL_CATEGORY_LETTER # omacron ō LATIN SMALL LETTER O WITH MACRON -0x03f3 "ķ" EEK_SYMBOL_CATEGORY_LETTER # kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA -0x03f9 "ų" EEK_SYMBOL_CATEGORY_LETTER # uogonek ų LATIN SMALL LETTER U WITH OGONEK -0x03fd "ũ" EEK_SYMBOL_CATEGORY_LETTER # utilde ũ LATIN SMALL LETTER U WITH TILDE -0x03fe "ū" EEK_SYMBOL_CATEGORY_LETTER # umacron ū LATIN SMALL LETTER U WITH MACRON -0x047e "‾" EEK_SYMBOL_CATEGORY_LETTER # overline ‾ OVERLINE -0x04a1 "。" EEK_SYMBOL_CATEGORY_LETTER # kana_fullstop 。 IDEOGRAPHIC FULL STOP -0x04a2 "「" EEK_SYMBOL_CATEGORY_LETTER # kana_openingbracket 「 LEFT CORNER BRACKET -0x04a3 "」" EEK_SYMBOL_CATEGORY_LETTER # kana_closingbracket 」 RIGHT CORNER BRACKET -0x04a4 "、" EEK_SYMBOL_CATEGORY_LETTER # kana_comma 、 IDEOGRAPHIC COMMA -0x04a5 "・" EEK_SYMBOL_CATEGORY_LETTER # kana_conjunctive ・ KATAKANA MIDDLE DOT -0x04a6 "ヲ" EEK_SYMBOL_CATEGORY_LETTER # kana_WO ヲ KATAKANA LETTER WO -0x04a7 "ァ" EEK_SYMBOL_CATEGORY_LETTER # kana_a ァ KATAKANA LETTER SMALL A -0x04a8 "ィ" EEK_SYMBOL_CATEGORY_LETTER # kana_i ィ KATAKANA LETTER SMALL I -0x04a9 "ゥ" EEK_SYMBOL_CATEGORY_LETTER # kana_u ゥ KATAKANA LETTER SMALL U -0x04aa "ェ" EEK_SYMBOL_CATEGORY_LETTER # kana_e ェ KATAKANA LETTER SMALL E -0x04ab "ォ" EEK_SYMBOL_CATEGORY_LETTER # kana_o ォ KATAKANA LETTER SMALL O -0x04ac "ャ" EEK_SYMBOL_CATEGORY_LETTER # kana_ya ャ KATAKANA LETTER SMALL YA -0x04ad "ュ" EEK_SYMBOL_CATEGORY_LETTER # kana_yu ュ KATAKANA LETTER SMALL YU -0x04ae "ョ" EEK_SYMBOL_CATEGORY_LETTER # kana_yo ョ KATAKANA LETTER SMALL YO -0x04af "ッ" EEK_SYMBOL_CATEGORY_LETTER # kana_tsu ッ KATAKANA LETTER SMALL TU -0x04b0 "ー" EEK_SYMBOL_CATEGORY_LETTER # prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK -0x04b1 "ア" EEK_SYMBOL_CATEGORY_LETTER # kana_A ア KATAKANA LETTER A -0x04b2 "イ" EEK_SYMBOL_CATEGORY_LETTER # kana_I イ KATAKANA LETTER I -0x04b3 "ウ" EEK_SYMBOL_CATEGORY_LETTER # kana_U ウ KATAKANA LETTER U -0x04b4 "エ" EEK_SYMBOL_CATEGORY_LETTER # kana_E エ KATAKANA LETTER E -0x04b5 "オ" EEK_SYMBOL_CATEGORY_LETTER # kana_O オ KATAKANA LETTER O -0x04b6 "カ" EEK_SYMBOL_CATEGORY_LETTER # kana_KA カ KATAKANA LETTER KA -0x04b7 "キ" EEK_SYMBOL_CATEGORY_LETTER # kana_KI キ KATAKANA LETTER KI -0x04b8 "ク" EEK_SYMBOL_CATEGORY_LETTER # kana_KU ク KATAKANA LETTER KU -0x04b9 "ケ" EEK_SYMBOL_CATEGORY_LETTER # kana_KE ケ KATAKANA LETTER KE -0x04ba "コ" EEK_SYMBOL_CATEGORY_LETTER # kana_KO コ KATAKANA LETTER KO -0x04bb "サ" EEK_SYMBOL_CATEGORY_LETTER # kana_SA サ KATAKANA LETTER SA -0x04bc "シ" EEK_SYMBOL_CATEGORY_LETTER # kana_SHI シ KATAKANA LETTER SI -0x04bd "ス" EEK_SYMBOL_CATEGORY_LETTER # kana_SU ス KATAKANA LETTER SU -0x04be "セ" EEK_SYMBOL_CATEGORY_LETTER # kana_SE セ KATAKANA LETTER SE -0x04bf "ソ" EEK_SYMBOL_CATEGORY_LETTER # kana_SO ソ KATAKANA LETTER SO -0x04c0 "タ" EEK_SYMBOL_CATEGORY_LETTER # kana_TA タ KATAKANA LETTER TA -0x04c1 "チ" EEK_SYMBOL_CATEGORY_LETTER # kana_CHI チ KATAKANA LETTER TI -0x04c2 "ツ" EEK_SYMBOL_CATEGORY_LETTER # kana_TSU ツ KATAKANA LETTER TU -0x04c3 "テ" EEK_SYMBOL_CATEGORY_LETTER # kana_TE テ KATAKANA LETTER TE -0x04c4 "ト" EEK_SYMBOL_CATEGORY_LETTER # kana_TO ト KATAKANA LETTER TO -0x04c5 "ナ" EEK_SYMBOL_CATEGORY_LETTER # kana_NA ナ KATAKANA LETTER NA -0x04c6 "ニ" EEK_SYMBOL_CATEGORY_LETTER # kana_NI ニ KATAKANA LETTER NI -0x04c7 "ヌ" EEK_SYMBOL_CATEGORY_LETTER # kana_NU ヌ KATAKANA LETTER NU -0x04c8 "ネ" EEK_SYMBOL_CATEGORY_LETTER # kana_NE ネ KATAKANA LETTER NE -0x04c9 "ノ" EEK_SYMBOL_CATEGORY_LETTER # kana_NO ノ KATAKANA LETTER NO -0x04ca "ハ" EEK_SYMBOL_CATEGORY_LETTER # kana_HA ハ KATAKANA LETTER HA -0x04cb "ヒ" EEK_SYMBOL_CATEGORY_LETTER # kana_HI ヒ KATAKANA LETTER HI -0x04cc "フ" EEK_SYMBOL_CATEGORY_LETTER # kana_FU フ KATAKANA LETTER HU -0x04cd "ヘ" EEK_SYMBOL_CATEGORY_LETTER # kana_HE ヘ KATAKANA LETTER HE -0x04ce "ホ" EEK_SYMBOL_CATEGORY_LETTER # kana_HO ホ KATAKANA LETTER HO -0x04cf "マ" EEK_SYMBOL_CATEGORY_LETTER # kana_MA マ KATAKANA LETTER MA -0x04d0 "ミ" EEK_SYMBOL_CATEGORY_LETTER # kana_MI ミ KATAKANA LETTER MI -0x04d1 "ム" EEK_SYMBOL_CATEGORY_LETTER # kana_MU ム KATAKANA LETTER MU -0x04d2 "メ" EEK_SYMBOL_CATEGORY_LETTER # kana_ME メ KATAKANA LETTER ME -0x04d3 "モ" EEK_SYMBOL_CATEGORY_LETTER # kana_MO モ KATAKANA LETTER MO -0x04d4 "ヤ" EEK_SYMBOL_CATEGORY_LETTER # kana_YA ヤ KATAKANA LETTER YA -0x04d5 "ユ" EEK_SYMBOL_CATEGORY_LETTER # kana_YU ユ KATAKANA LETTER YU -0x04d6 "ヨ" EEK_SYMBOL_CATEGORY_LETTER # kana_YO ヨ KATAKANA LETTER YO -0x04d7 "ラ" EEK_SYMBOL_CATEGORY_LETTER # kana_RA ラ KATAKANA LETTER RA -0x04d8 "リ" EEK_SYMBOL_CATEGORY_LETTER # kana_RI リ KATAKANA LETTER RI -0x04d9 "ル" EEK_SYMBOL_CATEGORY_LETTER # kana_RU ル KATAKANA LETTER RU -0x04da "レ" EEK_SYMBOL_CATEGORY_LETTER # kana_RE レ KATAKANA LETTER RE -0x04db "ロ" EEK_SYMBOL_CATEGORY_LETTER # kana_RO ロ KATAKANA LETTER RO -0x04dc "ワ" EEK_SYMBOL_CATEGORY_LETTER # kana_WA ワ KATAKANA LETTER WA -0x04dd "ン" EEK_SYMBOL_CATEGORY_LETTER # kana_N ン KATAKANA LETTER N -0x04de "゛" EEK_SYMBOL_CATEGORY_LETTER # voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK -0x04df "゜" EEK_SYMBOL_CATEGORY_LETTER # semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK -0x05ac "،" EEK_SYMBOL_CATEGORY_LETTER # Arabic_comma ، ARABIC COMMA -0x05bb "؛" EEK_SYMBOL_CATEGORY_LETTER # Arabic_semicolon ؛ ARABIC SEMICOLON -0x05bf "؟" EEK_SYMBOL_CATEGORY_LETTER # Arabic_question_mark ؟ ARABIC QUESTION MARK -0x05c1 "ء" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamza ء ARABIC LETTER HAMZA -0x05c2 "آ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE -0x05c3 "أ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE -0x05c4 "ؤ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE -0x05c5 "إ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW -0x05c6 "ئ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE -0x05c7 "ا" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alef ا ARABIC LETTER ALEF -0x05c8 "ب" EEK_SYMBOL_CATEGORY_LETTER # Arabic_beh ب ARABIC LETTER BEH -0x05c9 "ة" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA -0x05ca "ت" EEK_SYMBOL_CATEGORY_LETTER # Arabic_teh ت ARABIC LETTER TEH -0x05cb "ث" EEK_SYMBOL_CATEGORY_LETTER # Arabic_theh ث ARABIC LETTER THEH -0x05cc "ج" EEK_SYMBOL_CATEGORY_LETTER # Arabic_jeem ج ARABIC LETTER JEEM -0x05cd "ح" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hah ح ARABIC LETTER HAH -0x05ce "خ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_khah خ ARABIC LETTER KHAH -0x05cf "د" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dal د ARABIC LETTER DAL -0x05d0 "ذ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_thal ذ ARABIC LETTER THAL -0x05d1 "ر" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ra ر ARABIC LETTER REH -0x05d2 "ز" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zain ز ARABIC LETTER ZAIN -0x05d3 "س" EEK_SYMBOL_CATEGORY_LETTER # Arabic_seen س ARABIC LETTER SEEN -0x05d4 "ش" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sheen ش ARABIC LETTER SHEEN -0x05d5 "ص" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sad ص ARABIC LETTER SAD -0x05d6 "ض" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dad ض ARABIC LETTER DAD -0x05d7 "ط" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tah ط ARABIC LETTER TAH -0x05d8 "ظ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zah ظ ARABIC LETTER ZAH -0x05d9 "ع" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ain ع ARABIC LETTER AIN -0x05da "غ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ghain غ ARABIC LETTER GHAIN -0x05e0 "ـ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tatweel ـ ARABIC TATWEEL -0x05e1 "ف" EEK_SYMBOL_CATEGORY_LETTER # Arabic_feh ف ARABIC LETTER FEH -0x05e2 "ق" EEK_SYMBOL_CATEGORY_LETTER # Arabic_qaf ق ARABIC LETTER QAF -0x05e3 "ك" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kaf ك ARABIC LETTER KAF -0x05e4 "ل" EEK_SYMBOL_CATEGORY_LETTER # Arabic_lam ل ARABIC LETTER LAM -0x05e5 "م" EEK_SYMBOL_CATEGORY_LETTER # Arabic_meem م ARABIC LETTER MEEM -0x05e6 "ن" EEK_SYMBOL_CATEGORY_LETTER # Arabic_noon ن ARABIC LETTER NOON -0x05e7 "ه" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ha ه ARABIC LETTER HEH -0x05e8 "و" EEK_SYMBOL_CATEGORY_LETTER # Arabic_waw و ARABIC LETTER WAW -0x05e9 "ى" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA -0x05ea "ي" EEK_SYMBOL_CATEGORY_LETTER # Arabic_yeh ي ARABIC LETTER YEH -0x05eb "ً" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fathatan ً ARABIC FATHATAN -0x05ec "ٌ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dammatan ٌ ARABIC DAMMATAN -0x05ed "ٍ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasratan ٍ ARABIC KASRATAN -0x05ee "َ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fatha َ ARABIC FATHA -0x05ef "ُ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_damma ُ ARABIC DAMMA -0x05f0 "ِ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasra ِ ARABIC KASRA -0x05f1 "ّ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_shadda ّ ARABIC SHADDA -0x05f2 "ْ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sukun ْ ARABIC SUKUN -0x06a1 "ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_dje ђ CYRILLIC SMALL LETTER DJE -0x06a2 "ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE -0x06a3 "ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_io ё CYRILLIC SMALL LETTER IO -0x06a4 "є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE -0x06a5 "ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE -0x06a6 "і" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -0x06a7 "ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_yi ї CYRILLIC SMALL LETTER YI -0x06a8 "ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_je ј CYRILLIC SMALL LETTER JE -0x06a9 "љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_lje љ CYRILLIC SMALL LETTER LJE -0x06aa "њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_nje њ CYRILLIC SMALL LETTER NJE -0x06ab "ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE -0x06ac "ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_kje ќ CYRILLIC SMALL LETTER KJE -0x06ad "ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN -0x06ae "ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U -0x06af "џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE -0x06b0 "№" EEK_SYMBOL_CATEGORY_LETTER # numerosign № NUMERO SIGN -0x06b1 "Ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE -0x06b2 "Ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE -0x06b3 "Ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO -0x06b4 "Є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE -0x06b5 "Ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE -0x06b6 "І" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0x06b7 "Ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI -0x06b8 "Ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE -0x06b9 "Љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE -0x06ba "Њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE -0x06bb "Ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE -0x06bc "Ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE -0x06bd "Ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN -0x06be "Ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U -0x06bf "Џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE -0x06c0 "ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yu ю CYRILLIC SMALL LETTER YU -0x06c1 "а" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_a а CYRILLIC SMALL LETTER A -0x06c2 "б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_be б CYRILLIC SMALL LETTER BE -0x06c3 "ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_tse ц CYRILLIC SMALL LETTER TSE -0x06c4 "д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_de д CYRILLIC SMALL LETTER DE -0x06c5 "е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ie е CYRILLIC SMALL LETTER IE -0x06c6 "ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ef ф CYRILLIC SMALL LETTER EF -0x06c7 "г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ghe г CYRILLIC SMALL LETTER GHE -0x06c8 "х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ha х CYRILLIC SMALL LETTER HA -0x06c9 "и" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_i и CYRILLIC SMALL LETTER I -0x06ca "й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I -0x06cb "к" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ka к CYRILLIC SMALL LETTER KA -0x06cc "л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_el л CYRILLIC SMALL LETTER EL -0x06cd "м" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_em м CYRILLIC SMALL LETTER EM -0x06ce "н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_en н CYRILLIC SMALL LETTER EN -0x06cf "о" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_o о CYRILLIC SMALL LETTER O -0x06d0 "п" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_pe п CYRILLIC SMALL LETTER PE -0x06d1 "я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ya я CYRILLIC SMALL LETTER YA -0x06d2 "р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_er р CYRILLIC SMALL LETTER ER -0x06d3 "с" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_es с CYRILLIC SMALL LETTER ES -0x06d4 "т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_te т CYRILLIC SMALL LETTER TE -0x06d5 "у" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_u у CYRILLIC SMALL LETTER U -0x06d6 "ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE -0x06d7 "в" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ve в CYRILLIC SMALL LETTER VE -0x06d8 "ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN -0x06d9 "ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU -0x06da "з" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ze з CYRILLIC SMALL LETTER ZE -0x06db "ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_sha ш CYRILLIC SMALL LETTER SHA -0x06dc "э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_e э CYRILLIC SMALL LETTER E -0x06dd "щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA -0x06de "ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_che ч CYRILLIC SMALL LETTER CHE -0x06df "ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN -0x06e0 "Ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU -0x06e1 "А" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_A А CYRILLIC CAPITAL LETTER A -0x06e2 "Б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE -0x06e3 "Ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE -0x06e4 "Д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE -0x06e5 "Е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE -0x06e6 "Ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF -0x06e7 "Г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE -0x06e8 "Х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA -0x06e9 "И" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_I И CYRILLIC CAPITAL LETTER I -0x06ea "Й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I -0x06eb "К" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_KA К CYRILLIC CAPITAL LETTER KA -0x06ec "Л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL -0x06ed "М" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EM М CYRILLIC CAPITAL LETTER EM -0x06ee "Н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN -0x06ef "О" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_O О CYRILLIC CAPITAL LETTER O -0x06f0 "П" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_PE П CYRILLIC CAPITAL LETTER PE -0x06f1 "Я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA -0x06f2 "Р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER -0x06f3 "С" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ES С CYRILLIC CAPITAL LETTER ES -0x06f4 "Т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE -0x06f5 "У" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_U У CYRILLIC CAPITAL LETTER U -0x06f6 "Ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE -0x06f7 "В" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_VE В CYRILLIC CAPITAL LETTER VE -0x06f8 "Ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN -0x06f9 "Ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU -0x06fa "З" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE -0x06fb "Ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA -0x06fc "Э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_E Э CYRILLIC CAPITAL LETTER E -0x06fd "Щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA -0x06fe "Ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE -0x06ff "Ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN -0x07a1 "Ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS -0x07a2 "Έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS -0x07a3 "Ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS -0x07a4 "Ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS -0x07a5 "Ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -0x07a7 "Ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS -0x07a8 "Ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS -0x07a9 "Ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -0x07ab "Ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS -0x07ae "΅" EEK_SYMBOL_CATEGORY_LETTER # Geek_accentdieresis ΅ GREEK DIALYTIKA TONOS -0x07af "―" EEK_SYMBOL_CATEGORY_LETTER # Geek_horizbar ― HORIZONTAL BAR -0x07b1 "ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS -0x07b2 "έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS -0x07b3 "ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS -0x07b4 "ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS -0x07b5 "ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA -0x07b6 "ΐ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -0x07b7 "ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS -0x07b8 "ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS -0x07b9 "ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA -0x07ba "ΰ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -0x07bb "ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS -0x07c1 "Α" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHA Α GREEK CAPITAL LETTER ALPHA -0x07c2 "Β" EEK_SYMBOL_CATEGORY_LETTER # Geek_BETA Β GREEK CAPITAL LETTER BETA -0x07c3 "Γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_GAMMA Γ GREEK CAPITAL LETTER GAMMA -0x07c4 "Δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_DELTA Δ GREEK CAPITAL LETTER DELTA -0x07c5 "Ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILON Ε GREEK CAPITAL LETTER EPSILON -0x07c6 "Ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_ZETA Ζ GREEK CAPITAL LETTER ZETA -0x07c7 "Η" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETA Η GREEK CAPITAL LETTER ETA -0x07c8 "Θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_THETA Θ GREEK CAPITAL LETTER THETA -0x07c9 "Ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTA Ι GREEK CAPITAL LETTER IOTA -0x07ca "Κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_KAPPA Κ GREEK CAPITAL LETTER KAPPA -0x07cb "Λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA -0x07cc "Μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_MU Μ GREEK CAPITAL LETTER MU -0x07cd "Ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_NU Ν GREEK CAPITAL LETTER NU -0x07ce "Ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_XI Ξ GREEK CAPITAL LETTER XI -0x07cf "Ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRON Ο GREEK CAPITAL LETTER OMICRON -0x07d0 "Π" EEK_SYMBOL_CATEGORY_LETTER # Geek_PI Π GREEK CAPITAL LETTER PI -0x07d1 "Ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_RHO Ρ GREEK CAPITAL LETTER RHO -0x07d2 "Σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_SIGMA Σ GREEK CAPITAL LETTER SIGMA -0x07d4 "Τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_TAU Τ GREEK CAPITAL LETTER TAU -0x07d5 "Υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILON Υ GREEK CAPITAL LETTER UPSILON -0x07d6 "Φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PHI Φ GREEK CAPITAL LETTER PHI -0x07d7 "Χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_CHI Χ GREEK CAPITAL LETTER CHI -0x07d8 "Ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PSI Ψ GREEK CAPITAL LETTER PSI -0x07d9 "Ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGA Ω GREEK CAPITAL LETTER OMEGA -0x07e1 "α" EEK_SYMBOL_CATEGORY_LETTER # Geek_alpha α GREEK SMALL LETTER ALPHA -0x07e2 "β" EEK_SYMBOL_CATEGORY_LETTER # Geek_beta β GREEK SMALL LETTER BETA -0x07e3 "γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_gamma γ GREEK SMALL LETTER GAMMA -0x07e4 "δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_delta δ GREEK SMALL LETTER DELTA -0x07e5 "ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilon ε GREEK SMALL LETTER EPSILON -0x07e6 "ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_zeta ζ GREEK SMALL LETTER ZETA -0x07e7 "η" EEK_SYMBOL_CATEGORY_LETTER # Geek_eta η GREEK SMALL LETTER ETA -0x07e8 "θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_theta θ GREEK SMALL LETTER THETA -0x07e9 "ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_iota ι GREEK SMALL LETTER IOTA -0x07ea "κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_kappa κ GREEK SMALL LETTER KAPPA -0x07eb "λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_lambda λ GREEK SMALL LETTER LAMDA -0x07ec "μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_mu μ GREEK SMALL LETTER MU -0x07ed "ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_nu ν GREEK SMALL LETTER NU -0x07ee "ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_xi ξ GREEK SMALL LETTER XI -0x07ef "ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicron ο GREEK SMALL LETTER OMICRON -0x07f0 "π" EEK_SYMBOL_CATEGORY_LETTER # Geek_pi π GREEK SMALL LETTER PI -0x07f1 "ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_rho ρ GREEK SMALL LETTER RHO -0x07f2 "σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_sigma σ GREEK SMALL LETTER SIGMA -0x07f3 "ς" EEK_SYMBOL_CATEGORY_LETTER # Geek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA -0x07f4 "τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_tau τ GREEK SMALL LETTER TAU -0x07f5 "υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilon υ GREEK SMALL LETTER UPSILON -0x07f6 "φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_phi φ GREEK SMALL LETTER PHI -0x07f7 "χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_chi χ GREEK SMALL LETTER CHI -0x07f8 "ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_psi ψ GREEK SMALL LETTER PSI -0x07f9 "ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_omega ω GREEK SMALL LETTER OMEGA -# 0x08a1 leftradical ? ??? -# 0x08a2 topleftradical ? ??? -# 0x08a3 horizconnector ? ??? -0x08a4 "⌠" EEK_SYMBOL_CATEGORY_LETTER # topintegral ⌠ TOP HALF INTEGRAL -0x08a5 "⌡" EEK_SYMBOL_CATEGORY_LETTER # botintegral ⌡ BOTTOM HALF INTEGRAL -0x08a6 "│" EEK_SYMBOL_CATEGORY_LETTER # vertconnector │ BOX DRAWINGS LIGHT VERTICAL -# 0x08a7 topleftsqbracket ? ??? -# 0x08a8 botleftsqbracket ? ??? -# 0x08a9 toprightsqbracket ? ??? -# 0x08aa botrightsqbracket ? ??? -# 0x08ab topleftparens ? ??? -# 0x08ac botleftparens ? ??? -# 0x08ad toprightparens ? ??? -# 0x08ae botrightparens ? ??? -# 0x08af leftmiddlecurlybrace ? ??? -# 0x08b0 rightmiddlecurlybrace ? ??? -# 0x08b1 topleftsummation ? ??? -# 0x08b2 botleftsummation ? ??? -# 0x08b3 topvertsummationconnector ? ??? -# 0x08b4 botvertsummationconnector ? ??? -# 0x08b5 toprightsummation ? ??? -# 0x08b6 botrightsummation ? ??? -# 0x08b7 rightmiddlesummation ? ??? -0x08bc "≤" EEK_SYMBOL_CATEGORY_LETTER # lessthanequal ≤ LESS-THAN OR EQUAL TO -0x08bd "≠" EEK_SYMBOL_CATEGORY_LETTER # notequal ≠ NOT EQUAL TO -0x08be "≥" EEK_SYMBOL_CATEGORY_LETTER # greaterthanequal ≥ GREATER-THAN OR EQUAL TO -0x08bf "∫" EEK_SYMBOL_CATEGORY_LETTER # integral ∫ INTEGRAL -0x08c0 "∴" EEK_SYMBOL_CATEGORY_LETTER # therefore ∴ THEREFORE -0x08c1 "∝" EEK_SYMBOL_CATEGORY_LETTER # variation ∝ PROPORTIONAL TO -0x08c2 "∞" EEK_SYMBOL_CATEGORY_LETTER # infinity ∞ INFINITY -0x08c5 "∇" EEK_SYMBOL_CATEGORY_LETTER # nabla ∇ NABLA -0x08c8 "≅" EEK_SYMBOL_CATEGORY_LETTER # approximate ≅ APPROXIMATELY EQUAL TO -# 0x08c9 similarequal ? ??? -0x08cd "⇔" EEK_SYMBOL_CATEGORY_LETTER # ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW -0x08ce "⇒" EEK_SYMBOL_CATEGORY_LETTER # implies ⇒ RIGHTWARDS DOUBLE ARROW -0x08cf "≡" EEK_SYMBOL_CATEGORY_LETTER # identical ≡ IDENTICAL TO -0x08d6 "√" EEK_SYMBOL_CATEGORY_LETTER # radical √ SQUARE ROOT -0x08da "⊂" EEK_SYMBOL_CATEGORY_LETTER # includedin ⊂ SUBSET OF -0x08db "⊃" EEK_SYMBOL_CATEGORY_LETTER # includes ⊃ SUPERSET OF -0x08dc "∩" EEK_SYMBOL_CATEGORY_LETTER # intersection ∩ INTERSECTION -0x08dd "∪" EEK_SYMBOL_CATEGORY_LETTER # union ∪ UNION -0x08de "∧" EEK_SYMBOL_CATEGORY_LETTER # logicaland ∧ LOGICAL AND -0x08df "∨" EEK_SYMBOL_CATEGORY_LETTER # logicalor ∨ LOGICAL OR -0x08ef "∂" EEK_SYMBOL_CATEGORY_LETTER # partialderivative ∂ PARTIAL DIFFERENTIAL -0x08f6 "ƒ" EEK_SYMBOL_CATEGORY_LETTER # function ƒ LATIN SMALL LETTER F WITH HOOK -0x08fb "←" EEK_SYMBOL_CATEGORY_LETTER # leftarrow ← LEFTWARDS ARROW -0x08fc "↑" EEK_SYMBOL_CATEGORY_LETTER # uparrow ↑ UPWARDS ARROW -0x08fd "→" EEK_SYMBOL_CATEGORY_LETTER # rightarrow → RIGHTWARDS ARROW -0x08fe "↓" EEK_SYMBOL_CATEGORY_LETTER # downarrow ↓ DOWNWARDS ARROW -0x09df "␢" EEK_SYMBOL_CATEGORY_LETTER # blank ␢ BLANK SYMBOL -0x09e0 "◆" EEK_SYMBOL_CATEGORY_LETTER # soliddiamond ◆ BLACK DIAMOND -0x09e1 "▒" EEK_SYMBOL_CATEGORY_LETTER # checkerboard ▒ MEDIUM SHADE -0x09e2 "␉" EEK_SYMBOL_CATEGORY_LETTER # ht ␉ SYMBOL FOR HORIZONTAL TABULATION -0x09e3 "␌" EEK_SYMBOL_CATEGORY_LETTER # ff ␌ SYMBOL FOR FORM FEED -0x09e4 "␍" EEK_SYMBOL_CATEGORY_LETTER # cr ␍ SYMBOL FOR CARRIAGE RETURN -0x09e5 "␊" EEK_SYMBOL_CATEGORY_LETTER # lf ␊ SYMBOL FOR LINE FEED -0x09e8 "␤" EEK_SYMBOL_CATEGORY_LETTER # nl ␤ SYMBOL FOR NEWLINE -0x09e9 "␋" EEK_SYMBOL_CATEGORY_LETTER # vt ␋ SYMBOL FOR VERTICAL TABULATION -0x09ea "┘" EEK_SYMBOL_CATEGORY_LETTER # lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT -0x09eb "┐" EEK_SYMBOL_CATEGORY_LETTER # uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT -0x09ec "┌" EEK_SYMBOL_CATEGORY_LETTER # upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT -0x09ed "└" EEK_SYMBOL_CATEGORY_LETTER # lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT -0x09ee "┼" EEK_SYMBOL_CATEGORY_LETTER # crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -# 0x09ef horizlinescan1 ? ??? -# 0x09f0 horizlinescan3 ? ??? -0x09f1 "─" EEK_SYMBOL_CATEGORY_LETTER # horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL -# 0x09f2 horizlinescan7 ? ??? -# 0x09f3 horizlinescan9 ? ??? -0x09f4 "├" EEK_SYMBOL_CATEGORY_LETTER # leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT -0x09f5 "┤" EEK_SYMBOL_CATEGORY_LETTER # rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT -0x09f6 "┴" EEK_SYMBOL_CATEGORY_LETTER # bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL -0x09f7 "┬" EEK_SYMBOL_CATEGORY_LETTER # topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -0x09f8 "│" EEK_SYMBOL_CATEGORY_LETTER # vertbar │ BOX DRAWINGS LIGHT VERTICAL -0x0aa1 " " EEK_SYMBOL_CATEGORY_LETTER # emspace   EM SPACE -0x0aa2 " " EEK_SYMBOL_CATEGORY_LETTER # enspace   EN SPACE -0x0aa3 " " EEK_SYMBOL_CATEGORY_LETTER # em3space   THREE-PER-EM SPACE -0x0aa4 " " EEK_SYMBOL_CATEGORY_LETTER # em4space   FOUR-PER-EM SPACE -0x0aa5 " " EEK_SYMBOL_CATEGORY_LETTER # digitspace   FIGURE SPACE -0x0aa6 " " EEK_SYMBOL_CATEGORY_LETTER # punctspace   PUNCTUATION SPACE -0x0aa7 " " EEK_SYMBOL_CATEGORY_LETTER # thinspace   THIN SPACE -0x0aa8 " " EEK_SYMBOL_CATEGORY_LETTER # hairspace   HAIR SPACE -0x0aa9 "—" EEK_SYMBOL_CATEGORY_LETTER # emdash — EM DASH -0x0aaa "–" EEK_SYMBOL_CATEGORY_LETTER # endash – EN DASH -# 0x0aac signifblank ? ??? -0x0aae "…" EEK_SYMBOL_CATEGORY_LETTER # ellipsis … HORIZONTAL ELLIPSIS -# 0x0aaf doubbaselinedot ? ??? -0x0ab0 "⅓" EEK_SYMBOL_CATEGORY_LETTER # onethird ⅓ VULGAR FRACTION ONE THIRD -0x0ab1 "⅔" EEK_SYMBOL_CATEGORY_LETTER # twothirds ⅔ VULGAR FRACTION TWO THIRDS -0x0ab2 "⅕" EEK_SYMBOL_CATEGORY_LETTER # onefifth ⅕ VULGAR FRACTION ONE FIFTH -0x0ab3 "⅖" EEK_SYMBOL_CATEGORY_LETTER # twofifths ⅖ VULGAR FRACTION TWO FIFTHS -0x0ab4 "⅗" EEK_SYMBOL_CATEGORY_LETTER # threefifths ⅗ VULGAR FRACTION THREE FIFTHS -0x0ab5 "⅘" EEK_SYMBOL_CATEGORY_LETTER # fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS -0x0ab6 "⅙" EEK_SYMBOL_CATEGORY_LETTER # onesixth ⅙ VULGAR FRACTION ONE SIXTH -0x0ab7 "⅚" EEK_SYMBOL_CATEGORY_LETTER # fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS -0x0ab8 "℅" EEK_SYMBOL_CATEGORY_LETTER # careof ℅ CARE OF -0x0abb "‒" EEK_SYMBOL_CATEGORY_LETTER # figdash ‒ FIGURE DASH -0x0abc "〈" EEK_SYMBOL_CATEGORY_LETTER # leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET -0x0abd "." EEK_SYMBOL_CATEGORY_LETTER # decimalpoint . FULL STOP -0x0abe "〉" EEK_SYMBOL_CATEGORY_LETTER # rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET -# 0x0abf marker ? ??? -0x0ac3 "⅛" EEK_SYMBOL_CATEGORY_LETTER # oneeighth ⅛ VULGAR FRACTION ONE EIGHTH -0x0ac4 "⅜" EEK_SYMBOL_CATEGORY_LETTER # threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS -0x0ac5 "⅝" EEK_SYMBOL_CATEGORY_LETTER # fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS -0x0ac6 "⅞" EEK_SYMBOL_CATEGORY_LETTER # seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS -0x0ac9 "™" EEK_SYMBOL_CATEGORY_LETTER # trademark ™ TRADE MARK SIGN -0x0aca "☓" EEK_SYMBOL_CATEGORY_LETTER # signaturemark ☓ SALTIRE -# 0x0acb trademarkincircle ? ??? -0x0acc "◁" EEK_SYMBOL_CATEGORY_LETTER # leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE -0x0acd "▷" EEK_SYMBOL_CATEGORY_LETTER # rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE -0x0ace "○" EEK_SYMBOL_CATEGORY_LETTER # emopencircle ○ WHITE CIRCLE -0x0acf "□" EEK_SYMBOL_CATEGORY_LETTER # emopenrectangle □ WHITE SQUARE -0x0ad0 "‘" EEK_SYMBOL_CATEGORY_LETTER # leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK -0x0ad1 "’" EEK_SYMBOL_CATEGORY_LETTER # rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK -0x0ad2 "“" EEK_SYMBOL_CATEGORY_LETTER # leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK -0x0ad3 "”" EEK_SYMBOL_CATEGORY_LETTER # rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK -0x0ad4 "℞" EEK_SYMBOL_CATEGORY_LETTER # prescription ℞ PRESCRIPTION TAKE -0x0ad6 "′" EEK_SYMBOL_CATEGORY_LETTER # minutes ′ PRIME -0x0ad7 "″" EEK_SYMBOL_CATEGORY_LETTER # seconds ″ DOUBLE PRIME -0x0ad9 "✝" EEK_SYMBOL_CATEGORY_LETTER # latincross ✝ LATIN CROSS -# 0x0ada hexagram ? ??? -0x0adb "▬" EEK_SYMBOL_CATEGORY_LETTER # filledrectbullet ▬ BLACK RECTANGLE -0x0adc "◀" EEK_SYMBOL_CATEGORY_LETTER # filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE -0x0add "▶" EEK_SYMBOL_CATEGORY_LETTER # filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE -0x0ade "●" EEK_SYMBOL_CATEGORY_LETTER # emfilledcircle ● BLACK CIRCLE -0x0adf "■" EEK_SYMBOL_CATEGORY_LETTER # emfilledrect ■ BLACK SQUARE -0x0ae0 "◦" EEK_SYMBOL_CATEGORY_LETTER # enopencircbullet ◦ WHITE BULLET -0x0ae1 "▫" EEK_SYMBOL_CATEGORY_LETTER # enopensquarebullet ▫ WHITE SMALL SQUARE -0x0ae2 "▭" EEK_SYMBOL_CATEGORY_LETTER # openrectbullet ▭ WHITE RECTANGLE -0x0ae3 "△" EEK_SYMBOL_CATEGORY_LETTER # opentribulletup △ WHITE UP-POINTING TRIANGLE -0x0ae4 "▽" EEK_SYMBOL_CATEGORY_LETTER # opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE -0x0ae5 "☆" EEK_SYMBOL_CATEGORY_LETTER # openstar ☆ WHITE STAR -0x0ae6 "•" EEK_SYMBOL_CATEGORY_LETTER # enfilledcircbullet • BULLET -0x0ae7 "▪" EEK_SYMBOL_CATEGORY_LETTER # enfilledsqbullet ▪ BLACK SMALL SQUARE -0x0ae8 "▲" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletup ▲ BLACK UP-POINTING TRIANGLE -0x0ae9 "▼" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE -0x0aea "☜" EEK_SYMBOL_CATEGORY_LETTER # leftpointer ☜ WHITE LEFT POINTING INDEX -0x0aeb "☞" EEK_SYMBOL_CATEGORY_LETTER # rightpointer ☞ WHITE RIGHT POINTING INDEX -0x0aec "♣" EEK_SYMBOL_CATEGORY_LETTER # club ♣ BLACK CLUB SUIT -0x0aed "♦" EEK_SYMBOL_CATEGORY_LETTER # diamond ♦ BLACK DIAMOND SUIT -0x0aee "♥" EEK_SYMBOL_CATEGORY_LETTER # heart ♥ BLACK HEART SUIT -0x0af0 "✠" EEK_SYMBOL_CATEGORY_LETTER # maltesecross ✠ MALTESE CROSS -0x0af1 "†" EEK_SYMBOL_CATEGORY_LETTER # dagger † DAGGER -0x0af2 "‡" EEK_SYMBOL_CATEGORY_LETTER # doubledagger ‡ DOUBLE DAGGER -0x0af3 "✓" EEK_SYMBOL_CATEGORY_LETTER # checkmark ✓ CHECK MARK -0x0af4 "✗" EEK_SYMBOL_CATEGORY_LETTER # ballotcross ✗ BALLOT X -0x0af5 "♯" EEK_SYMBOL_CATEGORY_LETTER # musicalsharp ♯ MUSIC SHARP SIGN -0x0af6 "♭" EEK_SYMBOL_CATEGORY_LETTER # musicalflat ♭ MUSIC FLAT SIGN -0x0af7 "♂" EEK_SYMBOL_CATEGORY_LETTER # malesymbol ♂ MALE SIGN -0x0af8 "♀" EEK_SYMBOL_CATEGORY_LETTER # femalesymbol ♀ FEMALE SIGN -0x0af9 "☎" EEK_SYMBOL_CATEGORY_LETTER # telephone ☎ BLACK TELEPHONE -0x0afa "⌕" EEK_SYMBOL_CATEGORY_LETTER # telephonerecorder ⌕ TELEPHONE RECORDER -0x0afb "℗" EEK_SYMBOL_CATEGORY_LETTER # phonographcopyright ℗ SOUND RECORDING COPYRIGHT -0x0afc "‸" EEK_SYMBOL_CATEGORY_LETTER # caret ‸ CARET -0x0afd "‚" EEK_SYMBOL_CATEGORY_LETTER # singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK -0x0afe "„" EEK_SYMBOL_CATEGORY_LETTER # doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK -# 0x0aff cursor ? ??? -0x0ba3 "<" EEK_SYMBOL_CATEGORY_LETTER # leftcaret < LESS-THAN SIGN -0x0ba6 ">" EEK_SYMBOL_CATEGORY_LETTER # rightcaret > GREATER-THAN SIGN -0x0ba8 "∨" EEK_SYMBOL_CATEGORY_LETTER # downcaret ∨ LOGICAL OR -0x0ba9 "∧" EEK_SYMBOL_CATEGORY_LETTER # upcaret ∧ LOGICAL AND -0x0bc0 "¯" EEK_SYMBOL_CATEGORY_LETTER # overbar ¯ MACRON -0x0bc2 "⊤" EEK_SYMBOL_CATEGORY_LETTER # downtack ⊤ DOWN TACK -0x0bc3 "∩" EEK_SYMBOL_CATEGORY_LETTER # upshoe ∩ INTERSECTION -0x0bc4 "⌊" EEK_SYMBOL_CATEGORY_LETTER # downstile ⌊ LEFT FLOOR -0x0bc6 "_" EEK_SYMBOL_CATEGORY_LETTER # underbar _ LOW LINE -0x0bca "∘" EEK_SYMBOL_CATEGORY_LETTER # jot ∘ RING OPERATOR -0x0bcc "⎕" EEK_SYMBOL_CATEGORY_LETTER # quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) -0x0bce "⊥" EEK_SYMBOL_CATEGORY_LETTER # uptack ⊥ UP TACK -0x0bcf "○" EEK_SYMBOL_CATEGORY_LETTER # circle ○ WHITE CIRCLE -0x0bd3 "⌈" EEK_SYMBOL_CATEGORY_LETTER # upstile ⌈ LEFT CEILING -0x0bd6 "∪" EEK_SYMBOL_CATEGORY_LETTER # downshoe ∪ UNION -0x0bd8 "⊃" EEK_SYMBOL_CATEGORY_LETTER # rightshoe ⊃ SUPERSET OF -0x0bda "⊂" EEK_SYMBOL_CATEGORY_LETTER # leftshoe ⊂ SUBSET OF -0x0bdc "⊣" EEK_SYMBOL_CATEGORY_LETTER # lefttack ⊣ LEFT TACK -0x0bfc "⊢" EEK_SYMBOL_CATEGORY_LETTER # righttack ⊢ RIGHT TACK -0x0cdf "‗" EEK_SYMBOL_CATEGORY_LETTER # hebrew_doublelowline ‗ DOUBLE LOW LINE -0x0ce0 "א" EEK_SYMBOL_CATEGORY_LETTER # hebrew_aleph א HEBREW LETTER ALEF -0x0ce1 "ב" EEK_SYMBOL_CATEGORY_LETTER # hebrew_bet ב HEBREW LETTER BET -0x0ce2 "ג" EEK_SYMBOL_CATEGORY_LETTER # hebrew_gimel ג HEBREW LETTER GIMEL -0x0ce3 "ד" EEK_SYMBOL_CATEGORY_LETTER # hebrew_dalet ד HEBREW LETTER DALET -0x0ce4 "ה" EEK_SYMBOL_CATEGORY_LETTER # hebrew_he ה HEBREW LETTER HE -0x0ce5 "ו" EEK_SYMBOL_CATEGORY_LETTER # hebrew_waw ו HEBREW LETTER VAV -0x0ce6 "ז" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zain ז HEBREW LETTER ZAYIN -0x0ce7 "ח" EEK_SYMBOL_CATEGORY_LETTER # hebrew_chet ח HEBREW LETTER HET -0x0ce8 "ט" EEK_SYMBOL_CATEGORY_LETTER # hebrew_tet ט HEBREW LETTER TET -0x0ce9 "י" EEK_SYMBOL_CATEGORY_LETTER # hebrew_yod י HEBREW LETTER YOD -0x0cea "ך" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalkaph ך HEBREW LETTER FINAL KAF -0x0ceb "כ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_kaph כ HEBREW LETTER KAF -0x0cec "ל" EEK_SYMBOL_CATEGORY_LETTER # hebrew_lamed ל HEBREW LETTER LAMED -0x0ced "ם" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalmem ם HEBREW LETTER FINAL MEM -0x0cee "מ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_mem מ HEBREW LETTER MEM -0x0cef "ן" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalnun ן HEBREW LETTER FINAL NUN -0x0cf0 "נ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_nun נ HEBREW LETTER NUN -0x0cf1 "ס" EEK_SYMBOL_CATEGORY_LETTER # hebrew_samech ס HEBREW LETTER SAMEKH -0x0cf2 "ע" EEK_SYMBOL_CATEGORY_LETTER # hebrew_ayin ע HEBREW LETTER AYIN -0x0cf3 "ף" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalpe ף HEBREW LETTER FINAL PE -0x0cf4 "פ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_pe פ HEBREW LETTER PE -0x0cf5 "ץ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalzade ץ HEBREW LETTER FINAL TSADI -0x0cf6 "צ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zade צ HEBREW LETTER TSADI -0x0cf7 "ק" EEK_SYMBOL_CATEGORY_LETTER # hebrew_qoph ק HEBREW LETTER QOF -0x0cf8 "ר" EEK_SYMBOL_CATEGORY_LETTER # hebrew_resh ר HEBREW LETTER RESH -0x0cf9 "ש" EEK_SYMBOL_CATEGORY_LETTER # hebrew_shin ש HEBREW LETTER SHIN -0x0cfa "ת" EEK_SYMBOL_CATEGORY_LETTER # hebrew_taw ת HEBREW LETTER TAV -0x0da1 "ก" EEK_SYMBOL_CATEGORY_LETTER # Thai_kokai ก THAI CHARACTER KO KAI -0x0da2 "ข" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhai ข THAI CHARACTER KHO KHAI -0x0da3 "ฃ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT -0x0da4 "ค" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhwai ค THAI CHARACTER KHO KHWAI -0x0da5 "ฅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhon ฅ THAI CHARACTER KHO KHON -0x0da6 "ฆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG -0x0da7 "ง" EEK_SYMBOL_CATEGORY_LETTER # Thai_ngongu ง THAI CHARACTER NGO NGU -0x0da8 "จ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochan จ THAI CHARACTER CHO CHAN -0x0da9 "ฉ" EEK_SYMBOL_CATEGORY_LETTER # Thai_choching ฉ THAI CHARACTER CHO CHING -0x0daa "ช" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochang ช THAI CHARACTER CHO CHANG -0x0dab "ซ" EEK_SYMBOL_CATEGORY_LETTER # Thai_soso ซ THAI CHARACTER SO SO -0x0dac "ฌ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochoe ฌ THAI CHARACTER CHO CHOE -0x0dad "ญ" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoying ญ THAI CHARACTER YO YING -0x0dae "ฎ" EEK_SYMBOL_CATEGORY_LETTER # Thai_dochada ฎ THAI CHARACTER DO CHADA -0x0daf "ฏ" EEK_SYMBOL_CATEGORY_LETTER # Thai_topatak ฏ THAI CHARACTER TO PATAK -0x0db0 "ฐ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothan ฐ THAI CHARACTER THO THAN -0x0db1 "ฑ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO -0x0db2 "ฒ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO -0x0db3 "ณ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonen ณ THAI CHARACTER NO NEN -0x0db4 "ด" EEK_SYMBOL_CATEGORY_LETTER # Thai_dodek ด THAI CHARACTER DO DEK -0x0db5 "ต" EEK_SYMBOL_CATEGORY_LETTER # Thai_totao ต THAI CHARACTER TO TAO -0x0db6 "ถ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothung ถ THAI CHARACTER THO THUNG -0x0db7 "ท" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothahan ท THAI CHARACTER THO THAHAN -0x0db8 "ธ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothong ธ THAI CHARACTER THO THONG -0x0db9 "น" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonu น THAI CHARACTER NO NU -0x0dba "บ" EEK_SYMBOL_CATEGORY_LETTER # Thai_bobaimai บ THAI CHARACTER BO BAIMAI -0x0dbb "ป" EEK_SYMBOL_CATEGORY_LETTER # Thai_popla ป THAI CHARACTER PO PLA -0x0dbc "ผ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophung ผ THAI CHARACTER PHO PHUNG -0x0dbd "ฝ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofa ฝ THAI CHARACTER FO FA -0x0dbe "พ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophan พ THAI CHARACTER PHO PHAN -0x0dbf "ฟ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofan ฟ THAI CHARACTER FO FAN -0x0dc0 "ภ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO -0x0dc1 "ม" EEK_SYMBOL_CATEGORY_LETTER # Thai_moma ม THAI CHARACTER MO MA -0x0dc2 "ย" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoyak ย THAI CHARACTER YO YAK -0x0dc3 "ร" EEK_SYMBOL_CATEGORY_LETTER # Thai_rorua ร THAI CHARACTER RO RUA -0x0dc4 "ฤ" EEK_SYMBOL_CATEGORY_LETTER # Thai_ru ฤ THAI CHARACTER RU -0x0dc5 "ล" EEK_SYMBOL_CATEGORY_LETTER # Thai_loling ล THAI CHARACTER LO LING -0x0dc6 "ฦ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lu ฦ THAI CHARACTER LU -0x0dc7 "ว" EEK_SYMBOL_CATEGORY_LETTER # Thai_wowaen ว THAI CHARACTER WO WAEN -0x0dc8 "ศ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosala ศ THAI CHARACTER SO SALA -0x0dc9 "ษ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sorusi ษ THAI CHARACTER SO RUSI -0x0dca "ส" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosua ส THAI CHARACTER SO SUA -0x0dcb "ห" EEK_SYMBOL_CATEGORY_LETTER # Thai_hohip ห THAI CHARACTER HO HIP -0x0dcc "ฬ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lochula ฬ THAI CHARACTER LO CHULA -0x0dcd "อ" EEK_SYMBOL_CATEGORY_LETTER # Thai_oang อ THAI CHARACTER O ANG -0x0dce "ฮ" EEK_SYMBOL_CATEGORY_LETTER # Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK -0x0dcf "ฯ" EEK_SYMBOL_CATEGORY_LETTER # Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI -0x0dd0 "ะ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraa ะ THAI CHARACTER SARA A -0x0dd1 "ั" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT -0x0dd2 "า" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaa า THAI CHARACTER SARA AA -0x0dd3 "ำ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraam ำ THAI CHARACTER SARA AM -0x0dd4 "ิ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarai ิ THAI CHARACTER SARA I -0x0dd5 "ี" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraii ี THAI CHARACTER SARA II -0x0dd6 "ึ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraue ึ THAI CHARACTER SARA UE -0x0dd7 "ื" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauee ื THAI CHARACTER SARA UEE -0x0dd8 "ุ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarau ุ THAI CHARACTER SARA U -0x0dd9 "ู" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauu ู THAI CHARACTER SARA UU -0x0dda "ฺ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phinthu ฺ THAI CHARACTER PHINTHU -0x0dde "฾" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat_maitho ฾ ??? -0x0ddf "฿" EEK_SYMBOL_CATEGORY_LETTER # Thai_baht ฿ THAI CURRENCY SYMBOL BAHT -0x0de0 "เ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarae เ THAI CHARACTER SARA E -0x0de1 "แ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraae แ THAI CHARACTER SARA AE -0x0de2 "โ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarao โ THAI CHARACTER SARA O -0x0de3 "ใ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN -0x0de4 "ไ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI -0x0de5 "ๅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO -0x0de6 "ๆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK -0x0de7 "็" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU -0x0de8 "่" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiek ่ THAI CHARACTER MAI EK -0x0de9 "้" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitho ้ THAI CHARACTER MAI THO -0x0dea "๊" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitri ๊ THAI CHARACTER MAI TRI -0x0deb "๋" EEK_SYMBOL_CATEGORY_LETTER # Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA -0x0dec "์" EEK_SYMBOL_CATEGORY_LETTER # Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT -0x0ded "ํ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nikhahit ํ THAI CHARACTER NIKHAHIT -0x0df0 "๐" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksun ๐ THAI DIGIT ZERO -0x0df1 "๑" EEK_SYMBOL_CATEGORY_LETTER # Thai_leknung ๑ THAI DIGIT ONE -0x0df2 "๒" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksong ๒ THAI DIGIT TWO -0x0df3 "๓" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksam ๓ THAI DIGIT THREE -0x0df4 "๔" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksi ๔ THAI DIGIT FOUR -0x0df5 "๕" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekha ๕ THAI DIGIT FIVE -0x0df6 "๖" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekhok ๖ THAI DIGIT SIX -0x0df7 "๗" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekchet ๗ THAI DIGIT SEVEN -0x0df8 "๘" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekpaet ๘ THAI DIGIT EIGHT -0x0df9 "๙" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekkao ๙ THAI DIGIT NINE -0x0ea1 "ㄱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK -0x0ea2 "ㄲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK -0x0ea3 "ㄳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS -0x0ea4 "ㄴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Nieun ㄴ HANGUL LETTER NIEUN -0x0ea5 "ㄵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC -0x0ea6 "ㄶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH -0x0ea7 "ㄷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT -0x0ea8 "ㄸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT -0x0ea9 "ㄹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Rieul ㄹ HANGUL LETTER RIEUL -0x0eaa "ㄺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK -0x0eab "ㄻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM -0x0eac "ㄼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP -0x0ead "ㄽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS -0x0eae "ㄾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH -0x0eaf "ㄿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH -0x0eb0 "ㅀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH -0x0eb1 "ㅁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Mieum ㅁ HANGUL LETTER MIEUM -0x0eb2 "ㅂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Pieub ㅂ HANGUL LETTER PIEUP -0x0eb3 "ㅃ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP -0x0eb4 "ㅄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS -0x0eb5 "ㅅ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Sios ㅅ HANGUL LETTER SIOS -0x0eb6 "ㅆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS -0x0eb7 "ㅇ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Ieung ㅇ HANGUL LETTER IEUNG -0x0eb8 "ㅈ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Jieuj ㅈ HANGUL LETTER CIEUC -0x0eb9 "ㅉ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC -0x0eba "ㅊ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH -0x0ebb "ㅋ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH -0x0ebc "ㅌ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Tieut ㅌ HANGUL LETTER THIEUTH -0x0ebd "ㅍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH -0x0ebe "ㅎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Hieuh ㅎ HANGUL LETTER HIEUH -0x0ebf "ㅏ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_A ㅏ HANGUL LETTER A -0x0ec0 "ㅐ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AE ㅐ HANGUL LETTER AE -0x0ec1 "ㅑ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YA ㅑ HANGUL LETTER YA -0x0ec2 "ㅒ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YAE ㅒ HANGUL LETTER YAE -0x0ec3 "ㅓ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EO ㅓ HANGUL LETTER EO -0x0ec4 "ㅔ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_E ㅔ HANGUL LETTER E -0x0ec5 "ㅕ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YEO ㅕ HANGUL LETTER YEO -0x0ec6 "ㅖ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YE ㅖ HANGUL LETTER YE -0x0ec7 "ㅗ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_O ㅗ HANGUL LETTER O -0x0ec8 "ㅘ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WA ㅘ HANGUL LETTER WA -0x0ec9 "ㅙ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WAE ㅙ HANGUL LETTER WAE -0x0eca "ㅚ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_OE ㅚ HANGUL LETTER OE -0x0ecb "ㅛ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YO ㅛ HANGUL LETTER YO -0x0ecc "ㅜ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_U ㅜ HANGUL LETTER U -0x0ecd "ㅝ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WEO ㅝ HANGUL LETTER WEO -0x0ece "ㅞ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WE ㅞ HANGUL LETTER WE -0x0ecf "ㅟ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WI ㅟ HANGUL LETTER WI -0x0ed0 "ㅠ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YU ㅠ HANGUL LETTER YU -0x0ed1 "ㅡ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EU ㅡ HANGUL LETTER EU -0x0ed2 "ㅢ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YI ㅢ HANGUL LETTER YI -0x0ed3 "ㅣ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_I ㅣ HANGUL LETTER I -0x0ed4 "ᆨ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK -0x0ed5 "ᆩ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK -0x0ed6 "ᆪ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS -0x0ed7 "ᆫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN -0x0ed8 "ᆬ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC -0x0ed9 "ᆭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH -0x0eda "ᆮ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT -0x0edb "ᆯ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL -0x0edc "ᆰ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK -0x0edd "ᆱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM -0x0ede "ᆲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP -0x0edf "ᆳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS -0x0ee0 "ᆴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH -0x0ee1 "ᆵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH -0x0ee2 "ᆶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH -0x0ee3 "ᆷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM -0x0ee4 "ᆸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP -0x0ee5 "ᆹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS -0x0ee6 "ᆺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS -0x0ee7 "ᆻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS -0x0ee8 "ᆼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG -0x0ee9 "ᆽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC -0x0eea "ᆾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH -0x0eeb "ᆿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH -0x0eec "ᇀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH -0x0eed "ᇁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH -0x0eee "ᇂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH -0x0eef "ㅭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH -0x0ef0 "ㅱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM -0x0ef1 "ㅸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP -0x0ef2 "ㅿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PanSios ㅿ HANGUL LETTER PANSIOS -# 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? -0x0ef4 "ㆄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH -0x0ef5 "ㆆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH -0x0ef6 "ㆍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeA ㆍ HANGUL LETTER ARAEA -0x0ef7 "ㆎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE -0x0ef8 "ᇫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS -# 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? -0x0efa "ᇹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH -0x0eff "₩" EEK_SYMBOL_CATEGORY_LETTER # Korean_Won ₩ WON SIGN -0x13bc "Œ" EEK_SYMBOL_CATEGORY_LETTER # OE Œ LATIN CAPITAL LIGATURE OE -0x13bd "œ" EEK_SYMBOL_CATEGORY_LETTER # oe œ LATIN SMALL LIGATURE OE -0x13be "Ÿ" EEK_SYMBOL_CATEGORY_LETTER # Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS -0x20a0 "₠" EEK_SYMBOL_CATEGORY_LETTER # EcuSign ₠ EURO-CURRENCY SIGN -0x20a1 "₡" EEK_SYMBOL_CATEGORY_LETTER # ColonSign ₡ COLON SIGN -0x20a2 "₢" EEK_SYMBOL_CATEGORY_LETTER # CruzeiroSign ₢ CRUZEIRO SIGN -0x20a3 "₣" EEK_SYMBOL_CATEGORY_LETTER # FFrancSign ₣ FRENCH FRANC SIGN -0x20a4 "₤" EEK_SYMBOL_CATEGORY_LETTER # LiraSign ₤ LIRA SIGN -0x20a5 "₥" EEK_SYMBOL_CATEGORY_LETTER # MillSign ₥ MILL SIGN -0x20a6 "₦" EEK_SYMBOL_CATEGORY_LETTER # NairaSign ₦ NAIRA SIGN -0x20a7 "₧" EEK_SYMBOL_CATEGORY_LETTER # PesetaSign ₧ PESETA SIGN -0x20a8 "₨" EEK_SYMBOL_CATEGORY_LETTER # RupeeSign ₨ RUPEE SIGN -0x20a9 "₩" EEK_SYMBOL_CATEGORY_LETTER # WonSign ₩ WON SIGN -0x20aa "₪" EEK_SYMBOL_CATEGORY_LETTER # NewSheqelSign ₪ NEW SHEQEL SIGN -0x20ab "₫" EEK_SYMBOL_CATEGORY_LETTER # DongSign ₫ DONG SIGN -0x20ac "€" EEK_SYMBOL_CATEGORY_LETTER # EuroSign € EURO SIGN - -# Following items added to GTK, not in the xterm table - -# Numeric keypad - -# 0xFF80 # Space * -0xFFAA "*" EEK_SYMBOL_CATEGORY_LETTER # Multiply * -0xFFAB "+" EEK_SYMBOL_CATEGORY_LETTER # Add * -0xFFAC "," EEK_SYMBOL_CATEGORY_LETTER # Separator * -0xFFAD "-" EEK_SYMBOL_CATEGORY_LETTER # Subtract * -0xFFAE "." EEK_SYMBOL_CATEGORY_LETTER # Decimal * -0xFFAF "/" EEK_SYMBOL_CATEGORY_LETTER # Divide * -0xFFB0 "0" EEK_SYMBOL_CATEGORY_LETTER # 0 * -0xFFB1 "1" EEK_SYMBOL_CATEGORY_LETTER # 1 * -0xFFB2 "2" EEK_SYMBOL_CATEGORY_LETTER # 2 * -0xFFB3 "3" EEK_SYMBOL_CATEGORY_LETTER # 3 * -0xFFB4 "4" EEK_SYMBOL_CATEGORY_LETTER # 4 * -0xFFB5 "5" EEK_SYMBOL_CATEGORY_LETTER # 5 * -0xFFB6 "6" EEK_SYMBOL_CATEGORY_LETTER # 6 * -0xFFB7 "7" EEK_SYMBOL_CATEGORY_LETTER # 7 * -0xFFB8 "8" EEK_SYMBOL_CATEGORY_LETTER # 8 * -0xFFB9 "9" EEK_SYMBOL_CATEGORY_LETTER # 9 * -0xFFBD "=" EEK_SYMBOL_CATEGORY_LETTER # Equal * - -# End numeric keypad diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index f1c5c3ac..3be54477 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -75,7 +75,6 @@ struct _EekboardContextServicePrivate { GHashTable *keyboard_hash; // a table of available keyboards, per layout // TODO: make use of repeating buttons - EekKey *repeat_key; guint repeat_timeout_id; gboolean repeat_triggered; @@ -432,10 +431,9 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass) * * An #EekKeyboard currently active in this context. */ - pspec = g_param_spec_object ("keyboard", + pspec = g_param_spec_pointer("keyboard", "Keyboard", "Keyboard", - EEK_TYPE_KEYBOARD, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_KEYBOARD, diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index 014f0dbc..1e89f780 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -73,7 +73,7 @@ struct _EekboardContextServiceClass { GObjectClass parent_class; /*< public >*/ - EekKeyboard *(*create_keyboard) (EekboardContextService *self, + struct squeek_view *(*create_keyboard) (EekboardContextService *self, const gchar *keyboard_type); void (*show_keyboard) (EekboardContextService *self); void (*hide_keyboard) (EekboardContextService *self); diff --git a/src/float_ord.rs b/src/float_ord.rs new file mode 100644 index 00000000..c27ac5e9 --- /dev/null +++ b/src/float_ord.rs @@ -0,0 +1,141 @@ +//! Order floating point numbers, into this ordering: +//! +//! NaN | -Infinity | x < 0 | -0 | +0 | x > 0 | +Infinity | NaN + +/* Adapted from https://github.com/notriddle/rust-float-ord revision e995165f + * maintained by Michael Howell + * licensed under MIT / Apache-2.0 licenses + */ + +extern crate core; + +use ::float_ord::core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use ::float_ord::core::hash::{Hash, Hasher}; +use ::float_ord::core::mem::transmute; + +/// A wrapper for floats, that implements total equality and ordering +/// and hashing. +#[derive(Clone, Copy)] +pub struct FloatOrd(pub T); + +macro_rules! float_ord_impl { + ($f:ident, $i:ident, $n:expr) => { + impl FloatOrd<$f> { + fn convert(self) -> $i { + let u = unsafe { transmute::<$f, $i>(self.0) }; + let bit = 1 << ($n - 1); + if u & bit == 0 { + u | bit + } else { + !u + } + } + } + impl PartialEq for FloatOrd<$f> { + fn eq(&self, other: &Self) -> bool { + self.convert() == other.convert() + } + } + impl Eq for FloatOrd<$f> {} + impl PartialOrd for FloatOrd<$f> { + fn partial_cmp(&self, other: &Self) -> Option { + self.convert().partial_cmp(&other.convert()) + } + } + impl Ord for FloatOrd<$f> { + fn cmp(&self, other: &Self) -> Ordering { + self.convert().cmp(&other.convert()) + } + } + impl Hash for FloatOrd<$f> { + fn hash(&self, state: &mut H) { + self.convert().hash(state); + } + } + } +} + +float_ord_impl!(f32, u32, 32); +float_ord_impl!(f64, u64, 64); + +/// Sort a slice of floats. +/// +/// # Allocation behavior +/// +/// This routine uses a quicksort implementation that does not heap allocate. +/// +/// # Example +/// +/// ``` +/// let mut v = [-5.0, 4.0, 1.0, -3.0, 2.0]; +/// +/// float_ord::sort(&mut v); +/// assert!(v == [-5.0, -3.0, 1.0, 2.0, 4.0]); +/// ``` +#[allow(dead_code)] +pub fn sort(v: &mut [T]) where FloatOrd: Ord { + let v_: &mut [FloatOrd] = unsafe { transmute(v) }; + v_.sort_unstable(); +} + +#[cfg(test)] +mod tests { + extern crate std; + + use self::std::collections::hash_map::DefaultHasher; + use self::std::hash::{Hash, Hasher}; + use super::FloatOrd; + + #[test] + fn test_ord() { + assert!(FloatOrd(1.0f64) < FloatOrd(2.0f64)); + assert!(FloatOrd(2.0f32) > FloatOrd(1.0f32)); + assert!(FloatOrd(1.0f64) == FloatOrd(1.0f64)); + assert!(FloatOrd(1.0f32) == FloatOrd(1.0f32)); + assert!(FloatOrd(0.0f64) > FloatOrd(-0.0f64)); + assert!(FloatOrd(0.0f32) > FloatOrd(-0.0f32)); + assert!(FloatOrd(::float_ord::core::f64::NAN) == FloatOrd(::float_ord::core::f64::NAN)); + assert!(FloatOrd(::float_ord::core::f32::NAN) == FloatOrd(::float_ord::core::f32::NAN)); + assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::NAN)); + assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::NAN)); + assert!(FloatOrd(-::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::INFINITY)); + assert!(FloatOrd(-::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::INFINITY)); + assert!(FloatOrd(::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::NAN)); + assert!(FloatOrd(::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::NAN)); + assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::INFINITY)); + assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::INFINITY)); + } + + fn hash(f: F) -> u64 { + let mut hasher = DefaultHasher::new(); + f.hash(&mut hasher); + hasher.finish() + } + + #[test] + fn test_hash() { + assert_ne!(hash(FloatOrd(0.0f64)), hash(FloatOrd(-0.0f64))); + assert_ne!(hash(FloatOrd(0.0f32)), hash(FloatOrd(-0.0f32))); + assert_eq!(hash(FloatOrd(-0.0f64)), hash(FloatOrd(-0.0f64))); + assert_eq!(hash(FloatOrd(0.0f32)), hash(FloatOrd(0.0f32))); + assert_ne!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(-::float_ord::core::f64::NAN))); + assert_ne!(hash(FloatOrd(::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN))); + assert_eq!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(::float_ord::core::f64::NAN))); + assert_eq!(hash(FloatOrd(-::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN))); + } + + #[test] + fn test_sort_nan() { + let nan = ::float_ord::core::f64::NAN; + let mut v = [-1.0, 5.0, 0.0, -0.0, nan, 1.5, nan, 3.7]; + super::sort(&mut v); + assert!(v[0] == -1.0); + assert!(v[1] == 0.0 && v[1].is_sign_negative()); + assert!(v[2] == 0.0 && !v[2].is_sign_negative()); + assert!(v[3] == 1.5); + assert!(v[4] == 3.7); + assert!(v[5] == 5.0); + assert!(v[6].is_nan()); + assert!(v[7].is_nan()); + } +} diff --git a/src/keyboard.h b/src/keyboard.h index ff336f5e..ef402e2f 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -15,9 +15,11 @@ void squeek_key_add_symbol(struct squeek_key* key, const char *tooltip); uint32_t squeek_key_is_pressed(struct squeek_key *key); void squeek_key_set_pressed(struct squeek_key *key, uint32_t pressed); +uint32_t squeek_key_is_locked(struct squeek_key *key); +void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed); uint32_t squeek_key_get_keycode(struct squeek_key *key); void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode); -struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key, uint32_t level); +struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key); const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key); #endif diff --git a/src/keyboard.rs b/src/keyboard.rs index a7be346e..5c7b203f 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -7,8 +7,16 @@ pub mod c { use super::*; use ::util::c::{ as_cstr, into_cstring }; + use std::cell::RefCell; use std::ffi::CString; use std::os::raw::c_char; + use std::ptr; + use std::rc::Rc; + + // traits + + use std::borrow::ToOwned; + // The following defined in C #[no_mangle] @@ -16,6 +24,44 @@ pub mod c { fn eek_keysym_from_name(name: *const c_char) -> u32; } + /// The wrapped structure for KeyState suitable for handling in C + /// Since C doesn't respect borrowing rules, + /// RefCell will enforce them dynamically (only 1 writer/many readers) + /// Rc is implied and will ensure timely dropping + #[repr(transparent)] + pub struct CKeyState(*const RefCell); + + impl Clone for CKeyState { + fn clone(&self) -> Self { + CKeyState(self.0.clone()) + } + } + + impl CKeyState { + pub fn wrap(state: Rc>) -> CKeyState { + CKeyState(Rc::into_raw(state)) + } + pub fn unwrap(self) -> Rc> { + unsafe { Rc::from_raw(self.0) } + } + fn to_owned(self) -> KeyState { + let rc = self.unwrap(); + let state = rc.borrow().to_owned(); + Rc::into_raw(rc); // Prevent dropping + state + } + fn borrow_mut(self, f: F) -> T where F: FnOnce(&mut KeyState) -> T { + let rc = self.unwrap(); + let ret = { + let mut state = rc.borrow_mut(); + f(&mut state) + }; + Rc::into_raw(rc); // Prevent dropping + ret + } + } + + // TODO: unwrapping // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers @@ -23,48 +69,59 @@ pub mod c { // so it should handle garbled strings in the future #[no_mangle] pub extern "C" - fn squeek_key_new(keycode: u32) -> *mut KeyState { - Box::into_raw(Box::new( + fn squeek_key_new(keycode: u32) -> CKeyState { + let state: Rc> = Rc::new(RefCell::new( KeyState { pressed: false, + locked: false, keycode: keycode, - symbols: Vec::new(), + symbol: None, } - )) + )); + CKeyState::wrap(state) } #[no_mangle] pub extern "C" - fn squeek_key_free(key: *mut KeyState) { - unsafe { Box::from_raw(key) }; // gets dropped + fn squeek_key_free(key: CKeyState) { + key.unwrap(); // reference dropped } #[no_mangle] pub extern "C" - fn squeek_key_is_pressed(key: *const KeyState) -> u32 { - let key = unsafe { &*key }; - return key.pressed as u32; + fn squeek_key_is_pressed(key: CKeyState) -> u32 { + //let key = unsafe { Rc::from_raw(key.0) }; + return key.to_owned().pressed as u32; } #[no_mangle] pub extern "C" - fn squeek_key_set_pressed(key: *mut KeyState, pressed: u32) { - let key = unsafe { &mut *key }; - key.pressed = pressed != 0; + fn squeek_key_set_pressed(key: CKeyState, pressed: u32) { + key.borrow_mut(|key| key.pressed = pressed != 0); } #[no_mangle] pub extern "C" - fn squeek_key_get_keycode(key: *const KeyState) -> u32 { - let key = unsafe { &*key }; - return key.keycode as u32; + fn squeek_key_is_locked(key: CKeyState) -> u32 { + return key.to_owned().locked as u32; } #[no_mangle] pub extern "C" - fn squeek_key_set_keycode(key: *mut KeyState, code: u32) { - let key = unsafe { &mut *key }; - key.keycode = code; + fn squeek_key_set_locked(key: CKeyState, locked: u32) { + key.borrow_mut(|key| key.locked = locked != 0); + } + + #[no_mangle] + pub extern "C" + fn squeek_key_get_keycode(key: CKeyState) -> u32 { + return key.to_owned().keycode as u32; + } + + #[no_mangle] + pub extern "C" + fn squeek_key_set_keycode(key: CKeyState, code: u32) { + key.borrow_mut(|key| key.keycode = code); } // TODO: this will receive data from the filesystem, @@ -72,7 +129,7 @@ pub mod c { #[no_mangle] pub extern "C" fn squeek_key_add_symbol( - key: *mut KeyState, + key: CKeyState, element: *const c_char, text_raw: *const c_char, keyval: u32, label: *const c_char, icon: *const c_char, @@ -94,14 +151,6 @@ pub mod c { } }); - let key = unsafe { &mut *key }; - - if key.symbols.len() > 0 { - eprintln!("Key {:?} already has a symbol defined", text); - return; - } - - let icon = into_cstring(icon) .unwrap_or_else(|e| { eprintln!("Icon name unreadable: {}", e); @@ -131,107 +180,121 @@ pub mod c { None }); - let symbol = match element.to_bytes() { - b"symbol" => Symbol { - action: Action::Submit { - text: text, - keys: Vec::new(), - }, - label: label, - tooltip: tooltip, - }, - b"keysym" => { - let keysym = XKeySym( - if keyval == 0 { - unsafe { eek_keysym_from_name(text_raw) } - } else { - keyval - } - ); - Symbol { - action: match KeySym::from_u32(keysym.0) { - KeySym::Shift => Action::SetLevel(1), - _ => Action::Submit { - text: text, - keys: vec![keysym], - } + + key.borrow_mut(|key| { + if let Some(_) = key.symbol { + eprintln!("Key {:?} already has a symbol defined", text); + return; + } + + key.symbol = Some(match element.to_bytes() { + b"symbol" => Symbol { + action: Action::Submit { + text: text, + keys: Vec::new(), }, label: label, tooltip: tooltip, - } - }, - _ => panic!("unsupported element type {:?}", element), - }; - - key.symbols.push(symbol); + }, + _ => panic!("unsupported element type {:?}", element), + }); + }); } #[no_mangle] pub extern "C" - fn squeek_key_get_symbol( - key: *const KeyState, index: u32 - ) -> *const symbol::Symbol { - let key = unsafe { &*key }; - let index = index as usize; - &key.symbols[ - if index < key.symbols.len() { index } else { 0 } - ] as *const symbol::Symbol + fn squeek_key_get_symbol(key: CKeyState) -> *const symbol::Symbol { + key.borrow_mut(|key| { + match key.symbol { + // This pointer stays after the function exits, + // so it must reference borrowed data and not any copy + Some(ref symbol) => symbol as *const symbol::Symbol, + None => ptr::null(), + } + }) } #[no_mangle] pub extern "C" fn squeek_key_to_keymap_entry( key_name: *const c_char, - key: *const KeyState, + key: CKeyState, ) -> *const c_char { let key_name = as_cstr(&key_name) .expect("Missing key name") .to_str() .expect("Bad key name"); - let key = unsafe { &*key }; - let symbol_names = key.symbols.iter() - .map(|symbol| { - match &symbol.action { - symbol::Action::Submit { text: Some(text), .. } => { - Some( - text.clone() - .into_string().expect("Bad symbol") - ) - }, - _ => None - } - }) - .collect::>(); + let symbol_name = match key.to_owned().symbol { + Some(ref symbol) => match &symbol.action { + symbol::Action::Submit { text: Some(text), .. } => { + Some( + text.clone() + .into_string().expect("Bad symbol") + ) + }, + _ => None + }, + None => { + eprintln!("Key {} has no symbol", key_name); + None + }, + }; - 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: {}", symbol_names.len()), + let inner = match symbol_name { + Some(name) => format!("[ {} ]", name), + _ => format!("[ ]"), }; CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner)) .expect("Couldn't convert string") .into_raw() } + + #[no_mangle] + pub extern "C" + fn squeek_key_get_action_name( + key_name: *const c_char, + key: CKeyState, + ) -> *const c_char { + let key_name = as_cstr(&key_name) + .expect("Missing key name") + .to_str() + .expect("Bad key name"); + + let symbol_name = match key.to_owned().symbol { + Some(ref symbol) => match &symbol.action { + symbol::Action::Submit { text: Some(text), .. } => { + Some( + text.clone() + .into_string().expect("Bad symbol") + ) + }, + _ => None + }, + None => { + eprintln!("Key {} has no symbol", key_name); + None + }, + }; + + let inner = match symbol_name { + Some(name) => format!("[ {} ]", name), + _ => format!("[ ]"), + }; + + CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner)) + .expect("Couldn't convert string") + .into_raw() + } + } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct KeyState { - pressed: bool, - keycode: u32, - symbols: Vec, + pub pressed: bool, + pub locked: bool, + pub keycode: u32, + // TODO: remove the optionality of a symbol + pub symbol: Option, } diff --git a/src/layout.h b/src/layout.h new file mode 100644 index 00000000..1b01af52 --- /dev/null +++ b/src/layout.h @@ -0,0 +1,75 @@ +#ifndef __LAYOUT_H +#define __LAYOUT_H + +#include +#include +#include "eek/eek-element.h" +#include "src/keyboard.h" + +struct squeek_button; +struct squeek_row; +struct squeek_view; + +struct squeek_row *squeek_row_new(int32_t angle); +struct squeek_button *squeek_row_create_button (struct squeek_row *row, + guint keycode, guint oref); +struct squeek_button *squeek_row_create_button_with_state(struct squeek_row *row, + struct squeek_button *source); +void squeek_row_set_angle(struct squeek_row *row, int32_t angle); +int32_t squeek_row_get_angle(const struct squeek_row*); + +EekBounds squeek_row_get_bounds(const struct squeek_row*); +void squeek_row_set_bounds(struct squeek_row* row, EekBounds bounds); + +uint32_t squeek_row_contains(struct squeek_row*, struct squeek_button *button); + +struct button_place squeek_view_find_key(struct squeek_view*, struct squeek_key *state); + +struct squeek_button *squeek_row_find_button_by_position(struct squeek_row *row, EekPoint point, EekPoint origin); + +typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data); +void squeek_row_foreach(struct squeek_row*, + ButtonCallback callback, + gpointer user_data); + +void squeek_row_free(struct squeek_row*); + +/* +struct squeek_button *squeek_buttons_find_by_position( + const struct squeek_buttons *buttons, + double x, double y, + double origin_x, double origin_y, + double angle); +void squeek_buttons_add(struct squeek_buttons*, const struct squeek_button* button); +void squeek_buttons_remove_key(struct squeek_buttons*, const struct squeek_key* key); +*/ + +struct squeek_button *squeek_button_new(uint32_t keycode, uint32_t oref); +struct squeek_button *squeek_button_new_with_state(const struct squeek_button* source); +uint32_t squeek_button_get_oref(const struct squeek_button*); +EekBounds squeek_button_get_bounds(const struct squeek_button*); +void squeek_button_set_bounds(struct squeek_button* button, EekBounds bounds); + +struct squeek_symbol *squeek_button_get_symbol ( + const struct squeek_button *button); +struct squeek_key *squeek_button_get_key(const struct squeek_button*); +uint32_t *squeek_button_has_key(const struct squeek_button* button, + const struct squeek_key *key); +void squeek_button_print(const struct squeek_button* button); + + +struct squeek_view *squeek_view_new(EekBounds bounds); +struct squeek_row *squeek_view_create_row(struct squeek_view *, int32_t angle); +EekBounds squeek_view_get_bounds(const struct squeek_view*); +void squeek_view_set_bounds(const struct squeek_view*, EekBounds bounds); + +typedef void (*RowCallback) (struct squeek_row *row, gpointer user_data); +void squeek_view_foreach(struct squeek_view*, + RowCallback callback, + gpointer user_data); + +struct squeek_row *squeek_view_get_row(struct squeek_view *view, + struct squeek_button *button); + +void squeek_row_place_buttons(struct squeek_row *row, LevelKeyboard *keyboard); +#endif diff --git a/src/layout.rs b/src/layout.rs new file mode 100644 index 00000000..a676c3fb --- /dev/null +++ b/src/layout.rs @@ -0,0 +1,638 @@ +use std::cell::RefCell; +use std::rc::Rc; +use std::vec::Vec; + +use ::keyboard::*; +use ::float_ord::FloatOrd; +use ::symbol::*; + +/// Gathers stuff defined in C or called by C +pub mod c { + use super::*; + + use std::os::raw::c_void; + use std::ptr; + + // The following defined in C + + #[repr(transparent)] + pub struct UserData(*const c_void); + + /// The index in the relevant outline table + #[repr(C)] + #[derive(Clone, Debug)] + pub struct OutlineRef(u32); + + /// Defined in eek-types.h + #[repr(C)] + #[derive(Clone, Debug)] + pub struct Point { + pub x: f64, + pub y: f64, + } + + /// Defined in eek-types.h + #[repr(C)] + #[derive(Clone, Debug)] + pub struct Bounds { + pub x: f64, + pub y: f64, + pub width: f64, + pub height: f64 + } + + type ButtonCallback = unsafe extern "C" fn(button: *mut ::layout::Button, data: *mut UserData); + type RowCallback = unsafe extern "C" fn(row: *mut ::layout::Row, data: *mut UserData); + + // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers + + #[no_mangle] + pub extern "C" + fn squeek_view_new(bounds: Bounds) -> *mut ::layout::View { + Box::into_raw(Box::new(::layout::View { + rows: Vec::new(), + bounds: bounds, + })) + } + + #[no_mangle] + pub extern "C" + fn squeek_view_get_bounds(view: *const ::layout::View) -> Bounds { + unsafe { &*view }.bounds.clone() + } + + #[no_mangle] + pub extern "C" + fn squeek_view_set_bounds(view: *mut ::layout::View, bounds: Bounds) { + unsafe { &mut *view }.bounds = bounds; + } + + /// Places a row into the view and returns a reference to it + #[no_mangle] + pub extern "C" + fn squeek_view_create_row( + view: *mut ::layout::View, + angle: i32, + ) -> *mut ::layout::Row { + let view = unsafe { &mut *view }; + + view.rows.push(Box::new(::layout::Row::new(angle))); + // Return the reference directly instead of a Box, it's not on the stack + // It will live as long as the Vec + let last_idx = view.rows.len() - 1; + // Caution: Box can't be returned directly, + // so returning a reference to its innards + view.rows[last_idx].as_mut() as *mut ::layout::Row + } + + #[no_mangle] + pub extern "C" + fn squeek_view_foreach( + view: *mut ::layout::View, + callback: RowCallback, + data: *mut UserData, + ) { + let view = unsafe { &mut *view }; + for row in view.rows.iter_mut() { + let row = row.as_mut() as *mut ::layout::Row; + unsafe { callback(row, data) }; + } + } + + + #[no_mangle] + pub extern "C" + fn squeek_row_new(angle: i32) -> *mut ::layout::Row { + Box::into_raw(Box::new(::layout::Row::new(angle))) + } + + /// Places a button into the row and returns a reference to it + #[no_mangle] + pub extern "C" + fn squeek_row_create_button( + row: *mut ::layout::Row, + keycode: u32, oref: u32 + ) -> *mut ::layout::Button { + let row = unsafe { &mut *row }; + let state: Rc> = Rc::new(RefCell::new( + ::keyboard::KeyState { + pressed: false, + locked: false, + keycode: keycode, + symbol: None, + } + )); + row.buttons.push(Box::new(::layout::Button { + oref: OutlineRef(oref), + bounds: None, + state: state, + })); + // Return the reference directly instead of a Box, it's not on the stack + // It will live as long as the Vec + let last_idx = row.buttons.len() - 1; + // Caution: Box can't be returned directly, + // so returning a reference to its innards + row.buttons[last_idx].as_mut() as *mut ::layout::Button + } + + /// Places a button into the row, copying its state, + /// and returns a reference to it + #[no_mangle] + pub extern "C" + fn squeek_row_create_button_with_state( + row: *mut ::layout::Row, + button: *const ::layout::Button, + ) -> *mut ::layout::Button { + let row = unsafe { &mut *row }; + let source = unsafe { &*button }; + row.buttons.push(Box::new(source.clone())); + // Return the reference directly instead of a Box, it's not on the stack + // It will live as long as the Vec + let last_idx = row.buttons.len() - 1; + // Caution: Box can't be returned directly, + // so returning a reference to its innards directly + row.buttons[last_idx].as_mut() as *mut ::layout::Button + } + + #[no_mangle] + pub extern "C" + fn squeek_row_set_angle(row: *mut ::layout::Row, angle: i32) { + let row = unsafe { &mut *row }; + row.angle = angle; + } + + #[no_mangle] + pub extern "C" + fn squeek_row_get_angle(row: *const ::layout::Row) -> i32 { + let row = unsafe { &*row }; + row.angle + } + + #[no_mangle] + pub extern "C" + fn squeek_row_get_bounds(row: *const ::layout::Row) -> Bounds { + let row = unsafe { &*row }; + match &row.bounds { + Some(bounds) => bounds.clone(), + None => panic!("Row doesn't have any bounds yet"), + } + } + + /// Set bounds by consuming the value + #[no_mangle] + pub extern "C" + fn squeek_row_set_bounds(row: *mut ::layout::Row, bounds: Bounds) { + let row = unsafe { &mut *row }; + row.bounds = Some(bounds); + } + + #[no_mangle] + pub extern "C" + fn squeek_row_foreach( + row: *mut ::layout::Row, + callback: ButtonCallback, + data: *mut UserData, + ) { + let row = unsafe { &mut *row }; + for button in row.buttons.iter_mut() { + let button = button.as_mut() as *mut ::layout::Button; + unsafe { callback(button, data) }; + } + } + + #[no_mangle] + pub extern "C" + fn squeek_row_free(row: *mut ::layout::Row) { + unsafe { Box::from_raw(row) }; // gets dropped + } + + #[no_mangle] + pub extern "C" + fn squeek_button_new(keycode: u32, oref: u32) -> *mut ::layout::Button { + let state: Rc> = Rc::new(RefCell::new( + ::keyboard::KeyState { + pressed: false, + locked: false, + keycode: keycode, + symbol: None, + } + )); + Box::into_raw(Box::new(::layout::Button { + oref: OutlineRef(oref), + bounds: None, + state: state, + })) + } + + #[no_mangle] + pub extern "C" + fn squeek_button_new_with_state(source: *mut ::layout::Button) -> *mut ::layout::Button { + let source = unsafe { &*source }; + let button = Box::new(source.clone()); + Box::into_raw(button) + } + + #[no_mangle] + pub extern "C" + fn squeek_button_get_oref(button: *const ::layout::Button) -> u32 { + let button = unsafe { &*button }; + button.oref.0 + } + + // Bounds transparently mapped to C, therefore no pointer needed + + #[no_mangle] + pub extern "C" + fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds { + let button = unsafe { &*button }; + match &button.bounds { + Some(bounds) => bounds.clone(), + None => panic!("Button doesn't have any bounds yet"), + } + } + + /// Set bounds by consuming the value + #[no_mangle] + pub extern "C" + fn squeek_button_set_bounds(button: *mut ::layout::Button, bounds: Bounds) { + let button = unsafe { &mut *button }; + button.bounds = Some(bounds); + } + + /// Borrow a new reference to key state. Doesn't need freeing + #[no_mangle] + pub extern "C" + fn squeek_button_get_key( + button: *const ::layout::Button + ) -> ::keyboard::c::CKeyState { + let button = unsafe { &*button }; + ::keyboard::c::CKeyState::wrap(button.state.clone()) + } + + /// Really should just return the label + #[no_mangle] + pub extern "C" + fn squeek_button_get_symbol( + button: *const ::layout::Button, + ) -> *const Symbol { + let button = unsafe { &*button }; + let state = button.state.borrow(); + match state.symbol { + Some(ref symbol) => symbol as *const Symbol, + None => ptr::null(), + } + } + + #[no_mangle] + pub extern "C" + fn squeek_button_has_key( + button: *const ::layout::Button, + state: ::keyboard::c::CKeyState, + ) -> u32 { + let button = unsafe { &*button }; + let state = state.unwrap(); + let equal = Rc::ptr_eq(&button.state, &state); + Rc::into_raw(state); // Prevent dropping + equal as u32 + } + + #[no_mangle] + pub extern "C" + fn squeek_button_print(button: *const ::layout::Button) { + let button = unsafe { &*button }; + println!("{:?}", button); + } + + /// Entry points for more complex procedures and algoithms which span multiple modules + mod procedures { + use super::*; + + #[repr(transparent)] + pub struct LevelKeyboard(*const c_void); + + #[repr(C)] + #[derive(PartialEq, Debug)] + pub struct ButtonPlace { + row: *const Row, + button: *const Button, + } + + #[no_mangle] + extern "C" { + fn eek_get_outline_size( + keyboard: *const LevelKeyboard, + outline: u32 + ) -> Bounds; + + /// Checks if point falls within bounds, + /// which are relative to origin and rotated by angle (I think) + fn eek_are_bounds_inside (bounds: Bounds, + point: Point, + origin: Point, + angle: i32 + ) -> u32; + } + + fn squeek_buttons_get_outlines( + buttons: &Vec>, + keyboard: *const LevelKeyboard, + ) -> Vec { + buttons.iter().map(|button| { + unsafe { eek_get_outline_size(keyboard, button.oref.0) } + }).collect() + } + + /// Places each button in order, starting from 0 on the left, + /// keeping the spacing. + /// Sizes each button according to outline dimensions. + /// Sets the row size correctly + #[no_mangle] + pub extern "C" + fn squeek_row_place_buttons( + row: *mut ::layout::Row, + keyboard: *const LevelKeyboard, + ) { + let row = unsafe { &mut *row }; + + let sizes = squeek_buttons_get_outlines(&row.buttons, keyboard); + + row.place_buttons_with_sizes(sizes); + } + + #[no_mangle] + pub extern "C" + fn squeek_row_find_button_by_position( + row: *mut Row, point: Point, origin: Point + ) -> *mut Button { + let row = unsafe { &mut *row }; + let row_bounds = row.bounds + .as_ref().expect("Missing bounds on row"); + let origin = Point { + x: origin.x + row_bounds.x, + y: origin.y + row_bounds.y, + }; + let angle = row.angle; + let result = row.buttons.iter_mut().find(|button| { + let bounds = button.bounds + .as_ref().expect("Missing bounds on button") + .clone(); + let point = point.clone(); + let origin = origin.clone(); + unsafe { + eek_are_bounds_inside(bounds, point, origin, angle) == 1 + } + }); + + match result { + Some(button) => button.as_mut() as *mut Button, + None => ptr::null_mut(), + } + } + + fn squeek_row_contains(row: &Row, needle: *const Button) -> bool { + row.buttons.iter().position( + // TODO: wrap Button properly in Rc; this comparison is unreliable + |button| button.as_ref() as *const ::layout::Button == needle + ).is_some() + } + + #[no_mangle] + pub extern "C" + fn squeek_view_get_row( + view: *mut View, + needle: *const ::layout::Button, + ) -> *mut Row { + let view = unsafe { &mut *view }; + let result = view.rows.iter_mut().find(|row| { + squeek_row_contains(row, needle) + }); + match result { + Some(row) => row.as_mut() as *mut Row, + None => ptr::null_mut(), + } + } + + #[no_mangle] + pub extern "C" + fn squeek_view_find_key( + view: *const View, + needle: ::keyboard::c::CKeyState, + ) -> ButtonPlace { + let view = unsafe { &*view }; + let state = needle.unwrap(); + + let paths = ::layout::procedures::find_key_paths(view, &state); + + // Iterators used up, can turn the reference back into pointer + Rc::into_raw(state); + + // Can only return 1 entry back to C + let (row, button) = match paths.get(0) { + Some((row, button)) => ( + row.as_ref() as *const Row, + button.as_ref() as *const Button, + ), + None => ( ptr::null(), ptr::null() ), + }; + ButtonPlace { row, button } + } + + #[cfg(test)] + mod test { + use super::*; + + #[test] + fn row_has_button() { + let mut row = Row::new(0); + let button = squeek_row_create_button(&mut row as *mut Row, 0, 0); + assert_eq!(squeek_row_contains(&row, button), true); + let shared_button = squeek_row_create_button_with_state( + &mut row as *mut Row, + button + ); + assert_eq!(squeek_row_contains(&row, shared_button), true); + let row = Row::new(0); + assert_eq!(squeek_row_contains(&row, button), false); + } + + #[test] + fn view_has_button() { + let state = Rc::new(RefCell::new(::keyboard::KeyState { + pressed: false, + locked: false, + keycode: 0, + symbol: None, + })); + let state_clone = ::keyboard::c::CKeyState::wrap(state.clone()); + + let button = Box::new(Button { + oref: OutlineRef(0), + bounds: None, + state: state, + }); + let button_ptr = button.as_ref() as *const Button; + + let row = Box::new(Row { + buttons: vec!(button), + angle: 0, + bounds: None + }); + let row_ptr = row.as_ref() as *const Row; + + let view = View { + bounds: Bounds { + x: 0f64, y: 0f64, + width: 0f64, height: 0f64 + }, + rows: vec!(row), + }; + + assert_eq!( + squeek_view_find_key( + &view as *const View, + state_clone.clone(), + ), + ButtonPlace { + row: row_ptr, + button: button_ptr, + } + ); + + let view = View { + bounds: Bounds { + x: 0f64, y: 0f64, + width: 0f64, height: 0f64 + }, + rows: Vec::new(), + }; + assert_eq!( + squeek_view_find_key( + &view as *const View, + state_clone.clone() + ), + ButtonPlace { + row: ptr::null(), + button: ptr::null(), + } + ); + } + } + } + + #[cfg(test)] + mod test { + use super::*; + + #[test] + fn button_has_key() { + let button = squeek_button_new(0, 0); + let state = squeek_button_get_key(button); + assert_eq!(squeek_button_has_key(button, state.clone()), 1); + let other_button = squeek_button_new(0, 0); + assert_eq!(squeek_button_has_key(other_button, state.clone()), 0); + let other_state = ::keyboard::c::squeek_key_new(0); + assert_eq!(squeek_button_has_key(button, other_state), 0); + let shared_button = squeek_button_new_with_state(button); + assert_eq!(squeek_button_has_key(shared_button, state), 1); + } + } +} + +/// The graphical representation of a button +#[derive(Clone, Debug)] +pub struct Button { + oref: c::OutlineRef, + /// TODO: abolish Option, buttons should be created with bounds fully formed + bounds: Option, + /// current state, shared with other buttons + pub state: Rc>, +} + + +const BUTTON_SPACING: f64 = 4.0; + +/// The graphical representation of a row of buttons +pub struct Row { + buttons: Vec>, + /// Angle is not really used anywhere... + angle: i32, + bounds: Option, +} + +impl Row { + fn new(angle: i32) -> Row { + Row { + buttons: Vec::new(), + angle: angle, + bounds: None, + } + } + fn place_buttons_with_sizes(&mut self, outlines: Vec) { + let max_height = outlines.iter().map( + |bounds| FloatOrd(bounds.height) + ).max() + .unwrap_or(FloatOrd(0f64)) + .0; + + let mut acc = 0f64; + let x_offsets: Vec = outlines.iter().map(|outline| { + acc += outline.x; // account for offset outlines + let out = acc; + acc += outline.width + BUTTON_SPACING; + out + }).collect(); + + let total_width = acc; + + for ((mut button, outline), offset) + in &mut self.buttons + .iter_mut() + .zip(outlines) + .zip(x_offsets) { + button.bounds = Some(c::Bounds { + x: offset, + ..outline + }); + } + + let old_row_bounds = self.bounds.as_ref().unwrap().clone(); + self.bounds = Some(c::Bounds { + // FIXME: do centering of each row based on keyboard dimensions, + // one level up the iterators + // now centering by comparing previous width to the new, + // calculated one + x: (old_row_bounds.width - total_width) / 2f64, + width: total_width, + height: max_height, + ..old_row_bounds + }); + } +} + +pub struct View { + bounds: c::Bounds, + rows: Vec>, +} + +mod procedures { + use super::*; + + type Path<'v> = (&'v Box, &'v Box