Add keyboard selection dialog to preferences.
This commit is contained in:
		@ -256,7 +256,6 @@ Build options:
 | 
			
		||||
  Build shared libs         $enable_shared
 | 
			
		||||
  Build static libs         $enable_static
 | 
			
		||||
  CFLAGS                    $CFLAGS
 | 
			
		||||
  GTK version               $with_gtk
 | 
			
		||||
  Build Vala binding        $enable_vala
 | 
			
		||||
  Sound support             $enable_libcanberra
 | 
			
		||||
  Build document            $enable_gtk_doc
 | 
			
		||||
 | 
			
		||||
@ -119,7 +119,7 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    GtkAllocation allocation;
 | 
			
		||||
    EekColor background;
 | 
			
		||||
    GList *head;
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_get_allocation (self, &allocation);
 | 
			
		||||
 | 
			
		||||
@ -164,16 +164,18 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    /* redraw pressed key */
 | 
			
		||||
    head = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (; head; head = g_list_next (head)) {
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        render_pressed_key (self, head->data);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    /* redraw locked key */
 | 
			
		||||
    head = eek_keyboard_get_locked_keys (priv->keyboard);
 | 
			
		||||
    for (; head; head = g_list_next (head)) {
 | 
			
		||||
    list = eek_keyboard_get_locked_keys (priv->keyboard);
 | 
			
		||||
    for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        render_locked_key (self, ((EekModifierKey *)head->data)->key);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
@ -213,16 +215,12 @@ eek_gtk_keyboard_real_button_release_event (GtkWidget      *self,
 | 
			
		||||
                                            GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    /* Make a copy of HEAD before sending "released" signal on
 | 
			
		||||
       elements, so that the default handler of
 | 
			
		||||
       EekKeyboard::key-released signal can remove elements from its
 | 
			
		||||
       internal copy */
 | 
			
		||||
    head = g_list_copy (head);
 | 
			
		||||
    for (; head; head = g_list_next (head))
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (head = list; head; head = g_list_next (head))
 | 
			
		||||
        g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
    g_list_free (head);
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -238,21 +236,17 @@ eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
                                             (gdouble)event->x,
 | 
			
		||||
                                             (gdouble)event->y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
        gboolean found = FALSE;
 | 
			
		||||
 | 
			
		||||
        /* Make a copy of HEAD before sending "cancelled" signal on
 | 
			
		||||
           elements, so that the default handler of
 | 
			
		||||
           EekKeyboard::key-cancelled signal can remove elements from its
 | 
			
		||||
           internal copy */
 | 
			
		||||
        head = g_list_copy (head);
 | 
			
		||||
        for (; head; head = g_list_next (head)) {
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            if (head->data == key)
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            else
 | 
			
		||||
                g_signal_emit_by_name (head->data, "cancelled", priv->keyboard);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (head);
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        if (!found)
 | 
			
		||||
            g_signal_emit_by_name (key, "pressed", priv->keyboard);
 | 
			
		||||
@ -266,16 +260,16 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        /* Make a copy of HEAD before sending "released" signal on
 | 
			
		||||
           elements, so that the default handler of
 | 
			
		||||
           EekKeyboard::key-released signal can remove elements from its
 | 
			
		||||
           internal copy */
 | 
			
		||||
        head = g_list_copy (head);
 | 
			
		||||
        for (; head; head = g_list_next (head))
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head))
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
        g_list_free (head);
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->unmap (self);
 | 
			
		||||
@ -363,12 +357,13 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
            
 | 
			
		||||
        GList *head;
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        head = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (; head; head = g_list_next (head)) {
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
 | 
			
		||||
@ -74,6 +74,22 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    EekModifierType alt_gr_mask;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
 | 
			
		||||
                    eek_modifier_key_copy, eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
EekModifierKey *
 | 
			
		||||
eek_modifier_key_copy (EekModifierKey *modkey)
 | 
			
		||||
{
 | 
			
		||||
    return g_slice_dup (EekModifierKey, modkey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_modifier_key_free (EekModifierKey *modkey)
 | 
			
		||||
{
 | 
			
		||||
    g_object_unref (modkey->key);
 | 
			
		||||
    g_slice_free (EekModifierKey, modkey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_pressed (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
@ -240,7 +256,7 @@ set_modifiers_with_key (EekKeyboard    *self,
 | 
			
		||||
        if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
			
		||||
            EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
			
		||||
            modifier_key->modifiers = enabled;
 | 
			
		||||
            modifier_key->key = key;
 | 
			
		||||
            modifier_key->key = g_object_ref (key);
 | 
			
		||||
            priv->locked_keys =
 | 
			
		||||
                g_list_prepend (priv->locked_keys, modifier_key);
 | 
			
		||||
            g_signal_emit_by_name (modifier_key->key, "locked");
 | 
			
		||||
@ -356,7 +372,8 @@ eek_keyboard_finalize (GObject *object)
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    g_list_free (priv->pressed_keys);
 | 
			
		||||
    g_list_free (priv->locked_keys);
 | 
			
		||||
    g_list_free_full (priv->locked_keys,
 | 
			
		||||
                      (GDestroyNotify) eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
@ -810,7 +827,7 @@ GList *
 | 
			
		||||
eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return keyboard->priv->pressed_keys;
 | 
			
		||||
    return g_list_copy (keyboard->priv->pressed_keys);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -825,5 +842,5 @@ GList *
 | 
			
		||||
eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return keyboard->priv->locked_keys;
 | 
			
		||||
    return g_list_copy (keyboard->priv->locked_keys);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -183,5 +183,10 @@ GList              *eek_keyboard_get_pressed_keys
 | 
			
		||||
GList              *eek_keyboard_get_locked_keys
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
EekModifierKey     *eek_modifier_key_copy
 | 
			
		||||
                                     (EekModifierKey     *modkey);
 | 
			
		||||
void                eek_modifier_key_free
 | 
			
		||||
                                     (EekModifierKey      *modkey);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -56,11 +56,13 @@ struct _EekXmlLayoutPrivate
 | 
			
		||||
    EekXmlKeyboardDesc *desc;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE(EekXmlKeyboardDesc, eek_xml_keyboard_desc, eek_xml_keyboard_desc_copy, eek_xml_keyboard_desc_free);
 | 
			
		||||
 | 
			
		||||
#define BUFSIZE	8192
 | 
			
		||||
 | 
			
		||||
static GSList       *parse_keyboards (const gchar         *path,
 | 
			
		||||
static GList        *parse_keyboards (const gchar         *path,
 | 
			
		||||
                                      GError             **error);
 | 
			
		||||
static GSList       *parse_prerequisites
 | 
			
		||||
static GList        *parse_prerequisites
 | 
			
		||||
                                     (const gchar         *path,
 | 
			
		||||
                                      GError             **error);
 | 
			
		||||
static gboolean      parse_geometry  (const gchar         *path,
 | 
			
		||||
@ -69,7 +71,7 @@ static gboolean      parse_geometry  (const gchar         *path,
 | 
			
		||||
static gboolean      parse_symbols_with_prerequisites
 | 
			
		||||
                                     (const gchar         *name,
 | 
			
		||||
                                      EekKeyboard         *keyboard,
 | 
			
		||||
                                      GSList             **loaded,
 | 
			
		||||
                                      GList             **loaded,
 | 
			
		||||
                                      GError             **error);
 | 
			
		||||
static gboolean      parse_symbols   (const gchar         *path,
 | 
			
		||||
                                      EekKeyboard         *keyboard,
 | 
			
		||||
@ -107,7 +109,7 @@ keyboard_desc_free (EekXmlKeyboardDesc *desc)
 | 
			
		||||
struct _KeyboardsParseData {
 | 
			
		||||
    GSList *element_stack;
 | 
			
		||||
 | 
			
		||||
    GSList *keyboards;
 | 
			
		||||
    GList *keyboards;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _KeyboardsParseData KeyboardsParseData;
 | 
			
		||||
 | 
			
		||||
@ -120,7 +122,7 @@ keyboards_parse_data_new (void)
 | 
			
		||||
static void
 | 
			
		||||
keyboards_parse_data_free (KeyboardsParseData *data)
 | 
			
		||||
{
 | 
			
		||||
    g_slist_free_full (data->keyboards, (GDestroyNotify) keyboard_desc_free);
 | 
			
		||||
    g_list_free_full (data->keyboards, (GDestroyNotify) keyboard_desc_free);
 | 
			
		||||
    g_slice_free (KeyboardsParseData, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -150,7 +152,7 @@ keyboards_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        EekXmlKeyboardDesc *desc = g_slice_new0 (EekXmlKeyboardDesc);
 | 
			
		||||
        const gchar *attribute;
 | 
			
		||||
 | 
			
		||||
        data->keyboards = g_slist_prepend (data->keyboards, desc);
 | 
			
		||||
        data->keyboards = g_list_prepend (data->keyboards, desc);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "id");
 | 
			
		||||
@ -821,7 +823,7 @@ struct _PrerequisitesParseData {
 | 
			
		||||
    GSList *element_stack;
 | 
			
		||||
    GString *text;
 | 
			
		||||
 | 
			
		||||
    GSList *prerequisites;
 | 
			
		||||
    GList *prerequisites;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _PrerequisitesParseData PrerequisitesParseData;
 | 
			
		||||
 | 
			
		||||
@ -836,7 +838,7 @@ prerequisites_parse_data_new (void)
 | 
			
		||||
static void
 | 
			
		||||
prerequisites_parse_data_free (PrerequisitesParseData *data)
 | 
			
		||||
{
 | 
			
		||||
    g_slist_free_full (data->prerequisites, g_free);
 | 
			
		||||
    g_list_free_full (data->prerequisites, g_free);
 | 
			
		||||
    g_string_free (data->text, TRUE);
 | 
			
		||||
    g_slice_free (PrerequisitesParseData, data);
 | 
			
		||||
}
 | 
			
		||||
@ -877,7 +879,7 @@ prerequisites_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    g_slist_free1 (head);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "include") == 0) {
 | 
			
		||||
        data->prerequisites = g_slist_append (data->prerequisites,
 | 
			
		||||
        data->prerequisites = g_list_append (data->prerequisites,
 | 
			
		||||
                                              g_strndup (data->text->str,
 | 
			
		||||
                                                         data->text->len));
 | 
			
		||||
    }
 | 
			
		||||
@ -910,7 +912,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    gchar *filename, *path;
 | 
			
		||||
    GSList *loaded;
 | 
			
		||||
    GList *loaded;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -935,15 +937,13 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekKey *key = eek_keyboard_find_key_by_keycode (keyboard,
 | 
			
		||||
                                                    149);
 | 
			
		||||
    /* Read symbols information. */
 | 
			
		||||
    loaded = NULL;
 | 
			
		||||
    retval = parse_symbols_with_prerequisites (layout->priv->desc->symbols,
 | 
			
		||||
                                               keyboard,
 | 
			
		||||
                                               &loaded,
 | 
			
		||||
                                               &error);
 | 
			
		||||
    g_slist_free_full (loaded, g_free);
 | 
			
		||||
    g_list_free_full (loaded, g_free);
 | 
			
		||||
    if (!retval) {
 | 
			
		||||
        g_object_unref (keyboard);
 | 
			
		||||
        g_warning ("can't parse symbols file %s: %s",
 | 
			
		||||
@ -1057,7 +1057,7 @@ initable_init (GInitable    *initable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (initable);
 | 
			
		||||
    GSList *keyboards, *p;
 | 
			
		||||
    GList *keyboards, *p;
 | 
			
		||||
    gchar *path;
 | 
			
		||||
    EekXmlKeyboardDesc *desc;
 | 
			
		||||
 | 
			
		||||
@ -1081,10 +1081,10 @@ initable_init (GInitable    *initable,
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboards = g_slist_remove_link (keyboards, p);
 | 
			
		||||
    keyboards = g_list_remove_link (keyboards, p);
 | 
			
		||||
    layout->priv->desc = p->data;
 | 
			
		||||
    g_slist_free_1 (p);
 | 
			
		||||
    g_slist_free_full (keyboards, (GDestroyNotify) keyboard_desc_free);
 | 
			
		||||
    g_list_free_1 (p);
 | 
			
		||||
    g_list_free_full (keyboards, (GDestroyNotify) keyboard_desc_free);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -1095,14 +1095,34 @@ initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
    initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eek_xml_layout_list_keyboards (void)
 | 
			
		||||
GList *
 | 
			
		||||
eek_xml_list_keyboards (void)
 | 
			
		||||
{
 | 
			
		||||
    gchar *path;
 | 
			
		||||
    GSList *keyboards;
 | 
			
		||||
    GList *keyboards;
 | 
			
		||||
 | 
			
		||||
    path = g_build_filename (KEYBOARDSDIR, "keyboards.xml", NULL);
 | 
			
		||||
    return parse_keyboards (path, NULL);
 | 
			
		||||
    keyboards = parse_keyboards (path, NULL);
 | 
			
		||||
    g_free (path);
 | 
			
		||||
    return keyboards;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekXmlKeyboardDesc *
 | 
			
		||||
eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc)
 | 
			
		||||
{
 | 
			
		||||
    return g_slice_dup (EekXmlKeyboardDesc, desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
 | 
			
		||||
{
 | 
			
		||||
    g_free (desc->id);
 | 
			
		||||
    g_free (desc->name);
 | 
			
		||||
    g_free (desc->geometry);
 | 
			
		||||
    g_free (desc->symbols);
 | 
			
		||||
    g_free (desc->language);
 | 
			
		||||
    g_free (desc->longname);
 | 
			
		||||
    g_slice_free (EekXmlKeyboardDesc, desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@ -1164,11 +1184,11 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
static gboolean
 | 
			
		||||
parse_symbols_with_prerequisites (const gchar *name,
 | 
			
		||||
                                  EekKeyboard *keyboard,
 | 
			
		||||
                                  GSList     **loaded,
 | 
			
		||||
                                  GList     **loaded,
 | 
			
		||||
                                  GError     **error)
 | 
			
		||||
{
 | 
			
		||||
    gchar *filename, *path;
 | 
			
		||||
    GSList *prerequisites, *p;
 | 
			
		||||
    GList *prerequisites, *p;
 | 
			
		||||
    GError *prerequisites_error;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -1182,7 +1202,7 @@ parse_symbols_with_prerequisites (const gchar *name,
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    *loaded = g_slist_prepend (*loaded, g_strdup (name));
 | 
			
		||||
    *loaded = g_list_prepend (*loaded, g_strdup (name));
 | 
			
		||||
 | 
			
		||||
    filename = g_strdup_printf ("%s.xml", name);
 | 
			
		||||
    path = g_build_filename (KEYBOARDSDIR, "symbols", filename, NULL);
 | 
			
		||||
@ -1203,7 +1223,7 @@ parse_symbols_with_prerequisites (const gchar *name,
 | 
			
		||||
        if (!retval)
 | 
			
		||||
            return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    g_slist_free_full (prerequisites, (GDestroyNotify)g_free);
 | 
			
		||||
    g_list_free_full (prerequisites, (GDestroyNotify)g_free);
 | 
			
		||||
 | 
			
		||||
    retval = parse_symbols (path, keyboard, error);
 | 
			
		||||
    g_free (path);
 | 
			
		||||
@ -1243,14 +1263,14 @@ parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
static GList *
 | 
			
		||||
parse_prerequisites (const gchar *path, GError **error)
 | 
			
		||||
{
 | 
			
		||||
    PrerequisitesParseData *data;
 | 
			
		||||
    GMarkupParseContext *pcontext;
 | 
			
		||||
    GFile *file;
 | 
			
		||||
    GFileInputStream *input;
 | 
			
		||||
    GSList *prerequisites;
 | 
			
		||||
    GList *prerequisites;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
@ -1278,14 +1298,14 @@ parse_prerequisites (const gchar *path, GError **error)
 | 
			
		||||
    return prerequisites;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
static GList *
 | 
			
		||||
parse_keyboards (const gchar *path, GError **error)
 | 
			
		||||
{
 | 
			
		||||
    KeyboardsParseData *data;
 | 
			
		||||
    GMarkupParseContext *pcontext;
 | 
			
		||||
    GFile *file;
 | 
			
		||||
    GFileInputStream *input;
 | 
			
		||||
    GSList *keyboards;
 | 
			
		||||
    GList *keyboards;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
 | 
			
		||||
@ -76,10 +76,13 @@ struct _EekXmlKeyboardDesc
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekXmlKeyboardDesc EekXmlKeyboardDesc;
 | 
			
		||||
 | 
			
		||||
GType      eek_xml_layout_get_type       (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout *eek_xml_layout_new            (const gchar *id,
 | 
			
		||||
                                          GError     **error);
 | 
			
		||||
GSList    *eek_xml_layout_list_keyboards (void);
 | 
			
		||||
GType               eek_xml_layout_get_type    (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout          *eek_xml_layout_new         (const gchar        *id,
 | 
			
		||||
                                                GError            **error);
 | 
			
		||||
GList              *eek_xml_list_keyboards     (void);
 | 
			
		||||
 | 
			
		||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
 | 
			
		||||
void                eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,7 @@ enum {
 | 
			
		||||
enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -114,8 +115,9 @@ static const gchar introspection_xml[] =
 | 
			
		||||
    /* signals */
 | 
			
		||||
    "    <signal name='Enabled'/>"
 | 
			
		||||
    "    <signal name='Disabled'/>"
 | 
			
		||||
    "    <signal name='Destroyed'/>"
 | 
			
		||||
    "    <signal name='KeyActivated'>"
 | 
			
		||||
    "      <arg type='s' name='keyname'/>"
 | 
			
		||||
    "      <arg type='u' name='keycode'/>"
 | 
			
		||||
    "      <arg type='v' name='symbol'/>"
 | 
			
		||||
    "      <arg type='u' name='modifiers'/>"
 | 
			
		||||
    "    </signal>"
 | 
			
		||||
@ -399,6 +401,23 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContextService::destroyed:
 | 
			
		||||
     * @context: an #EekboardContextService
 | 
			
		||||
     *
 | 
			
		||||
     * Emitted when @context is destroyed.
 | 
			
		||||
     */
 | 
			
		||||
    signals[DESTROYED] =
 | 
			
		||||
        g_signal_new (I_("destroyed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextServiceClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContextService:object-path:
 | 
			
		||||
     *
 | 
			
		||||
@ -574,7 +593,7 @@ emit_key_activated_dbus_signal (EekboardContextService *context,
 | 
			
		||||
                                EekKey                 *key)
 | 
			
		||||
{
 | 
			
		||||
    if (context->priv->connection && context->priv->enabled) {
 | 
			
		||||
        const gchar *keyname = eek_element_get_name (EEK_ELEMENT(key));
 | 
			
		||||
        guint keycode = eek_key_get_keycode (key);
 | 
			
		||||
        EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
        guint modifiers = eek_keyboard_get_modifiers (context->priv->keyboard);
 | 
			
		||||
        GVariant *variant;
 | 
			
		||||
@ -589,8 +608,8 @@ emit_key_activated_dbus_signal (EekboardContextService *context,
 | 
			
		||||
                                                context->priv->object_path,
 | 
			
		||||
                                                EEKBOARD_CONTEXT_SERVICE_INTERFACE,
 | 
			
		||||
                                                "KeyActivated",
 | 
			
		||||
                                                g_variant_new ("(svu)",
 | 
			
		||||
                                                               keyname,
 | 
			
		||||
                                                g_variant_new ("(uvu)",
 | 
			
		||||
                                                               keycode,
 | 
			
		||||
                                                               variant,
 | 
			
		||||
                                                               modifiers),
 | 
			
		||||
                                                &error);
 | 
			
		||||
@ -748,13 +767,15 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(u)", &keyboard_id);
 | 
			
		||||
 | 
			
		||||
        current_keyboard_id =
 | 
			
		||||
            GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(context->priv->keyboard),
 | 
			
		||||
                                                 "keyboard-id"));
 | 
			
		||||
        if (keyboard_id == current_keyboard_id) {
 | 
			
		||||
            disconnect_keyboard_signals (context);
 | 
			
		||||
            context->priv->keyboard = NULL;
 | 
			
		||||
            g_object_notify (G_OBJECT(context), "keyboard");
 | 
			
		||||
        if (context->priv->keyboard != NULL) {
 | 
			
		||||
            current_keyboard_id =
 | 
			
		||||
                GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(context->priv->keyboard),
 | 
			
		||||
                                                     "keyboard-id"));
 | 
			
		||||
            if (keyboard_id == current_keyboard_id) {
 | 
			
		||||
                disconnect_keyboard_signals (context);
 | 
			
		||||
                context->priv->keyboard = NULL;
 | 
			
		||||
                g_object_notify (G_OBJECT(context), "keyboard");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_hash_table_remove (context->priv->keyboard_hash,
 | 
			
		||||
@ -978,6 +999,42 @@ eekboard_context_service_disable (EekboardContextService *context)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_service_destroy:
 | 
			
		||||
 * @context: an #EekboardContextService
 | 
			
		||||
 *
 | 
			
		||||
 * Destroy @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_service_destroy (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context));
 | 
			
		||||
    g_return_if_fail (context->priv->connection);
 | 
			
		||||
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
        eekboard_context_service_disable (context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    retval = g_dbus_connection_emit_signal (context->priv->connection,
 | 
			
		||||
                                            NULL,
 | 
			
		||||
                                            context->priv->object_path,
 | 
			
		||||
                                            EEKBOARD_CONTEXT_SERVICE_INTERFACE,
 | 
			
		||||
                                            "Destroyed",
 | 
			
		||||
                                            NULL,
 | 
			
		||||
                                            &error);
 | 
			
		||||
    if (!retval) {
 | 
			
		||||
        g_warning ("failed to emit Destroyed signal: %s",
 | 
			
		||||
                   error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
    g_signal_emit (context, signals[DESTROYED], 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_service_get_keyboard:
 | 
			
		||||
 * @context: an #EekboardContextService
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,7 @@ struct _EekboardContextServiceClass {
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void         (*enabled)            (EekboardContextService *self);
 | 
			
		||||
    void         (*disabled)           (EekboardContextService *self);
 | 
			
		||||
    void         (*destroyed)          (EekboardContextService *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -83,6 +84,7 @@ GType         eekboard_context_service_get_type
 | 
			
		||||
                                              (void) G_GNUC_CONST;
 | 
			
		||||
void          eekboard_context_service_enable (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_disable (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_destroy (EekboardContextService *context);
 | 
			
		||||
EekKeyboard  *eekboard_context_service_get_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
gboolean      eekboard_context_service_get_fullscreen
 | 
			
		||||
 | 
			
		||||
@ -36,8 +36,8 @@
 | 
			
		||||
enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    KEY_PRESSED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    KEY_ACTIVATED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -80,14 +80,19 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Destroyed") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[DESTROYED], 0);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
 | 
			
		||||
        const gchar *keyname;
 | 
			
		||||
        guint keycode;
 | 
			
		||||
        GVariant *variant = NULL;
 | 
			
		||||
        guint modifiers = 0;
 | 
			
		||||
        EekSerializable *serializable;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(&svu)",
 | 
			
		||||
                       &keyname, &variant, &modifiers);
 | 
			
		||||
        g_variant_get (parameters, "(uvu)",
 | 
			
		||||
                       &keycode, &variant, &modifiers);
 | 
			
		||||
        g_return_if_fail (variant != NULL);
 | 
			
		||||
 | 
			
		||||
        serializable = eek_serializable_deserialize (variant);
 | 
			
		||||
@ -95,8 +100,8 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
 | 
			
		||||
        g_return_if_fail (EEK_IS_SYMBOL(serializable));
 | 
			
		||||
        
 | 
			
		||||
        g_signal_emit (context, signals[KEY_PRESSED], 0,
 | 
			
		||||
                       keyname, EEK_SYMBOL(serializable), modifiers);
 | 
			
		||||
        g_signal_emit (context, signals[KEY_ACTIVATED], 0,
 | 
			
		||||
                       keycode, EEK_SYMBOL(serializable), modifiers);
 | 
			
		||||
        g_object_unref (serializable);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
@ -140,15 +145,15 @@ eekboard_context_real_disabled (EekboardContext *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_key_pressed (EekboardContext *self,
 | 
			
		||||
                                   const gchar     *keyname,
 | 
			
		||||
                                   EekSymbol       *symbol,
 | 
			
		||||
                                   guint            modifiers)
 | 
			
		||||
eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
eekboard_context_real_key_activated (EekboardContext *self,
 | 
			
		||||
                                     const gchar     *keyname,
 | 
			
		||||
                                     EekSymbol       *symbol,
 | 
			
		||||
                                     guint            modifiers)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -181,8 +186,8 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
 | 
			
		||||
    klass->enabled = eekboard_context_real_enabled;
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->key_pressed = eekboard_context_real_key_pressed;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
    klass->key_activated = eekboard_context_real_key_activated;
 | 
			
		||||
 | 
			
		||||
    proxy_class->g_signal = eekboard_context_real_g_signal;
 | 
			
		||||
 | 
			
		||||
@ -237,26 +242,26 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::key-pressed:
 | 
			
		||||
     * EekboardContext::key-activated:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     * @keycode: keycode
 | 
			
		||||
     * @keycode: a keycode
 | 
			
		||||
     * @symbol: an #EekSymbol
 | 
			
		||||
     * @modifiers: modifiers
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-pressed signal is emitted each time a key is pressed
 | 
			
		||||
     * in @context.
 | 
			
		||||
     * The ::key-activated signal is emitted each time a key is
 | 
			
		||||
     * pressed in @context.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
    signals[KEY_ACTIVATED] =
 | 
			
		||||
        g_signal_new (I_("key-activated"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, key_pressed),
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, key_activated),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      _eekboard_marshal_VOID__STRING_OBJECT_UINT,
 | 
			
		||||
                      _eekboard_marshal_VOID__UINT_OBJECT_UINT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      3,
 | 
			
		||||
                      G_TYPE_STRING,
 | 
			
		||||
                      G_TYPE_UINT,
 | 
			
		||||
                      G_TYPE_OBJECT,
 | 
			
		||||
                      G_TYPE_UINT);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -66,12 +66,13 @@ struct _EekboardContextClass {
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (*enabled)      (EekboardContext *self);
 | 
			
		||||
    void (*disabled)     (EekboardContext *self);
 | 
			
		||||
    void (*key_pressed)  (EekboardContext *self,
 | 
			
		||||
                          const gchar     *keyname,
 | 
			
		||||
                          EekSymbol       *symbol,
 | 
			
		||||
                          guint            modifiers);
 | 
			
		||||
    void (*destroyed)    (EekboardContext *self);
 | 
			
		||||
 | 
			
		||||
    void (*key_activated)  (EekboardContext *self,
 | 
			
		||||
                            const gchar     *keyname,
 | 
			
		||||
                            EekSymbol       *symbol,
 | 
			
		||||
                            guint            modifiers);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
VOID:STRING,OBJECT,UINT
 | 
			
		||||
VOID:UINT,OBJECT,UINT
 | 
			
		||||
 | 
			
		||||
@ -70,9 +70,6 @@ static const gchar introspection_xml[] =
 | 
			
		||||
    "      <arg direction='in' type='s' name='object_path'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='PopContext'/>"
 | 
			
		||||
    "    <method name='DestroyContext'>"
 | 
			
		||||
    "      <arg direction='in' type='s' name='object_path'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='Destroy'/>"
 | 
			
		||||
    /* signals */
 | 
			
		||||
    "  </interface>"
 | 
			
		||||
@ -349,6 +346,18 @@ service_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
        eekboard_context_service_enable (service->priv->context_stack->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_destroyed_cb (EekboardContextService *context, EekboardService *service)
 | 
			
		||||
{
 | 
			
		||||
    gchar *object_path = NULL;
 | 
			
		||||
 | 
			
		||||
    remove_context_from_stack (service, context);
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT(context), "object-path", &object_path, NULL);
 | 
			
		||||
    g_hash_table_remove (service->priv->context_hash, object_path);
 | 
			
		||||
    g_free (object_path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
                    const gchar           *sender,
 | 
			
		||||
@ -387,6 +396,10 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
                                        service_name_vanished_callback,
 | 
			
		||||
                                        service,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
 | 
			
		||||
        g_signal_connect (G_OBJECT(context), "destroyed",
 | 
			
		||||
                          G_CALLBACK(context_destroyed_cb), service);
 | 
			
		||||
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation,
 | 
			
		||||
                                               g_variant_new ("(s)",
 | 
			
		||||
                                                              object_path));
 | 
			
		||||
@ -445,38 +458,6 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "DestroyContext") == 0) {
 | 
			
		||||
        EekboardContextService *context;
 | 
			
		||||
        const gchar *object_path;
 | 
			
		||||
        const gchar *owner;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(&s)", &object_path);
 | 
			
		||||
        context = g_hash_table_lookup (service->priv->context_hash, object_path);
 | 
			
		||||
        if (!context) {
 | 
			
		||||
            g_dbus_method_invocation_return_error (invocation,
 | 
			
		||||
                                                   G_IO_ERROR,
 | 
			
		||||
                                                   G_IO_ERROR_FAILED_HANDLED,
 | 
			
		||||
                                                   "context not found");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        owner = g_object_get_data (G_OBJECT(context), "owner");
 | 
			
		||||
        if (g_strcmp0 (owner, sender) != 0) {
 | 
			
		||||
            g_dbus_method_invocation_return_error
 | 
			
		||||
                (invocation,
 | 
			
		||||
                 G_IO_ERROR,
 | 
			
		||||
                 G_IO_ERROR_FAILED_HANDLED,
 | 
			
		||||
                 "the context at %s not owned by %s",
 | 
			
		||||
                 object_path, sender);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        remove_context_from_stack (service, context);
 | 
			
		||||
        g_hash_table_remove (service->priv->context_hash, object_path);
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "Destroy") == 0) {
 | 
			
		||||
        g_signal_emit (service, signals[DESTROYED], 0);
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										149
									
								
								src/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								src/Makefile.am
									
									
									
									
									
								
							@ -16,83 +16,120 @@
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS = \
 | 
			
		||||
	eekboard \
 | 
			
		||||
	eekboard-server
 | 
			
		||||
bin_PROGRAMS =					\
 | 
			
		||||
	eekboard				\
 | 
			
		||||
	eekboard-server				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	$(GIO2_CFLAGS) \
 | 
			
		||||
	$(GTK_CFLAGS) \
 | 
			
		||||
	$(XKB_CFLAGS) \
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS) \
 | 
			
		||||
	-DKEYBOARDDIR=\"$(pkgdatadir)/keyboards\" \
 | 
			
		||||
	-DPKGDATADIR=\"$(pkgdatadir)\"
 | 
			
		||||
libexec_PROGRAMS =				\
 | 
			
		||||
	eekboard-setup				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_LDADD = \
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
	$(GIO2_LIBS) \
 | 
			
		||||
	$(GTK_LIBS) \
 | 
			
		||||
	$(XKB_LIBS) \
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)
 | 
			
		||||
eekboard_CFLAGS =					\
 | 
			
		||||
	-I$(top_srcdir)					\
 | 
			
		||||
	$(GIO2_CFLAGS)					\
 | 
			
		||||
	$(GTK_CFLAGS)					\
 | 
			
		||||
	$(XKB_CFLAGS)					\
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)				\
 | 
			
		||||
	-DLIBEXECDIR=\"$(libexecdir)\"			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_LDADD =				\
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la	\
 | 
			
		||||
	$(top_builddir)/eek/libeek.la		\
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la	\
 | 
			
		||||
	$(GIO2_LIBS)				\
 | 
			
		||||
	$(GTK_LIBS)				\
 | 
			
		||||
	$(XKB_LIBS)				\
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if ENABLE_XTEST
 | 
			
		||||
eekboard_CFLAGS += \
 | 
			
		||||
	$(XTEST_CFLAGS)
 | 
			
		||||
eekboard_LDADD += \
 | 
			
		||||
	$(XTEST_LIBS)
 | 
			
		||||
eekboard_CFLAGS += $(XTEST_CFLAGS)
 | 
			
		||||
eekboard_LDADD += $(XTEST_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_ATSPI
 | 
			
		||||
eekboard_CFLAGS += \
 | 
			
		||||
	$(ATSPI2_CFLAGS)
 | 
			
		||||
eekboard_LDADD += \
 | 
			
		||||
	$(ATSPI2_LIBS)
 | 
			
		||||
eekboard_CFLAGS += $(ATSPI2_CFLAGS)
 | 
			
		||||
eekboard_LDADD += $(ATSPI2_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_IBUS
 | 
			
		||||
eekboard_CFLAGS += \
 | 
			
		||||
	$(IBUS_CFLAGS)
 | 
			
		||||
eekboard_LDADD += \
 | 
			
		||||
	$(IBUS_LIBS)
 | 
			
		||||
eekboard_CFLAGS += $(IBUS_CFLAGS)
 | 
			
		||||
eekboard_LDADD += $(IBUS_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
eekboard_headers = client.h preferences-dialog.h
 | 
			
		||||
eekboard_SOURCES = client.c preferences-dialog.c client-main.c
 | 
			
		||||
eekboard_headers =				\
 | 
			
		||||
	client.h				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_server_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	$(GIO2_CFLAGS) \
 | 
			
		||||
	$(GTK_CFLAGS) \
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS) \
 | 
			
		||||
	-DTHEMEDIR=\"$(pkgdatadir)/themes\" \
 | 
			
		||||
	-DKEYBOARDDIR=\"$(pkgdatadir)/keyboards\"
 | 
			
		||||
eekboard_SOURCES =				\
 | 
			
		||||
	client.c				\
 | 
			
		||||
	client-main.c				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_server_LDADD = \
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-gtk.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
	$(GIO2_LIBS) \
 | 
			
		||||
	$(GTK_LIBS) \
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)
 | 
			
		||||
eekboard_server_CFLAGS =				\
 | 
			
		||||
	-I$(top_srcdir)					\
 | 
			
		||||
	$(GIO2_CFLAGS)					\
 | 
			
		||||
	$(GTK_CFLAGS)					\
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)				\
 | 
			
		||||
	-DTHEMESDIR=\"$(pkgdatadir)/themes\"		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_server_LDADD =				\
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la	\
 | 
			
		||||
	$(top_builddir)/eek/libeek.la		\
 | 
			
		||||
	$(top_builddir)/eek/libeek-gtk.la	\
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la	\
 | 
			
		||||
	$(GIO2_LIBS)				\
 | 
			
		||||
	$(GTK_LIBS)				\
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if ENABLE_XDOCK
 | 
			
		||||
eekboard_server_CFLAGS += $(XDOCK_CFLAGS)
 | 
			
		||||
eekboard_server_LDADD += $(XDOCK_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
eekboard_server_headers = server-service.h server-context-service.h
 | 
			
		||||
eekboard_server_SOURCES = server-service.c server-context-service.c server-main.c
 | 
			
		||||
eekboard_server_headers =			\
 | 
			
		||||
	server-service.h			\
 | 
			
		||||
	server-context-service.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboarddir = $(includedir)/eekboard-$(EEK_API_VERSION)/eekboard
 | 
			
		||||
eekboard_HEADERS =				\
 | 
			
		||||
	$(libeekboard_headers)
 | 
			
		||||
eekboard_server_SOURCES =			\
 | 
			
		||||
	server-service.c			\
 | 
			
		||||
	server-context-service.c		\
 | 
			
		||||
	server-main.c				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = \
 | 
			
		||||
	$(eekboard_headers) \
 | 
			
		||||
	$(eekboard_server_headers)
 | 
			
		||||
eekboard_setup_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir)					\
 | 
			
		||||
	$(GIO2_CFLAGS)					\
 | 
			
		||||
	$(GTK_CFLAGS)					\
 | 
			
		||||
	$(XKB_CFLAGS)					\
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)				\
 | 
			
		||||
	-DPKGDATADIR=\"$(pkgdatadir)\"			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_setup_headers =			\
 | 
			
		||||
	preferences-dialog.h			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_setup_SOURCES =			\
 | 
			
		||||
	preferences-dialog.c			\
 | 
			
		||||
	setup-main.c				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eekboard_setup_LDADD =				\
 | 
			
		||||
	$(top_builddir)/eek/libeek.la		\
 | 
			
		||||
	$(GIO2_LIBS)				\
 | 
			
		||||
	$(GTK_LIBS)				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
dist_pkgdata_DATA = preferences-dialog.ui
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS =				\
 | 
			
		||||
	$(eekboard_headers)			\
 | 
			
		||||
	$(eekboard_server_headers)		\
 | 
			
		||||
	$(eekboard_setup_headers)		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
@ -67,21 +67,6 @@ static const GOptionEntry options[] = {
 | 
			
		||||
    {NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_visible (GObject    *object,
 | 
			
		||||
                   GParamSpec *spec,
 | 
			
		||||
                   gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    GMainLoop *loop = user_data;
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
 | 
			
		||||
    g_object_get (object, "visible", &visible, NULL);
 | 
			
		||||
 | 
			
		||||
    /* user explicitly closed the window */
 | 
			
		||||
    if (!visible && eekboard_context_is_enabled (EEKBOARD_CONTEXT(object)))
 | 
			
		||||
        g_main_loop_quit (loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
@ -139,7 +124,7 @@ main (int argc, char **argv)
 | 
			
		||||
    GMainLoop *loop = NULL;
 | 
			
		||||
    gint focus;
 | 
			
		||||
    GSettings *settings = NULL;
 | 
			
		||||
    gchar **keyboards;
 | 
			
		||||
    gchar **keyboards = NULL;
 | 
			
		||||
    gint retval = 0;
 | 
			
		||||
 | 
			
		||||
    if (!gtk_init_check (&argc, &argv)) {
 | 
			
		||||
@ -302,8 +287,6 @@ main (int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
    if (!opt_focus) {
 | 
			
		||||
        g_object_get (client, "context", &context, NULL);
 | 
			
		||||
        g_signal_connect (context, "notify::visible",
 | 
			
		||||
                          G_CALLBACK(on_notify_visible), loop);
 | 
			
		||||
        g_signal_connect (context, "destroyed",
 | 
			
		||||
                          G_CALLBACK(on_context_destroyed), loop);
 | 
			
		||||
        g_object_unref (context);
 | 
			
		||||
@ -321,16 +304,16 @@ main (int argc, char **argv)
 | 
			
		||||
                      G_CALLBACK(on_destroyed), loop);
 | 
			
		||||
    g_object_unref (eekboard);
 | 
			
		||||
    
 | 
			
		||||
    if (opt_keyboards != NULL)
 | 
			
		||||
    if (opt_keyboards != NULL) {
 | 
			
		||||
        keyboards = g_strsplit (opt_keyboards, ",", -1);
 | 
			
		||||
    else
 | 
			
		||||
        keyboards = g_settings_get_strv (settings, "keyboards");
 | 
			
		||||
    if (!set_keyboards (client, (const gchar * const *)keyboards)) {
 | 
			
		||||
 | 
			
		||||
        if (!set_keyboards (client, (const gchar * const *)keyboards)) {
 | 
			
		||||
            g_strfreev (keyboards);
 | 
			
		||||
            retval = 1;
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
        g_strfreev (keyboards);
 | 
			
		||||
        retval = 1;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    g_strfreev (keyboards);
 | 
			
		||||
 | 
			
		||||
    g_main_loop_run (loop);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										94
									
								
								src/client.c
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								src/client.c
									
									
									
									
									
								
							@ -42,7 +42,6 @@
 | 
			
		||||
#include "eekboard/eekboard-client.h"
 | 
			
		||||
#include "eekboard/eekboard-xklutil.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "preferences-dialog.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@ -54,6 +53,7 @@ enum {
 | 
			
		||||
    PROP_CONNECTION,
 | 
			
		||||
    PROP_EEKBOARD,
 | 
			
		||||
    PROP_CONTEXT,
 | 
			
		||||
    PROP_KEYBOARDS,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -66,14 +66,15 @@ struct _Client {
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
 | 
			
		||||
    GSList *keyboards;
 | 
			
		||||
    GSList *keyboards_head;
 | 
			
		||||
 | 
			
		||||
    XklEngine *xkl_engine;
 | 
			
		||||
    XklConfigRegistry *xkl_config_registry;
 | 
			
		||||
 | 
			
		||||
    gulong xkl_config_changed_handler;
 | 
			
		||||
    gulong xkl_state_changed_handler;
 | 
			
		||||
 | 
			
		||||
    gulong key_pressed_handler;
 | 
			
		||||
    gulong key_released_handler;
 | 
			
		||||
    gulong key_activated_handler;
 | 
			
		||||
 | 
			
		||||
    gboolean follows_focus;
 | 
			
		||||
    guint hide_keyboard_timeout_id;
 | 
			
		||||
@ -158,16 +159,21 @@ client_set_property (GObject      *object,
 | 
			
		||||
            if (client->context == NULL) {
 | 
			
		||||
                g_object_unref (client->eekboard);
 | 
			
		||||
                client->eekboard = NULL;
 | 
			
		||||
            } else
 | 
			
		||||
            } else {
 | 
			
		||||
                eekboard_client_push_context (client->eekboard,
 | 
			
		||||
                                              client->context,
 | 
			
		||||
                                              NULL);
 | 
			
		||||
                g_settings_bind (client->settings, "keyboards",
 | 
			
		||||
                                 client, "keyboards",
 | 
			
		||||
                                 G_SETTINGS_BIND_GET);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_KEYBOARDS:
 | 
			
		||||
        client_set_keyboards (client, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_set_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
                               value);
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -188,9 +194,7 @@ client_get_property (GObject    *object,
 | 
			
		||||
        g_value_set_object (value, client->context);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_get_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
                               value);
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -289,6 +293,15 @@ client_class_init (ClientClass *klass)
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_CONTEXT,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_boxed ("keyboards",
 | 
			
		||||
                                "Keyboards",
 | 
			
		||||
                                "Keyboards",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_WRITABLE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_KEYBOARDS,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -753,10 +766,20 @@ set_keyboards (Client              *client,
 | 
			
		||||
{
 | 
			
		||||
    guint keyboard_id;
 | 
			
		||||
    const gchar * const *p;
 | 
			
		||||
    GSList *head = NULL;
 | 
			
		||||
    GSList *head;
 | 
			
		||||
 | 
			
		||||
    if (client->keyboards)
 | 
			
		||||
    g_return_val_if_fail (keyboards != NULL, FALSE);
 | 
			
		||||
    g_return_val_if_fail (client->context, FALSE);
 | 
			
		||||
 | 
			
		||||
    if (client->keyboards) {
 | 
			
		||||
        for (head = client->keyboards; head; head = head->next) {
 | 
			
		||||
            eekboard_context_remove_keyboard (client->context,
 | 
			
		||||
                                              GPOINTER_TO_UINT(head->data),
 | 
			
		||||
                                              NULL);
 | 
			
		||||
        }
 | 
			
		||||
        g_slist_free (client->keyboards);
 | 
			
		||||
        client->keyboards = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (p = keyboards; *p != NULL; p++) {
 | 
			
		||||
        keyboard_id = eekboard_context_add_keyboard (client->context, *p, NULL);
 | 
			
		||||
@ -764,17 +787,16 @@ set_keyboards (Client              *client,
 | 
			
		||||
            g_slist_free (head);
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        head = g_slist_prepend (head, GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
        client->keyboards = g_slist_prepend (client->keyboards,
 | 
			
		||||
                                             GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* make a cycle */
 | 
			
		||||
    head = g_slist_reverse (head);
 | 
			
		||||
    g_slist_last (head)->next = head;
 | 
			
		||||
    client->keyboards = head;
 | 
			
		||||
    client->keyboards = g_slist_reverse (client->keyboards);
 | 
			
		||||
    client->keyboards_head = client->keyboards;
 | 
			
		||||
 | 
			
		||||
    /* select the first keyboard */
 | 
			
		||||
    eekboard_context_set_keyboard (client->context,
 | 
			
		||||
                                   GPOINTER_TO_UINT(head->data),
 | 
			
		||||
                                   GPOINTER_TO_UINT(client->keyboards_head->data),
 | 
			
		||||
                                   NULL);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -1028,25 +1050,37 @@ send_fake_key_events (Client    *client,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_pressed (EekboardContext *context,
 | 
			
		||||
                const gchar     *keyname,
 | 
			
		||||
                EekSymbol       *symbol,
 | 
			
		||||
                guint            modifiers,
 | 
			
		||||
                gpointer         user_data)
 | 
			
		||||
on_key_activated (EekboardContext *context,
 | 
			
		||||
                  guint            keycode,
 | 
			
		||||
                  EekSymbol       *symbol,
 | 
			
		||||
                  guint            modifiers,
 | 
			
		||||
                  gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    Client *client = user_data;
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (eek_symbol_get_name (symbol), "cycle-keyboard") == 0) {
 | 
			
		||||
        client->keyboards = g_slist_next (client->keyboards);
 | 
			
		||||
        client->keyboards_head = g_slist_next (client->keyboards_head);
 | 
			
		||||
        if (client->keyboards_head == NULL)
 | 
			
		||||
            client->keyboards_head = client->keyboards;
 | 
			
		||||
        eekboard_context_set_keyboard (client->context,
 | 
			
		||||
                                       GPOINTER_TO_UINT(client->keyboards->data),
 | 
			
		||||
                                       GPOINTER_TO_UINT(client->keyboards_head->data),
 | 
			
		||||
                                       NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (eek_symbol_get_name (symbol), "preferences") == 0) {
 | 
			
		||||
        PreferencesDialog *dialog = preferences_dialog_new ();
 | 
			
		||||
        preferences_dialog_run (dialog);
 | 
			
		||||
        gchar *argv[2];
 | 
			
		||||
        GError *error;
 | 
			
		||||
 | 
			
		||||
        argv[0] = g_build_filename (LIBEXECDIR, "eekboard-setup", NULL);
 | 
			
		||||
        argv[1] = NULL;
 | 
			
		||||
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        if (!g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error)) {
 | 
			
		||||
            g_warning ("can't spawn %s: %s", argv[0], error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
        }
 | 
			
		||||
        g_free (argv[0]);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1104,9 +1138,9 @@ client_enable_xtest (Client *client)
 | 
			
		||||
 | 
			
		||||
    update_modifier_keycodes (client);
 | 
			
		||||
 | 
			
		||||
    client->key_pressed_handler =
 | 
			
		||||
        g_signal_connect (client->context, "key-pressed",
 | 
			
		||||
                          G_CALLBACK(on_key_pressed), client);
 | 
			
		||||
    client->key_activated_handler =
 | 
			
		||||
        g_signal_connect (client->context, "key-activated",
 | 
			
		||||
                          G_CALLBACK(on_key_activated), client);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include "preferences-dialog.h"
 | 
			
		||||
#include <eek/eek.h>
 | 
			
		||||
 | 
			
		||||
struct _PreferencesDialog {
 | 
			
		||||
    GtkWidget *dialog;
 | 
			
		||||
@ -29,9 +30,16 @@ struct _PreferencesDialog {
 | 
			
		||||
    GtkWidget *repeat_speed_scale;
 | 
			
		||||
    GtkWidget *auto_hide_toggle;
 | 
			
		||||
    GtkWidget *auto_hide_delay_scale;
 | 
			
		||||
    GtkWidget *start_fullscreen_toggle;
 | 
			
		||||
    GtkWidget *keyboard_entry;
 | 
			
		||||
    GtkWidget *selected_keyboards_treeview;
 | 
			
		||||
    GtkWidget *up_button;
 | 
			
		||||
    GtkWidget *down_button;
 | 
			
		||||
    GtkWidget *add_button;
 | 
			
		||||
    GtkWidget *remove_button;
 | 
			
		||||
 | 
			
		||||
    GtkWidget *new_keyboard_dialog;
 | 
			
		||||
    GtkWidget *available_keyboards_treeview;
 | 
			
		||||
 | 
			
		||||
    GList *available_keyboards;
 | 
			
		||||
    GSettings *settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -62,33 +70,191 @@ set_rate (const GValue       *value,
 | 
			
		||||
    return g_variant_new_uint32 (msecs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_strv (GValue   *value,
 | 
			
		||||
          GVariant *variant,
 | 
			
		||||
          gpointer  user_data)
 | 
			
		||||
static void
 | 
			
		||||
add_keyboard_to_treeview (GtkTreeView *treeview,
 | 
			
		||||
                          const gchar *id,
 | 
			
		||||
                          const gchar *longname)
 | 
			
		||||
{
 | 
			
		||||
    const gchar **strv = g_variant_get_strv (variant, NULL);
 | 
			
		||||
    gchar *text = g_strjoinv (", ", (gchar **)strv);
 | 
			
		||||
    g_free (strv);
 | 
			
		||||
    g_value_set_string (value, text);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    GtkTreeModel *model = gtk_tree_view_get_model (treeview);
 | 
			
		||||
    GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
    if (gtk_tree_model_get_iter_first (model, &iter)) {
 | 
			
		||||
        do {
 | 
			
		||||
            gchar *_id;
 | 
			
		||||
            gtk_tree_model_get (model, &iter, 0, &_id, -1);
 | 
			
		||||
            if (g_strcmp0 (id, _id) == 0) {
 | 
			
		||||
                g_free (_id);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            g_free (_id);
 | 
			
		||||
        } while (gtk_tree_model_iter_next (model, &iter));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gtk_list_store_append (GTK_LIST_STORE(model),
 | 
			
		||||
                           &iter);
 | 
			
		||||
    gtk_list_store_set (GTK_LIST_STORE(model),
 | 
			
		||||
                        &iter,
 | 
			
		||||
                        0, id,
 | 
			
		||||
                        1, longname,
 | 
			
		||||
                        -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GVariant *
 | 
			
		||||
set_strv (const GValue       *value,
 | 
			
		||||
          const GVariantType *expected_type,
 | 
			
		||||
          gpointer            user_data)
 | 
			
		||||
static void
 | 
			
		||||
add_keyboard (GtkWidget *button, PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *text = g_value_get_string (value);
 | 
			
		||||
    gchar **strv = g_strsplit (text, ",", -1), **p;
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    gint retval = gtk_dialog_run (GTK_DIALOG(dialog->new_keyboard_dialog));
 | 
			
		||||
    if (retval == GTK_RESPONSE_OK) {
 | 
			
		||||
        GtkTreeSelection *selection;
 | 
			
		||||
        GtkTreeModel *model;
 | 
			
		||||
        GList *rows, *p;
 | 
			
		||||
 | 
			
		||||
    for (p = strv; *p != NULL; p++)
 | 
			
		||||
        g_strstrip (*p);
 | 
			
		||||
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->available_keyboards_treeview));
 | 
			
		||||
        rows = gtk_tree_selection_get_selected_rows (selection, &model);
 | 
			
		||||
        for (p = rows; p; p = p->next) {
 | 
			
		||||
            GtkTreeIter iter;
 | 
			
		||||
            if (gtk_tree_model_get_iter (model, &iter, p->data)) {
 | 
			
		||||
                gchar *id, *longname;
 | 
			
		||||
                gtk_tree_model_get (model, &iter, 0, &id, 1, &longname, -1);
 | 
			
		||||
                add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->selected_keyboards_treeview),
 | 
			
		||||
                                          id,
 | 
			
		||||
                                          longname);
 | 
			
		||||
                g_free (id);
 | 
			
		||||
                g_free (longname);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    gtk_widget_hide (dialog->new_keyboard_dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    variant = g_variant_new_strv ((const gchar * const *)strv, -1);
 | 
			
		||||
static void
 | 
			
		||||
remove_keyboard (GtkWidget *button, PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    GtkTreeSelection *selection;
 | 
			
		||||
    GtkTreeModel *model;
 | 
			
		||||
    GList *rows, *p;
 | 
			
		||||
 | 
			
		||||
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
 | 
			
		||||
    rows = gtk_tree_selection_get_selected_rows (selection, &model);
 | 
			
		||||
    for (p = rows; p; p = p->next) {
 | 
			
		||||
        GtkTreeIter iter;
 | 
			
		||||
        if (gtk_tree_model_get_iter (model, &iter, p->data))
 | 
			
		||||
            gtk_list_store_remove (GTK_LIST_STORE(model), &iter);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
up_keyboard (GtkWidget *button, PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    GtkTreeSelection *selection;
 | 
			
		||||
    GtkTreeModel *model;
 | 
			
		||||
    GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
 | 
			
		||||
    if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 | 
			
		||||
        GtkTreeIter prev = iter;
 | 
			
		||||
        if (gtk_tree_model_iter_previous (model, &prev))
 | 
			
		||||
            gtk_list_store_swap (GTK_LIST_STORE(model), &iter, &prev);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
down_keyboard (GtkWidget *button, PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    GtkTreeSelection *selection;
 | 
			
		||||
    GtkTreeModel *model;
 | 
			
		||||
    GtkTreeIter iter;
 | 
			
		||||
 | 
			
		||||
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
 | 
			
		||||
    if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 | 
			
		||||
        GtkTreeIter next = iter;
 | 
			
		||||
        if (gtk_tree_model_iter_next (model, &next))
 | 
			
		||||
            gtk_list_store_swap (GTK_LIST_STORE(model), &iter, &next);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
selection_changed_cb (GtkTreeSelection *selection, PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    gint count = gtk_tree_selection_count_selected_rows (selection);
 | 
			
		||||
    if (count > 0) {
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->remove_button, TRUE);
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->up_button, TRUE);
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->down_button, TRUE);
 | 
			
		||||
    } else {
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->remove_button, FALSE);
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->up_button, FALSE);
 | 
			
		||||
        gtk_widget_set_sensitive (dialog->down_button, FALSE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_keyboard_id (const EekXmlKeyboardDesc *desc, const char *id)
 | 
			
		||||
{
 | 
			
		||||
    return g_strcmp0 (desc->id, id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
populate_selected_keyboards (PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    gchar **strv, **p;
 | 
			
		||||
 | 
			
		||||
    strv = g_settings_get_strv (dialog->settings, "keyboards");
 | 
			
		||||
    for (p = strv; *p != NULL; p++) {
 | 
			
		||||
        GList *head = g_list_find_custom (dialog->available_keyboards,
 | 
			
		||||
                                            *p,
 | 
			
		||||
                                            (GCompareFunc) compare_keyboard_id);
 | 
			
		||||
        if (head == NULL) {
 | 
			
		||||
            g_warning ("unknown keyboard %s", *p);
 | 
			
		||||
        } else {
 | 
			
		||||
            EekXmlKeyboardDesc *desc = head->data;
 | 
			
		||||
            add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->selected_keyboards_treeview),
 | 
			
		||||
                                      desc->id,
 | 
			
		||||
                                      desc->longname);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
    return variant;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
populate_available_keyboards (PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    GList *p;
 | 
			
		||||
 | 
			
		||||
    for (p = dialog->available_keyboards; p; p = p->next) {
 | 
			
		||||
        EekXmlKeyboardDesc *desc = p->data;
 | 
			
		||||
        add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->available_keyboards_treeview),
 | 
			
		||||
                                  desc->id,
 | 
			
		||||
                                  desc->longname);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
save_keyboards (PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    GtkTreeModel *model;
 | 
			
		||||
    GtkTreeIter iter;
 | 
			
		||||
    GList *list = NULL, *head;
 | 
			
		||||
    gchar **strv, **p;
 | 
			
		||||
 | 
			
		||||
    model = gtk_tree_view_get_model (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
 | 
			
		||||
    if (gtk_tree_model_get_iter_first (model, &iter)) {
 | 
			
		||||
        do {
 | 
			
		||||
            gchar *id;
 | 
			
		||||
            gtk_tree_model_get (model, &iter, 0, &id, -1);
 | 
			
		||||
            list = g_list_prepend (list, id);
 | 
			
		||||
        } while (gtk_tree_model_iter_next (model, &iter));
 | 
			
		||||
    }
 | 
			
		||||
    list = g_list_reverse (list);
 | 
			
		||||
 | 
			
		||||
    strv = g_new0 (gchar *, g_list_length (list) + 1);
 | 
			
		||||
    for (head = list, p = strv; head; head = head->next, p++) {
 | 
			
		||||
        *p = head->data;
 | 
			
		||||
    }
 | 
			
		||||
    g_settings_set_strv (dialog->settings,
 | 
			
		||||
                         "keyboards",
 | 
			
		||||
                         (const gchar * const *)strv);
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PreferencesDialog *
 | 
			
		||||
@ -99,13 +265,19 @@ preferences_dialog_new (void)
 | 
			
		||||
    GtkBuilder *builder;
 | 
			
		||||
    GObject *object;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GtkListStore *store;
 | 
			
		||||
    GtkCellRenderer *renderer;
 | 
			
		||||
    GtkTreeViewColumn *column;
 | 
			
		||||
    GtkTreeSelection *selection;
 | 
			
		||||
 | 
			
		||||
    dialog = g_slice_new0 (PreferencesDialog);
 | 
			
		||||
    dialog->settings = g_settings_new ("org.fedorahosted.eekboard");
 | 
			
		||||
 | 
			
		||||
    builder = gtk_builder_new ();
 | 
			
		||||
    gtk_builder_set_translation_domain (builder, "eekboard");
 | 
			
		||||
    ui_path = g_strdup_printf ("%s/%s", PKGDATADIR, "preferences-dialog.ui");
 | 
			
		||||
    ui_path = g_build_filename (PKGDATADIR,
 | 
			
		||||
                                "preferences-dialog.ui",
 | 
			
		||||
                                NULL);
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    if (gtk_builder_add_from_file (builder, ui_path, &error) == 0) {
 | 
			
		||||
        g_warning ("can't load %s: %s", ui_path, error->message);
 | 
			
		||||
@ -113,28 +285,24 @@ preferences_dialog_new (void)
 | 
			
		||||
    }
 | 
			
		||||
    g_free (ui_path);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "dialog");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "dialog");
 | 
			
		||||
    dialog->dialog = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "repeat_toggle");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "repeat_toggle");
 | 
			
		||||
    dialog->repeat_toggle = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind (dialog->settings, "repeat",
 | 
			
		||||
                     dialog->repeat_toggle, "active",
 | 
			
		||||
                     G_SETTINGS_BIND_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "repeat_delay_scale");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "repeat_delay_scale");
 | 
			
		||||
    dialog->repeat_delay_scale = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind (dialog->settings, "repeat-delay",
 | 
			
		||||
                     gtk_range_get_adjustment (GTK_RANGE (dialog->repeat_delay_scale)), "value",
 | 
			
		||||
                     G_SETTINGS_BIND_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "repeat_speed_scale");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "repeat_speed_scale");
 | 
			
		||||
    dialog->repeat_speed_scale = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind_with_mapping (dialog->settings, "repeat-interval",
 | 
			
		||||
@ -142,38 +310,85 @@ preferences_dialog_new (void)
 | 
			
		||||
                                  G_SETTINGS_BIND_DEFAULT,
 | 
			
		||||
                                  get_rate, set_rate, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "auto_hide_toggle");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "auto_hide_toggle");
 | 
			
		||||
    dialog->auto_hide_toggle = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind (dialog->settings, "auto-hide",
 | 
			
		||||
                     dialog->auto_hide_toggle, "active",
 | 
			
		||||
                     G_SETTINGS_BIND_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "auto_hide_delay_scale");
 | 
			
		||||
    object = gtk_builder_get_object (builder, "auto_hide_delay_scale");
 | 
			
		||||
    dialog->auto_hide_delay_scale = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind (dialog->settings, "auto-hide-delay",
 | 
			
		||||
                     gtk_range_get_adjustment (GTK_RANGE (dialog->auto_hide_delay_scale)), "value",
 | 
			
		||||
                     G_SETTINGS_BIND_DEFAULT);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "start_fullscreen_toggle");
 | 
			
		||||
    dialog->start_fullscreen_toggle = GTK_WIDGET(object);
 | 
			
		||||
    object = gtk_builder_get_object (builder,
 | 
			
		||||
                                     "selected_keyboards_treeview");
 | 
			
		||||
    dialog->selected_keyboards_treeview = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind (dialog->settings, "start-fullscreen",
 | 
			
		||||
                     dialog->start_fullscreen_toggle, "active",
 | 
			
		||||
                     G_SETTINGS_BIND_DEFAULT);
 | 
			
		||||
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
 | 
			
		||||
    g_signal_connect (G_OBJECT(selection), "changed",
 | 
			
		||||
                      G_CALLBACK(selection_changed_cb), dialog);
 | 
			
		||||
 | 
			
		||||
    object =
 | 
			
		||||
        gtk_builder_get_object (builder, "keyboard_entry");
 | 
			
		||||
    dialog->keyboard_entry = GTK_WIDGET(object);
 | 
			
		||||
    renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new ());
 | 
			
		||||
    column = gtk_tree_view_column_new_with_attributes ("Keyboard",
 | 
			
		||||
                                                       renderer,
 | 
			
		||||
                                                       "text",
 | 
			
		||||
                                                       1,
 | 
			
		||||
                                                       NULL);
 | 
			
		||||
    gtk_tree_view_append_column (GTK_TREE_VIEW (object), column);
 | 
			
		||||
 | 
			
		||||
    g_settings_bind_with_mapping (dialog->settings, "keyboards",
 | 
			
		||||
                                  GTK_ENTRY(dialog->keyboard_entry), "text",
 | 
			
		||||
                                  G_SETTINGS_BIND_DEFAULT,
 | 
			
		||||
                                  get_strv, set_strv, NULL, NULL);
 | 
			
		||||
    object = gtk_builder_get_object (builder, "up_button");
 | 
			
		||||
    dialog->up_button = GTK_WIDGET(object);
 | 
			
		||||
    g_signal_connect (object, "clicked",
 | 
			
		||||
                      G_CALLBACK(up_keyboard), dialog);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder, "down_button");
 | 
			
		||||
    dialog->down_button = GTK_WIDGET(object);
 | 
			
		||||
    g_signal_connect (object, "clicked",
 | 
			
		||||
                      G_CALLBACK(down_keyboard), dialog);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder, "add_button");
 | 
			
		||||
    dialog->add_button = GTK_WIDGET(object);
 | 
			
		||||
    g_signal_connect (object, "clicked",
 | 
			
		||||
                      G_CALLBACK(add_keyboard), dialog);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder, "remove_button");
 | 
			
		||||
    dialog->remove_button = GTK_WIDGET(object);
 | 
			
		||||
    g_signal_connect (object, "clicked",
 | 
			
		||||
                      G_CALLBACK(remove_keyboard), dialog);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder, "new_keyboard_dialog");
 | 
			
		||||
    dialog->new_keyboard_dialog = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder,
 | 
			
		||||
                                     "available_keyboards_treeview");
 | 
			
		||||
    dialog->available_keyboards_treeview = GTK_WIDGET(object);
 | 
			
		||||
 | 
			
		||||
    renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new ());
 | 
			
		||||
    column = gtk_tree_view_column_new_with_attributes ("Keyboard",
 | 
			
		||||
                                                       renderer,
 | 
			
		||||
                                                       "text",
 | 
			
		||||
                                                       1,
 | 
			
		||||
                                                       NULL);
 | 
			
		||||
    gtk_tree_view_append_column (GTK_TREE_VIEW (object), column);
 | 
			
		||||
 | 
			
		||||
    object = gtk_builder_get_object (builder,
 | 
			
		||||
                                     "available_keyboards_liststore");
 | 
			
		||||
    store = GTK_LIST_STORE(object);
 | 
			
		||||
 | 
			
		||||
    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),
 | 
			
		||||
                                          1,
 | 
			
		||||
                                          GTK_SORT_ASCENDING);
 | 
			
		||||
 | 
			
		||||
    dialog->available_keyboards = eek_xml_list_keyboards ();
 | 
			
		||||
 | 
			
		||||
    populate_selected_keyboards (dialog);
 | 
			
		||||
    populate_available_keyboards (dialog);
 | 
			
		||||
 | 
			
		||||
    g_object_unref (builder);
 | 
			
		||||
 | 
			
		||||
    return dialog;
 | 
			
		||||
}
 | 
			
		||||
@ -183,5 +398,18 @@ preferences_dialog_run (PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    gtk_window_present (GTK_WINDOW(dialog->dialog));
 | 
			
		||||
    gtk_dialog_run (GTK_DIALOG(dialog->dialog));
 | 
			
		||||
    gtk_widget_destroy (dialog->dialog);
 | 
			
		||||
    save_keyboards (dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
preferences_dialog_free (PreferencesDialog *dialog)
 | 
			
		||||
{
 | 
			
		||||
    gtk_widget_destroy (dialog->dialog);
 | 
			
		||||
    // gtk_widget_destroy (dialog->new_keyboard_dialog);
 | 
			
		||||
 | 
			
		||||
    g_object_unref (dialog->settings);
 | 
			
		||||
    g_list_free_full (dialog->available_keyboards,
 | 
			
		||||
                      (GDestroyNotify) eek_xml_keyboard_desc_free);
 | 
			
		||||
 | 
			
		||||
    g_slice_free (PreferencesDialog, dialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,15 @@
 | 
			
		||||
#ifndef PREFERENCES_DIALOG_H
 | 
			
		||||
#define PREFERENCES_DIALOG_H 1
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _PreferencesDialog PreferencesDialog;
 | 
			
		||||
 | 
			
		||||
PreferencesDialog *preferences_dialog_new  (void);
 | 
			
		||||
void               preferences_dialog_run  (PreferencesDialog *dialog);
 | 
			
		||||
void               preferences_dialog_free (PreferencesDialog *dialog);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* PREFERENCES_DIALOG_H */
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,31 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<interface>
 | 
			
		||||
  <!-- interface-requires gtk+ 3.0 -->
 | 
			
		||||
  <object class="GtkAction" id="action1">
 | 
			
		||||
    <property name="stock_id">gtk-close</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAction" id="action2">
 | 
			
		||||
    <property name="stock_id">gtk-cancel</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAction" id="action3">
 | 
			
		||||
    <property name="label" translatable="yes">Select</property>
 | 
			
		||||
    <property name="stock_id">gtk-ok</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAdjustment" id="auto_hide_delay_adjustment">
 | 
			
		||||
    <property name="lower">100</property>
 | 
			
		||||
    <property name="upper">2000</property>
 | 
			
		||||
    <property name="value">500</property>
 | 
			
		||||
    <property name="step_increment">10</property>
 | 
			
		||||
    <property name="page_increment">10</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkListStore" id="available_keyboards_liststore">
 | 
			
		||||
    <columns>
 | 
			
		||||
      <!-- column-name id -->
 | 
			
		||||
      <column type="gchararray"/>
 | 
			
		||||
      <!-- column-name gchararray1 -->
 | 
			
		||||
      <column type="gchararray"/>
 | 
			
		||||
    </columns>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkDialog" id="dialog">
 | 
			
		||||
    <property name="can_focus">False</property>
 | 
			
		||||
    <property name="border_width">5</property>
 | 
			
		||||
@ -452,116 +477,6 @@
 | 
			
		||||
                    <property name="position">1</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkVBox" id="vbox1">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">False</property>
 | 
			
		||||
                    <property name="spacing">6</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkLabel" id="label2">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">False</property>
 | 
			
		||||
                        <property name="xalign">0</property>
 | 
			
		||||
                        <property name="label" translatable="yes">Keyboard</property>
 | 
			
		||||
                        <attributes>
 | 
			
		||||
                          <attribute name="weight" value="bold"/>
 | 
			
		||||
                        </attributes>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">False</property>
 | 
			
		||||
                        <property name="position">0</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkHBox" id="hbox1">
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">False</property>
 | 
			
		||||
                        <child>
 | 
			
		||||
                          <object class="GtkLabel" id="label3">
 | 
			
		||||
                            <property name="visible">True</property>
 | 
			
		||||
                            <property name="can_focus">False</property>
 | 
			
		||||
                            <property name="label">    </property>
 | 
			
		||||
                          </object>
 | 
			
		||||
                          <packing>
 | 
			
		||||
                            <property name="expand">False</property>
 | 
			
		||||
                            <property name="fill">False</property>
 | 
			
		||||
                            <property name="position">0</property>
 | 
			
		||||
                          </packing>
 | 
			
		||||
                        </child>
 | 
			
		||||
                        <child>
 | 
			
		||||
                          <object class="GtkVBox" id="appearances_vbox1">
 | 
			
		||||
                            <property name="visible">True</property>
 | 
			
		||||
                            <property name="can_focus">False</property>
 | 
			
		||||
                            <property name="spacing">6</property>
 | 
			
		||||
                            <child>
 | 
			
		||||
                              <object class="GtkCheckButton" id="start_fullscreen_toggle">
 | 
			
		||||
                                <property name="label" translatable="yes">Start in fullscreen mode</property>
 | 
			
		||||
                                <property name="visible">True</property>
 | 
			
		||||
                                <property name="can_focus">True</property>
 | 
			
		||||
                                <property name="receives_default">False</property>
 | 
			
		||||
                                <property name="use_action_appearance">False</property>
 | 
			
		||||
                                <property name="use_underline">True</property>
 | 
			
		||||
                                <property name="xalign">0</property>
 | 
			
		||||
                                <property name="draw_indicator">True</property>
 | 
			
		||||
                              </object>
 | 
			
		||||
                              <packing>
 | 
			
		||||
                                <property name="expand">False</property>
 | 
			
		||||
                                <property name="fill">False</property>
 | 
			
		||||
                                <property name="position">0</property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                            <child>
 | 
			
		||||
                              <object class="GtkTable" id="table2">
 | 
			
		||||
                                <property name="visible">True</property>
 | 
			
		||||
                                <property name="can_focus">False</property>
 | 
			
		||||
                                <property name="n_columns">4</property>
 | 
			
		||||
                                <child>
 | 
			
		||||
                                  <object class="GtkLabel" id="label4">
 | 
			
		||||
                                    <property name="visible">True</property>
 | 
			
		||||
                                    <property name="can_focus">False</property>
 | 
			
		||||
                                    <property name="label" translatable="yes">Keyboard type: </property>
 | 
			
		||||
                                  </object>
 | 
			
		||||
                                </child>
 | 
			
		||||
                                <child>
 | 
			
		||||
                                  <object class="GtkEntry" id="keyboard_entry">
 | 
			
		||||
                                    <property name="visible">True</property>
 | 
			
		||||
                                    <property name="can_focus">True</property>
 | 
			
		||||
                                    <property name="invisible_char">●</property>
 | 
			
		||||
                                  </object>
 | 
			
		||||
                                  <packing>
 | 
			
		||||
                                    <property name="left_attach">1</property>
 | 
			
		||||
                                    <property name="right_attach">4</property>
 | 
			
		||||
                                  </packing>
 | 
			
		||||
                                </child>
 | 
			
		||||
                              </object>
 | 
			
		||||
                              <packing>
 | 
			
		||||
                                <property name="expand">True</property>
 | 
			
		||||
                                <property name="fill">True</property>
 | 
			
		||||
                                <property name="position">1</property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                          </object>
 | 
			
		||||
                          <packing>
 | 
			
		||||
                            <property name="expand">True</property>
 | 
			
		||||
                            <property name="fill">True</property>
 | 
			
		||||
                            <property name="position">1</property>
 | 
			
		||||
                          </packing>
 | 
			
		||||
                        </child>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">False</property>
 | 
			
		||||
                        <property name="position">1</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                    <property name="position">2</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child type="tab">
 | 
			
		||||
@ -575,10 +490,119 @@
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <placeholder/>
 | 
			
		||||
              <object class="GtkVBox" id="keyboards_page">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">False</property>
 | 
			
		||||
                <property name="border_width">12</property>
 | 
			
		||||
                <property name="spacing">18</property>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkTreeView" id="selected_keyboards_treeview">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">True</property>
 | 
			
		||||
                    <property name="model">selected_keyboards_liststore</property>
 | 
			
		||||
                    <property name="headers_visible">False</property>
 | 
			
		||||
                    <property name="headers_clickable">False</property>
 | 
			
		||||
                    <child internal-child="selection">
 | 
			
		||||
                      <object class="GtkTreeSelection" id="treeview-selection2"/>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="expand">True</property>
 | 
			
		||||
                    <property name="fill">True</property>
 | 
			
		||||
                    <property name="position">0</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
                <child>
 | 
			
		||||
                  <object class="GtkButtonBox" id="buttonbox1">
 | 
			
		||||
                    <property name="visible">True</property>
 | 
			
		||||
                    <property name="can_focus">False</property>
 | 
			
		||||
                    <property name="spacing">2</property>
 | 
			
		||||
                    <property name="layout_style">end</property>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="up_button">
 | 
			
		||||
                        <property name="label">gtk-go-up</property>
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="sensitive">False</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="receives_default">True</property>
 | 
			
		||||
                        <property name="use_action_appearance">False</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">True</property>
 | 
			
		||||
                        <property name="position">0</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="down_button">
 | 
			
		||||
                        <property name="label">gtk-go-down</property>
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="sensitive">False</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="receives_default">True</property>
 | 
			
		||||
                        <property name="use_action_appearance">False</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">True</property>
 | 
			
		||||
                        <property name="position">1</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="add_button">
 | 
			
		||||
                        <property name="label">gtk-add</property>
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="receives_default">True</property>
 | 
			
		||||
                        <property name="use_action_appearance">False</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">True</property>
 | 
			
		||||
                        <property name="position">2</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                    <child>
 | 
			
		||||
                      <object class="GtkButton" id="remove_button">
 | 
			
		||||
                        <property name="label">gtk-remove</property>
 | 
			
		||||
                        <property name="visible">True</property>
 | 
			
		||||
                        <property name="sensitive">False</property>
 | 
			
		||||
                        <property name="can_focus">True</property>
 | 
			
		||||
                        <property name="receives_default">True</property>
 | 
			
		||||
                        <property name="use_action_appearance">False</property>
 | 
			
		||||
                        <property name="use_stock">True</property>
 | 
			
		||||
                      </object>
 | 
			
		||||
                      <packing>
 | 
			
		||||
                        <property name="expand">False</property>
 | 
			
		||||
                        <property name="fill">True</property>
 | 
			
		||||
                        <property name="position">3</property>
 | 
			
		||||
                      </packing>
 | 
			
		||||
                    </child>
 | 
			
		||||
                  </object>
 | 
			
		||||
                  <packing>
 | 
			
		||||
                    <property name="expand">False</property>
 | 
			
		||||
                    <property name="fill">False</property>
 | 
			
		||||
                    <property name="position">1</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="position">1</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child type="tab">
 | 
			
		||||
              <placeholder/>
 | 
			
		||||
              <object class="GtkLabel" id="label2">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">False</property>
 | 
			
		||||
                <property name="label" translatable="yes">Keyboards</property>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="position">1</property>
 | 
			
		||||
                <property name="tab_fill">False</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <placeholder/>
 | 
			
		||||
@ -599,8 +623,86 @@
 | 
			
		||||
      <action-widget response="0">button1</action-widget>
 | 
			
		||||
    </action-widgets>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAction" id="action1">
 | 
			
		||||
    <property name="stock_id">gtk-close</property>
 | 
			
		||||
  <object class="GtkDialog" id="new_keyboard_dialog">
 | 
			
		||||
    <property name="can_focus">False</property>
 | 
			
		||||
    <property name="border_width">5</property>
 | 
			
		||||
    <property name="default_height">430</property>
 | 
			
		||||
    <property name="destroy_with_parent">True</property>
 | 
			
		||||
    <property name="type_hint">dialog</property>
 | 
			
		||||
    <property name="transient_for">dialog</property>
 | 
			
		||||
    <child internal-child="vbox">
 | 
			
		||||
      <object class="GtkBox" id="dialog-vbox2">
 | 
			
		||||
        <property name="can_focus">False</property>
 | 
			
		||||
        <property name="orientation">vertical</property>
 | 
			
		||||
        <property name="spacing">2</property>
 | 
			
		||||
        <child internal-child="action_area">
 | 
			
		||||
          <object class="GtkButtonBox" id="dialog-action_area2">
 | 
			
		||||
            <property name="can_focus">False</property>
 | 
			
		||||
            <property name="layout_style">end</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="button2">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="receives_default">True</property>
 | 
			
		||||
                <property name="related_action">action2</property>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="expand">False</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
                <property name="position">0</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkButton" id="button3">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="receives_default">True</property>
 | 
			
		||||
                <property name="related_action">action3</property>
 | 
			
		||||
              </object>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="expand">False</property>
 | 
			
		||||
                <property name="fill">True</property>
 | 
			
		||||
                <property name="position">1</property>
 | 
			
		||||
              </packing>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="expand">False</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
            <property name="pack_type">end</property>
 | 
			
		||||
            <property name="position">0</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
        <child>
 | 
			
		||||
          <object class="GtkScrolledWindow" id="scrolledwindow1">
 | 
			
		||||
            <property name="visible">True</property>
 | 
			
		||||
            <property name="can_focus">True</property>
 | 
			
		||||
            <property name="shadow_type">in</property>
 | 
			
		||||
            <child>
 | 
			
		||||
              <object class="GtkTreeView" id="available_keyboards_treeview">
 | 
			
		||||
                <property name="visible">True</property>
 | 
			
		||||
                <property name="can_focus">True</property>
 | 
			
		||||
                <property name="model">available_keyboards_liststore</property>
 | 
			
		||||
                <property name="headers_visible">False</property>
 | 
			
		||||
                <property name="headers_clickable">False</property>
 | 
			
		||||
                <child internal-child="selection">
 | 
			
		||||
                  <object class="GtkTreeSelection" id="treeview-selection3"/>
 | 
			
		||||
                </child>
 | 
			
		||||
              </object>
 | 
			
		||||
            </child>
 | 
			
		||||
          </object>
 | 
			
		||||
          <packing>
 | 
			
		||||
            <property name="expand">True</property>
 | 
			
		||||
            <property name="fill">True</property>
 | 
			
		||||
            <property name="position">1</property>
 | 
			
		||||
          </packing>
 | 
			
		||||
        </child>
 | 
			
		||||
      </object>
 | 
			
		||||
    </child>
 | 
			
		||||
    <action-widgets>
 | 
			
		||||
      <action-widget response="0">button2</action-widget>
 | 
			
		||||
      <action-widget response="-5">button3</action-widget>
 | 
			
		||||
    </action-widgets>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAdjustment" id="repeat_delay_adjustment">
 | 
			
		||||
    <property name="lower">100</property>
 | 
			
		||||
@ -616,11 +718,12 @@
 | 
			
		||||
    <property name="step_increment">1</property>
 | 
			
		||||
    <property name="page_increment">1</property>
 | 
			
		||||
  </object>
 | 
			
		||||
  <object class="GtkAdjustment" id="auto_hide_delay_adjustment">
 | 
			
		||||
    <property name="lower">100</property>
 | 
			
		||||
    <property name="upper">2000</property>
 | 
			
		||||
    <property name="value">500</property>
 | 
			
		||||
    <property name="step_increment">10</property>
 | 
			
		||||
    <property name="page_increment">10</property>
 | 
			
		||||
  <object class="GtkListStore" id="selected_keyboards_liststore">
 | 
			
		||||
    <columns>
 | 
			
		||||
      <!-- column-name id -->
 | 
			
		||||
      <column type="gchararray"/>
 | 
			
		||||
      <!-- column-name gchararray1 -->
 | 
			
		||||
      <column type="gchararray"/>
 | 
			
		||||
    </columns>
 | 
			
		||||
  </object>
 | 
			
		||||
</interface>
 | 
			
		||||
 | 
			
		||||
@ -79,8 +79,11 @@ on_destroy (GtkWidget *widget, gpointer user_data)
 | 
			
		||||
    ServerContextService *context = user_data;
 | 
			
		||||
 | 
			
		||||
    g_assert (widget == context->window);
 | 
			
		||||
 | 
			
		||||
    context->window = NULL;
 | 
			
		||||
    context->widget = NULL;
 | 
			
		||||
 | 
			
		||||
    eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -96,6 +99,7 @@ on_notify_keyboard (GObject    *object,
 | 
			
		||||
        if (keyboard == NULL) {
 | 
			
		||||
            gtk_widget_hide (context->window);
 | 
			
		||||
            gtk_widget_destroy (context->widget);
 | 
			
		||||
            context->widget = NULL;
 | 
			
		||||
        } else {
 | 
			
		||||
            gboolean was_visible = gtk_widget_get_visible (context->window);
 | 
			
		||||
            /* avoid to send KeyboardVisibilityChanged */
 | 
			
		||||
@ -273,16 +277,21 @@ update_widget (ServerContextService *context)
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    const gchar *client_name;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gchar *theme_name, *theme_path;
 | 
			
		||||
    gchar *theme_name, *theme_filename, *theme_path;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
    
 | 
			
		||||
    if (context->widget)
 | 
			
		||||
    if (context->widget) {
 | 
			
		||||
        gtk_widget_destroy (context->widget);
 | 
			
		||||
        context->widget = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    theme_name = g_settings_get_string (context->settings, "theme");
 | 
			
		||||
    theme_path = g_strdup_printf ("%s/%s.css", THEMEDIR, theme_name);
 | 
			
		||||
    theme_filename = g_strdup_printf ("%s.css", theme_name);
 | 
			
		||||
    g_free (theme_name);
 | 
			
		||||
 | 
			
		||||
    theme_path = g_build_filename (THEMESDIR, theme_filename, NULL);
 | 
			
		||||
    g_free (theme_filename);
 | 
			
		||||
 | 
			
		||||
    theme = eek_theme_new (theme_path, NULL, NULL);
 | 
			
		||||
    g_free (theme_path);
 | 
			
		||||
 | 
			
		||||
@ -353,6 +362,11 @@ server_context_service_real_disabled (EekboardContextService *_context)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_real_destroyed (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_set_property (GObject      *object,
 | 
			
		||||
                                     guint         prop_id,
 | 
			
		||||
@ -377,9 +391,7 @@ server_context_service_set_property (GObject      *object,
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_set_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
                               value);
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -408,6 +420,7 @@ server_context_service_class_init (ServerContextServiceClass *klass)
 | 
			
		||||
    context_class->hide_keyboard = server_context_service_real_hide_keyboard;
 | 
			
		||||
    context_class->enabled = server_context_service_real_enabled;
 | 
			
		||||
    context_class->disabled = server_context_service_real_disabled;
 | 
			
		||||
    context_class->destroyed = server_context_service_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = server_context_service_set_property;
 | 
			
		||||
    gobject_class->dispose = server_context_service_dispose;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								src/setup-main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/setup-main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2012 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "preferences-dialog.h"
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    PreferencesDialog *dialog;
 | 
			
		||||
 | 
			
		||||
    if (!gtk_init_check (&argc, &argv)) {
 | 
			
		||||
        g_printerr ("Can't init GTK\n");
 | 
			
		||||
        return EXIT_FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dialog = preferences_dialog_new ();
 | 
			
		||||
    preferences_dialog_run (dialog);
 | 
			
		||||
    preferences_dialog_free (dialog);
 | 
			
		||||
 | 
			
		||||
    return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user