Add a standalone application.
This commit is contained in:
		@ -17,4 +17,4 @@
 | 
				
			|||||||
# 02110-1301 USA
 | 
					# 02110-1301 USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ACLOCAL_AMFLAGS = -I m4
 | 
					ACLOCAL_AMFLAGS = -I m4
 | 
				
			||||||
SUBDIRS = eek examples tests docs
 | 
					SUBDIRS = eek src examples tests docs
 | 
				
			||||||
 | 
				
			|||||||
@ -34,12 +34,16 @@ PKG_CHECK_MODULES([PANGO], [pango], ,
 | 
				
			|||||||
  [AC_MSG_ERROR([Pango not found])])
 | 
					  [AC_MSG_ERROR([Pango not found])])
 | 
				
			||||||
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
 | 
					PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
 | 
				
			||||||
  [AC_MSG_ERROR([Clutter not found])])
 | 
					  [AC_MSG_ERROR([Clutter not found])])
 | 
				
			||||||
 | 
					PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10], ,
 | 
				
			||||||
 | 
					  [AC_MSG_ERROR([clutter-gtk not found])])
 | 
				
			||||||
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], ,
 | 
					PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], ,
 | 
				
			||||||
  [AC_MSG_ERROR([GTK2 not found])])
 | 
					  [AC_MSG_ERROR([GTK2 not found])])
 | 
				
			||||||
PKG_CHECK_MODULES([XKB], [x11], ,
 | 
					PKG_CHECK_MODULES([XKB], [x11], ,
 | 
				
			||||||
  [AC_MSG_ERROR([XKB support not found])])
 | 
					  [AC_MSG_ERROR([XKB support not found])])
 | 
				
			||||||
PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
 | 
					PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
 | 
				
			||||||
  [AC_MSG_ERROR([Libxklavier not found])])
 | 
					  [AC_MSG_ERROR([Libxklavier not found])])
 | 
				
			||||||
 | 
					PKG_CHECK_MODULES([LIBFAKEKEY], [libfakekey], ,
 | 
				
			||||||
 | 
					  [AC_MSG_ERROR([libfakekey not found])])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
 | 
					GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,6 +55,7 @@ AC_CHECK_PROGS([PYTHON], [python])
 | 
				
			|||||||
AC_CONFIG_HEADERS([eek/config.h])
 | 
					AC_CONFIG_HEADERS([eek/config.h])
 | 
				
			||||||
AC_CONFIG_FILES([Makefile
 | 
					AC_CONFIG_FILES([Makefile
 | 
				
			||||||
eek/Makefile
 | 
					eek/Makefile
 | 
				
			||||||
 | 
					src/Makefile
 | 
				
			||||||
examples/Makefile
 | 
					examples/Makefile
 | 
				
			||||||
tests/Makefile
 | 
					tests/Makefile
 | 
				
			||||||
docs/Makefile
 | 
					docs/Makefile
 | 
				
			||||||
 | 
				
			|||||||
@ -154,6 +154,18 @@ eek_keyboard_real_create_section (EekKeyboard *self)
 | 
				
			|||||||
    return section;
 | 
					    return section;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_group_changed (EekLayout *layout,
 | 
				
			||||||
 | 
					                  gint       new_group,
 | 
				
			||||||
 | 
					                  gpointer   user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard = user_data;
 | 
				
			||||||
 | 
					    gint group, level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_keyboard_get_keysym_index (keyboard, &group, &level);
 | 
				
			||||||
 | 
					    eek_keyboard_set_keysym_index (keyboard, new_group, level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_keyboard_real_set_layout (EekKeyboard *self,
 | 
					eek_keyboard_real_set_layout (EekKeyboard *self,
 | 
				
			||||||
                              EekLayout   *layout)
 | 
					                              EekLayout   *layout)
 | 
				
			||||||
@ -163,6 +175,8 @@ eek_keyboard_real_set_layout (EekKeyboard *self,
 | 
				
			|||||||
    g_return_if_fail (EEK_IS_LAYOUT(layout));
 | 
					    g_return_if_fail (EEK_IS_LAYOUT(layout));
 | 
				
			||||||
    priv->layout = layout;
 | 
					    priv->layout = layout;
 | 
				
			||||||
    g_object_ref_sink (priv->layout);
 | 
					    g_object_ref_sink (priv->layout);
 | 
				
			||||||
 | 
					    g_signal_connect (priv->layout, "group_changed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_group_changed), self);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -173,6 +187,8 @@ eek_keyboard_real_realize (EekKeyboard *self)
 | 
				
			|||||||
    g_return_if_fail (priv->layout);
 | 
					    g_return_if_fail (priv->layout);
 | 
				
			||||||
    g_return_if_fail (!priv->is_realized);
 | 
					    g_return_if_fail (!priv->is_realized);
 | 
				
			||||||
    EEK_LAYOUT_GET_IFACE(priv->layout)->apply (priv->layout, self);
 | 
					    EEK_LAYOUT_GET_IFACE(priv->layout)->apply (priv->layout, self);
 | 
				
			||||||
 | 
					    /* apply the initial group setting */
 | 
				
			||||||
 | 
					    on_group_changed (priv->layout, eek_layout_get_group (priv->layout), self);
 | 
				
			||||||
    priv->is_realized = TRUE;
 | 
					    priv->is_realized = TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -33,13 +33,39 @@
 | 
				
			|||||||
#include "eek-layout.h"
 | 
					#include "eek-layout.h"
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    GROUP_CHANGED,
 | 
				
			||||||
 | 
					    CHANGED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_layout_base_init (gpointer gobject_class)
 | 
					eek_layout_base_init (gpointer gobject_class)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static gboolean is_initialized = FALSE;
 | 
					    static gboolean is_initialized = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!is_initialized) {
 | 
					    if (!is_initialized) {
 | 
				
			||||||
        /* TODO: signals */
 | 
					        signals[GROUP_CHANGED] =
 | 
				
			||||||
 | 
					            g_signal_new ("group-changed",
 | 
				
			||||||
 | 
					                          G_TYPE_FROM_INTERFACE(gobject_class),
 | 
				
			||||||
 | 
					                          G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                          G_STRUCT_OFFSET(EekLayoutIface, group_changed),
 | 
				
			||||||
 | 
					                          NULL,
 | 
				
			||||||
 | 
					                          NULL,
 | 
				
			||||||
 | 
					                          g_cclosure_marshal_VOID__INT,
 | 
				
			||||||
 | 
					                          G_TYPE_NONE, 1,
 | 
				
			||||||
 | 
					                          G_TYPE_INT);
 | 
				
			||||||
 | 
					        signals[CHANGED] =
 | 
				
			||||||
 | 
					            g_signal_new ("changed",
 | 
				
			||||||
 | 
					                          G_TYPE_FROM_INTERFACE(gobject_class),
 | 
				
			||||||
 | 
					                          G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                          G_STRUCT_OFFSET(EekLayoutIface, changed),
 | 
				
			||||||
 | 
					                          NULL,
 | 
				
			||||||
 | 
					                          NULL,
 | 
				
			||||||
 | 
					                          g_cclosure_marshal_VOID__VOID,
 | 
				
			||||||
 | 
					                          G_TYPE_NONE, 0);
 | 
				
			||||||
        is_initialized = TRUE;
 | 
					        is_initialized = TRUE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -69,3 +95,9 @@ eek_layout_apply (EekLayout   *layout,
 | 
				
			|||||||
    EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
 | 
					    EEK_LAYOUT_GET_IFACE(layout)->apply (layout, keyboard);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gint
 | 
				
			||||||
 | 
					eek_layout_get_group (EekLayout *layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_LAYOUT(layout), -1);
 | 
				
			||||||
 | 
					    return EEK_LAYOUT_GET_IFACE(layout)->get_group (layout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -39,13 +39,21 @@ struct _EekLayoutIface
 | 
				
			|||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    GTypeInterface parent_iface;
 | 
					    GTypeInterface parent_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void (*apply) (EekLayout   *self,
 | 
					    /*< public >*/
 | 
				
			||||||
                   EekKeyboard *keyboard);
 | 
					    void (* apply)         (EekLayout   *self,
 | 
				
			||||||
 | 
					                            EekKeyboard *keyboard);
 | 
				
			||||||
 | 
					    gint (* get_group)     (EekLayout   *self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void (* group_changed) (EekLayout   *self,
 | 
				
			||||||
 | 
					                            gint         group);
 | 
				
			||||||
 | 
					    void (* changed)       (EekLayout   *self);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GType eek_layout_get_type (void) G_GNUC_CONST;
 | 
					GType eek_layout_get_type  (void) G_GNUC_CONST;
 | 
				
			||||||
void  eek_layout_apply    (EekLayout   *layout,
 | 
					void  eek_layout_apply     (EekLayout   *layout,
 | 
				
			||||||
                           EekKeyboard *keyboard);
 | 
					                            EekKeyboard *keyboard);
 | 
				
			||||||
 | 
					gint  eek_layout_get_group (EekLayout   *layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_LAYOUT_H */
 | 
					#endif  /* EEK_LAYOUT_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -27,14 +27,15 @@
 | 
				
			|||||||
 * elements using XKB.
 | 
					 * elements using XKB.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_CONFIG_H
 | 
					 | 
				
			||||||
#include "config.h"
 | 
					 | 
				
			||||||
#endif  /* HAVE_CONFIG_H */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <gdk/gdkx.h>
 | 
					#include <gdk/gdkx.h>
 | 
				
			||||||
#include <X11/XKBlib.h>
 | 
					#include <X11/XKBlib.h>
 | 
				
			||||||
#include <X11/extensions/XKBgeom.h>
 | 
					#include <X11/extensions/XKBgeom.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-xkb-layout.h"
 | 
					#include "eek-xkb-layout.h"
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
@ -308,19 +309,41 @@ eek_xkb_layout_real_apply (EekLayout *layout, EekKeyboard *keyboard)
 | 
				
			|||||||
    create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
 | 
					    create_keyboard (EEK_XKB_LAYOUT(layout), keyboard);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gint
 | 
				
			||||||
 | 
					compare_component_names (gchar *name0, gchar *name1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (name0 && name1)
 | 
				
			||||||
 | 
					        return g_strcmp0 (name0, name1);
 | 
				
			||||||
 | 
					    else if (!name0 && name1)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    else if (name0 && !name1)
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_xkb_layout_real_set_names (EekXkbLayout *self, XkbComponentNamesRec *names)
 | 
					eek_xkb_layout_real_set_names (EekXkbLayout *self, XkbComponentNamesRec *names)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
 | 
					    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
 | 
				
			||||||
 | 
					    gboolean is_changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_if_fail (priv);
 | 
					    g_return_if_fail (priv);
 | 
				
			||||||
 | 
					    is_changed =
 | 
				
			||||||
 | 
					        compare_component_names (names->keycodes, priv->names.keycodes) != 0;
 | 
				
			||||||
    g_free (priv->names.keycodes);
 | 
					    g_free (priv->names.keycodes);
 | 
				
			||||||
    priv->names.keycodes = g_strdup (names->keycodes);
 | 
					    priv->names.keycodes = g_strdup (names->keycodes);
 | 
				
			||||||
 | 
					    is_changed =
 | 
				
			||||||
 | 
					        compare_component_names (names->geometry, priv->names.geometry) != 0;
 | 
				
			||||||
    g_free (priv->names.geometry);
 | 
					    g_free (priv->names.geometry);
 | 
				
			||||||
    priv->names.geometry = g_strdup (names->geometry);
 | 
					    priv->names.geometry = g_strdup (names->geometry);
 | 
				
			||||||
 | 
					    is_changed =
 | 
				
			||||||
 | 
					        compare_component_names (names->symbols, priv->names.symbols) != 0;
 | 
				
			||||||
    g_free (priv->names.symbols);
 | 
					    g_free (priv->names.symbols);
 | 
				
			||||||
    priv->names.symbols = g_strdup (names->symbols);
 | 
					    priv->names.symbols = g_strdup (names->symbols);
 | 
				
			||||||
    get_keyboard (self);
 | 
					    get_keyboard (self);
 | 
				
			||||||
 | 
					    if (is_changed)
 | 
				
			||||||
 | 
					        g_signal_emit_by_name (self, "changed");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -574,11 +597,18 @@ void
 | 
				
			|||||||
eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes)
 | 
					eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
					    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
				
			||||||
 | 
					    gboolean is_changed = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_if_fail (priv);
 | 
					    g_return_if_fail (priv);
 | 
				
			||||||
 | 
					    if (keycodes && priv->names.keycodes)
 | 
				
			||||||
 | 
					        is_changed = g_strcmp0 (keycodes, priv->names.keycodes) != 0;
 | 
				
			||||||
 | 
					    else if (keycodes == NULL && priv->names.keycodes == NULL)
 | 
				
			||||||
 | 
					        is_changed = FALSE;
 | 
				
			||||||
    g_free (priv->names.keycodes);
 | 
					    g_free (priv->names.keycodes);
 | 
				
			||||||
    priv->names.keycodes = g_strdup (keycodes);
 | 
					    priv->names.keycodes = g_strdup (keycodes);
 | 
				
			||||||
    get_keyboard (layout);
 | 
					    get_keyboard (layout);
 | 
				
			||||||
 | 
					    if (is_changed)
 | 
				
			||||||
 | 
					        g_signal_emit_by_name (layout, "changed");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -592,11 +622,18 @@ void
 | 
				
			|||||||
eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry)
 | 
					eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
					    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
				
			||||||
 | 
					    gboolean is_changed = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_if_fail (priv);
 | 
					    g_return_if_fail (priv);
 | 
				
			||||||
 | 
					    if (geometry && priv->names.geometry)
 | 
				
			||||||
 | 
					        is_changed = g_strcmp0 (geometry, priv->names.geometry) != 0;
 | 
				
			||||||
 | 
					    else if (geometry == NULL && priv->names.geometry == NULL)
 | 
				
			||||||
 | 
					        is_changed = FALSE;
 | 
				
			||||||
    g_free (priv->names.geometry);
 | 
					    g_free (priv->names.geometry);
 | 
				
			||||||
    priv->names.geometry = g_strdup (geometry);
 | 
					    priv->names.geometry = g_strdup (geometry);
 | 
				
			||||||
    get_keyboard (layout);
 | 
					    get_keyboard (layout);
 | 
				
			||||||
 | 
					    if (is_changed)
 | 
				
			||||||
 | 
					        g_signal_emit_by_name (layout, "changed");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -610,11 +647,18 @@ void
 | 
				
			|||||||
eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols)
 | 
					eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
					    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
				
			||||||
 | 
					    gboolean is_changed = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_return_if_fail (priv);
 | 
					    g_return_if_fail (priv);
 | 
				
			||||||
 | 
					    if (symbols && priv->names.symbols)
 | 
				
			||||||
 | 
					        is_changed = g_strcmp0 (symbols, priv->names.symbols) != 0;
 | 
				
			||||||
 | 
					    else if (symbols == NULL && priv->names.symbols == NULL)
 | 
				
			||||||
 | 
					        is_changed = FALSE;
 | 
				
			||||||
    g_free (priv->names.symbols);
 | 
					    g_free (priv->names.symbols);
 | 
				
			||||||
    priv->names.symbols = g_strdup (symbols);
 | 
					    priv->names.symbols = g_strdup (symbols);
 | 
				
			||||||
    get_keyboard (layout);
 | 
					    get_keyboard (layout);
 | 
				
			||||||
 | 
					    if (is_changed)
 | 
				
			||||||
 | 
					        g_signal_emit_by_name (layout, "changed");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define noKBDRAW_DEBUG
 | 
					#define noKBDRAW_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT);
 | 
					static void eek_layout_iface_init (EekLayoutIface *iface);
 | 
				
			||||||
 | 
					static EekLayoutIface *parent_layout_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_WITH_CODE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
				
			||||||
 | 
					                         G_IMPLEMENT_INTERFACE(EEK_TYPE_LAYOUT,
 | 
				
			||||||
 | 
					                                               eek_layout_iface_init));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EEK_XKL_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
					#define EEK_XKL_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
				
			||||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
 | 
					    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
 | 
				
			||||||
@ -72,6 +77,26 @@ extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void get_xkb_component_names (EekXklLayout *layout);
 | 
					static void get_xkb_component_names (EekXklLayout *layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gint
 | 
				
			||||||
 | 
					eek_xkl_layout_real_get_group (EekLayout *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
 | 
				
			||||||
 | 
					    XklState *state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state = xkl_engine_get_current_state (priv->engine);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (state, -1);
 | 
				
			||||||
 | 
					    return state->group;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_layout_iface_init (EekLayoutIface *iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    parent_layout_iface = g_type_interface_peek_parent (iface);
 | 
				
			||||||
 | 
					    if (!parent_layout_iface)
 | 
				
			||||||
 | 
					        parent_layout_iface = g_type_default_interface_peek (EEK_TYPE_LAYOUT);
 | 
				
			||||||
 | 
					    iface->get_group = eek_xkl_layout_real_get_group;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_xkl_layout_finalize (GObject *object)
 | 
					eek_xkl_layout_finalize (GObject *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -145,12 +170,12 @@ eek_xkl_layout_get_property (GObject    *object,
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
					eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
    GParamSpec        *pspec;
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
 | 
					    g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gobject_class->finalize     = eek_xkl_layout_finalize;
 | 
					    gobject_class->finalize = eek_xkl_layout_finalize;
 | 
				
			||||||
    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
					    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
				
			||||||
    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
					    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,6 +201,19 @@ eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
				
			|||||||
    g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
 | 
					    g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_state_changed (XklEngine           *xklengine,
 | 
				
			||||||
 | 
					                  XklEngineStateChange type,
 | 
				
			||||||
 | 
					                  gint                 value,
 | 
				
			||||||
 | 
					                  gboolean             restore,
 | 
				
			||||||
 | 
					                  gpointer             user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekLayout *layout = user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type == GROUP_CHANGED)
 | 
				
			||||||
 | 
					        g_signal_emit_by_name (layout, "group_changed", value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_xkl_layout_init (EekXklLayout *self)
 | 
					eek_xkl_layout_init (EekXklLayout *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -189,18 +227,37 @@ eek_xkl_layout_init (EekXklLayout *self)
 | 
				
			|||||||
    g_return_if_fail (display);
 | 
					    g_return_if_fail (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    priv->engine = xkl_engine_get_instance (display);
 | 
					    priv->engine = xkl_engine_get_instance (display);
 | 
				
			||||||
 | 
					    g_signal_connect (priv->engine, "X-state-changed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_state_changed), self);
 | 
				
			||||||
    xkl_config_rec_get_from_server (&priv->config, priv->engine);
 | 
					    xkl_config_rec_get_from_server (&priv->config, priv->engine);
 | 
				
			||||||
    get_xkb_component_names (self);
 | 
					    get_xkb_component_names (self);
 | 
				
			||||||
 | 
					    xkl_engine_start_listen (priv->engine, XKLL_TRACK_KEYBOARD_STATE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekLayout *
 | 
					EekLayout *
 | 
				
			||||||
eek_xkl_layout_new (gchar **layouts,
 | 
					eek_xkl_layout_new (void)
 | 
				
			||||||
                    gchar **variants,
 | 
					 | 
				
			||||||
                    gchar **options)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return g_object_new (EEK_TYPE_XKL_LAYOUT, NULL);
 | 
					    return g_object_new (EEK_TYPE_XKL_LAYOUT, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_xkl_layout_set_config (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                           gchar       **layouts,
 | 
				
			||||||
 | 
					                           gchar       **variants,
 | 
				
			||||||
 | 
					                           gchar       **options)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (priv);
 | 
				
			||||||
 | 
					    g_strfreev (priv->config.layouts);
 | 
				
			||||||
 | 
					    priv->config.layouts = g_strdupv (layouts);
 | 
				
			||||||
 | 
					    g_strfreev (priv->config.variants);
 | 
				
			||||||
 | 
					    priv->config.variants = g_strdupv (variants);
 | 
				
			||||||
 | 
					    g_strfreev (priv->config.options);
 | 
				
			||||||
 | 
					    priv->config.options = g_strdupv (options);
 | 
				
			||||||
 | 
					    get_xkb_component_names (layout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_xkl_layout_set_layouts (EekXklLayout *layout, gchar **layouts)
 | 
					eek_xkl_layout_set_layouts (EekXklLayout *layout, gchar **layouts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -268,6 +325,7 @@ get_xkb_component_names (EekXklLayout *layout)
 | 
				
			|||||||
    XkbComponentNamesRec names;
 | 
					    XkbComponentNamesRec names;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (xkl_xkb_config_native_prepare (priv->engine, &priv->config, &names)) {
 | 
					    if (xkl_xkb_config_native_prepare (priv->engine, &priv->config, &names)) {
 | 
				
			||||||
 | 
					        g_debug ("symbols = \"%s\"", names.symbols);
 | 
				
			||||||
        EEK_XKB_LAYOUT_GET_CLASS (layout)->
 | 
					        EEK_XKB_LAYOUT_GET_CLASS (layout)->
 | 
				
			||||||
            set_names (EEK_XKB_LAYOUT(layout), &names);
 | 
					            set_names (EEK_XKB_LAYOUT(layout), &names);
 | 
				
			||||||
        xkl_xkb_config_native_cleanup (priv->engine, &names);
 | 
					        xkl_xkb_config_native_cleanup (priv->engine, &names);
 | 
				
			||||||
 | 
				
			|||||||
@ -51,7 +51,10 @@ struct _EekXklLayoutClass
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
GType      eek_xkl_layout_get_type     (void) G_GNUC_CONST;
 | 
					GType      eek_xkl_layout_get_type     (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekLayout *eek_xkl_layout_new          (gchar       **layouts,
 | 
					EekLayout *eek_xkl_layout_new          (void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void       eek_xkl_layout_set_config   (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                        gchar       **layouts,
 | 
				
			||||||
                                        gchar       **variants,
 | 
					                                        gchar       **variants,
 | 
				
			||||||
                                        gchar       **options);
 | 
					                                        gchar       **options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -63,7 +66,8 @@ void       eek_xkl_layout_set_options  (EekXklLayout *layout,
 | 
				
			|||||||
                                        gchar       **options);
 | 
					                                        gchar       **options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gchar    **eek_xkl_layout_get_layouts  (EekXklLayout *layout);
 | 
					gchar    **eek_xkl_layout_get_layouts  (EekXklLayout *layout);
 | 
				
			||||||
gchar    **eek_xkl_layout_get_variants (EekXklLayout *layout);
 | 
					gchar    **eek_xkl_layout_get_variants
 | 
				
			||||||
 | 
					                                       (EekXklLayout *layout);
 | 
				
			||||||
gchar    **eek_xkl_layout_get_options  (EekXklLayout *layout);
 | 
					gchar    **eek_xkl_layout_get_options  (EekXklLayout *layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,14 @@
 | 
				
			|||||||
#include "eek/eek-clutter.h"
 | 
					 | 
				
			||||||
#include "eek/eek-xkb.h"
 | 
					 | 
				
			||||||
#include <gtk/gtk.h>
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek/eek-clutter.h"
 | 
				
			||||||
 | 
					#include "eek/eek-xkb.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CSW 640
 | 
					#define CSW 640
 | 
				
			||||||
#define CSH 480
 | 
					#define CSH 480
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2010 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					# Copyright (C) 2010 Red Hat, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					# modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					# as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					# the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					# Lesser General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					# License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					# 02110-1301 USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bin_PROGRAMS = eekboard
 | 
				
			||||||
 | 
					eekboard_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS) $(LIBXKLAVIER_CFLAGS) $(LIBFAKEKEY_CFLAGS)
 | 
				
			||||||
 | 
					eekboard_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkl.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(GTK2_CFLAGS) $(XKB_LIBS) $(LIBXKLAVIER_LIBS) $(LIBFAKEKEY_LIBS)
 | 
				
			||||||
							
								
								
									
										416
									
								
								src/eekboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								src/eekboard.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,416 @@
 | 
				
			|||||||
 | 
					#include <clutter-gtk/clutter-gtk.h>
 | 
				
			||||||
 | 
					#include <fakekey/fakekey.h>
 | 
				
			||||||
 | 
					#include <glib/gi18n.h>
 | 
				
			||||||
 | 
					#include <gdk/gdkx.h>
 | 
				
			||||||
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
 | 
					#include <libxklavier/xklavier.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek/eek-clutter.h"
 | 
				
			||||||
 | 
					#include "eek/eek-xkl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CSW 640
 | 
				
			||||||
 | 
					#define CSH 480
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gchar *window_id = NULL;
 | 
				
			||||||
 | 
					gfloat stage_width, stage_height;
 | 
				
			||||||
 | 
					Display *display;
 | 
				
			||||||
 | 
					FakeKey *fakekey;
 | 
				
			||||||
 | 
					Window target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekLayout *layout;
 | 
				
			||||||
 | 
					EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void on_capture_key_event_toggled (GtkToggleAction *action,
 | 
				
			||||||
 | 
					                                          GtkWidget *window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const GOptionEntry options[] = {
 | 
				
			||||||
 | 
					    {"window-id", '\0', 0, G_OPTION_ARG_STRING, &window_id,
 | 
				
			||||||
 | 
					     "the target window ID; use xwininfo to obtain the value", NULL},
 | 
				
			||||||
 | 
					    {NULL},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const GtkActionEntry action_entry[] = {
 | 
				
			||||||
 | 
					    {"FileMenu", NULL, N_("_File")},
 | 
				
			||||||
 | 
					    {"KeyboardMenu", NULL, N_("_Keyboard")},
 | 
				
			||||||
 | 
					    {"HelpMenu", NULL, N_("_Help")},
 | 
				
			||||||
 | 
					    {"Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (gtk_main_quit)},
 | 
				
			||||||
 | 
					    {"SetLayout", NULL, N_("Set Layout"), NULL, NULL, NULL},
 | 
				
			||||||
 | 
					    {"About", GTK_STOCK_ABOUT, NULL, NULL, NULL, NULL}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const GtkToggleActionEntry toggle_action_entry[] = {
 | 
				
			||||||
 | 
					    {"CaptureKeyEvent", NULL, N_("Capture Key Event"), NULL, NULL,
 | 
				
			||||||
 | 
					     G_CALLBACK(on_capture_key_event_toggled), FALSE}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_capture_key_event_toggled (GtkToggleAction *action,
 | 
				
			||||||
 | 
					                              GtkWidget *window)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gboolean active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    active = gtk_toggle_action_get_active (action);
 | 
				
			||||||
 | 
					    g_object_set (G_OBJECT(window), "accept_focus", active, NULL);
 | 
				
			||||||
 | 
					    g_object_set (G_OBJECT(window), "can_focus", active, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekBoardLayoutVariant {
 | 
				
			||||||
 | 
					    gchar *layout;
 | 
				
			||||||
 | 
					    gchar *variant;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _EekBoardLayoutVariant EekBoardLayoutVariant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_key_pressed (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                EekKey      *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fakekey_press_keysym (fakekey, eek_key_get_keysym (key), 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_key_released (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                 EekKey      *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fakekey_release (fakekey);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_activate (GtkAction *action, gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBoardLayoutVariant *config = user_data;
 | 
				
			||||||
 | 
					    gchar *layouts[2], *variants[2], **vp = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    layouts[0] = config->layout;
 | 
				
			||||||
 | 
					    layouts[1] = NULL;
 | 
				
			||||||
 | 
					    if (config->variant) {
 | 
				
			||||||
 | 
					        variants[0] = config->variant;
 | 
				
			||||||
 | 
					        variants[1] = NULL;
 | 
				
			||||||
 | 
					        vp = variants;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    eek_xkl_layout_set_config (EEK_XKL_LAYOUT(layout), layouts, vp, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekKeyboard *
 | 
				
			||||||
 | 
					create_keyboard (ClutterActor *stage,
 | 
				
			||||||
 | 
					                 EekLayout    *layout,
 | 
				
			||||||
 | 
					                 gfloat        width,
 | 
				
			||||||
 | 
					                 gfloat        height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					    ClutterActor *actor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keyboard = eek_clutter_keyboard_new (width, height);
 | 
				
			||||||
 | 
					    g_signal_connect (keyboard, "key-pressed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_key_pressed), NULL);
 | 
				
			||||||
 | 
					    g_signal_connect (keyboard, "key-released",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_key_released), NULL);
 | 
				
			||||||
 | 
					    eek_keyboard_set_layout (keyboard, layout);
 | 
				
			||||||
 | 
					    actor = eek_clutter_keyboard_get_actor (EEK_CLUTTER_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    clutter_actor_set_name (actor, "keyboard");
 | 
				
			||||||
 | 
					    clutter_actor_get_size (actor, &width, &height);
 | 
				
			||||||
 | 
					    clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor);
 | 
				
			||||||
 | 
					    clutter_actor_set_size (stage, width, height);
 | 
				
			||||||
 | 
					    return keyboard;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FIXME: EekKeyboard should handle relayout by itself. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_changed (EekLayout *layout, gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ClutterActor *stage = user_data, *actor;
 | 
				
			||||||
 | 
					    gfloat width, height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clutter_actor_get_size (stage, &width, &height);
 | 
				
			||||||
 | 
					    actor = clutter_container_find_child_by_name (stage, "keyboard");
 | 
				
			||||||
 | 
					    if (actor)
 | 
				
			||||||
 | 
					        clutter_container_remove_actor (CLUTTER_CONTAINER(stage), actor);
 | 
				
			||||||
 | 
					    g_object_unref (keyboard);
 | 
				
			||||||
 | 
					    create_keyboard (stage, layout, width, height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char ui_description[] =
 | 
				
			||||||
 | 
					    "<ui>"
 | 
				
			||||||
 | 
					    "  <menubar name='MainMenu'>"
 | 
				
			||||||
 | 
					    "    <menu action='FileMenu'>"
 | 
				
			||||||
 | 
					    "      <menuitem action='Quit'/>"
 | 
				
			||||||
 | 
					    "    </menu>"
 | 
				
			||||||
 | 
					    "    <menu action='KeyboardMenu'>"
 | 
				
			||||||
 | 
					    "      <menuitem action='CaptureKeyEvent'/>"
 | 
				
			||||||
 | 
					    "      <menu action='SetLayout'>"
 | 
				
			||||||
 | 
					    "        <placeholder name='LayoutsPH'/>"
 | 
				
			||||||
 | 
					    "      </menu>"
 | 
				
			||||||
 | 
					    "    </menu>"
 | 
				
			||||||
 | 
					    "    <menu action='HelpMenu'>"
 | 
				
			||||||
 | 
					    "      <menuitem action='About'/>"
 | 
				
			||||||
 | 
					    "    </menu>"
 | 
				
			||||||
 | 
					    "  </menubar>"
 | 
				
			||||||
 | 
					    "</ui>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SET_LAYOUT_UI_PATH "/MainMenu/KeyboardMenu/SetLayout/LayoutsPH"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekBoardAddLayoutData {
 | 
				
			||||||
 | 
					    GtkUIManager *ui_manager;
 | 
				
			||||||
 | 
					    GtkActionGroup *action_group;
 | 
				
			||||||
 | 
					    guint merge_id;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _EekBoardAddLayoutData EekBoardAddLayoutData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekBoardAddVariantData {
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
 | 
					    gchar *description;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _EekBoardAddVariantData EekBoardAddVariantData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					variant_callback (XklConfigRegistry *registry,
 | 
				
			||||||
 | 
					                  XklConfigItem *item,
 | 
				
			||||||
 | 
					                  gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBoardAddVariantData *variant_data;
 | 
				
			||||||
 | 
					    GSList **head = user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    variant_data = g_slice_new (EekBoardAddVariantData);
 | 
				
			||||||
 | 
					    variant_data->name = g_strdup (item->name);
 | 
				
			||||||
 | 
					    variant_data->description = g_strdup (item->description);
 | 
				
			||||||
 | 
					    *head = g_slist_prepend (*head, variant_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					layout_callback (XklConfigRegistry *registry,
 | 
				
			||||||
 | 
					                 XklConfigItem *item,
 | 
				
			||||||
 | 
					                 gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkAction *action;
 | 
				
			||||||
 | 
					    EekBoardAddLayoutData *layout_data = user_data;
 | 
				
			||||||
 | 
					    GSList *variants = NULL;
 | 
				
			||||||
 | 
					    char layout_action_name[128], variant_action_name[128];
 | 
				
			||||||
 | 
					    EekBoardLayoutVariant *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_snprintf (layout_action_name, sizeof (layout_action_name),
 | 
				
			||||||
 | 
					                "SetLayout%s", item->name);
 | 
				
			||||||
 | 
					    action = gtk_action_new (layout_action_name, item->description, NULL, NULL);
 | 
				
			||||||
 | 
					    gtk_action_group_add_action (layout_data->action_group, action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xkl_config_registry_foreach_layout_variant (registry,
 | 
				
			||||||
 | 
					                                                item->name,
 | 
				
			||||||
 | 
					                                                variant_callback,
 | 
				
			||||||
 | 
					                                                &variants);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!variants) {
 | 
				
			||||||
 | 
					        data = g_slice_new (EekBoardLayoutVariant);
 | 
				
			||||||
 | 
					        data->layout = g_strdup (item->name);
 | 
				
			||||||
 | 
					        data->variant = NULL;
 | 
				
			||||||
 | 
					        g_signal_connect (action, "activate", G_CALLBACK (on_activate),
 | 
				
			||||||
 | 
					                          data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        g_object_unref (action);
 | 
				
			||||||
 | 
					        gtk_ui_manager_add_ui (layout_data->ui_manager, layout_data->merge_id,
 | 
				
			||||||
 | 
					                               SET_LAYOUT_UI_PATH,
 | 
				
			||||||
 | 
					                               layout_action_name, layout_action_name,
 | 
				
			||||||
 | 
					                               GTK_UI_MANAGER_MENUITEM, FALSE);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        char layout_path[128];
 | 
				
			||||||
 | 
					        GSList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        g_object_unref (action);
 | 
				
			||||||
 | 
					        gtk_ui_manager_add_ui (layout_data->ui_manager,
 | 
				
			||||||
 | 
					                               layout_data->merge_id,
 | 
				
			||||||
 | 
					                               SET_LAYOUT_UI_PATH,
 | 
				
			||||||
 | 
					                               layout_action_name, layout_action_name,
 | 
				
			||||||
 | 
					                               GTK_UI_MANAGER_MENU, FALSE);
 | 
				
			||||||
 | 
					        g_snprintf (layout_path, sizeof (layout_path),
 | 
				
			||||||
 | 
					                    SET_LAYOUT_UI_PATH "/%s", layout_action_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (head = variants; head; head = head->next) {
 | 
				
			||||||
 | 
					            EekBoardAddVariantData *variant_data = head->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            g_snprintf (variant_action_name, sizeof (variant_action_name),
 | 
				
			||||||
 | 
					                        "SetVariant%s%s", item->name, variant_data->name);
 | 
				
			||||||
 | 
					            action = gtk_action_new (variant_action_name,
 | 
				
			||||||
 | 
					                                     variant_data->description,
 | 
				
			||||||
 | 
					                                     NULL,
 | 
				
			||||||
 | 
					                                     NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            data = g_slice_new (EekBoardLayoutVariant);
 | 
				
			||||||
 | 
					            data->layout = g_strdup (item->name);
 | 
				
			||||||
 | 
					            data->variant = g_strdup (variant_data->name);
 | 
				
			||||||
 | 
					            g_signal_connect (action, "activate", G_CALLBACK (on_activate),
 | 
				
			||||||
 | 
					                              data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            gtk_action_group_add_action (layout_data->action_group, action);
 | 
				
			||||||
 | 
					            g_object_unref (action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            gtk_ui_manager_add_ui (layout_data->ui_manager,
 | 
				
			||||||
 | 
					                                   layout_data->merge_id,
 | 
				
			||||||
 | 
					                                   layout_path,
 | 
				
			||||||
 | 
					                                   variant_action_name, variant_action_name,
 | 
				
			||||||
 | 
					                                   GTK_UI_MANAGER_MENUITEM, FALSE);
 | 
				
			||||||
 | 
					            g_free (variant_data->name);
 | 
				
			||||||
 | 
					            g_free (variant_data->description);
 | 
				
			||||||
 | 
					            g_slice_free (EekBoardAddVariantData, variant_data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        g_slist_free (variants);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					create_menus (GtkWidget *window, GtkUIManager * ui_manager)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkActionGroup *action_group;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    action_group = gtk_action_group_new ("MenuActions");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_action_group_add_actions (action_group, action_entry,
 | 
				
			||||||
 | 
					                                  G_N_ELEMENTS (action_entry), window);
 | 
				
			||||||
 | 
					    gtk_action_group_add_toggle_actions (action_group, toggle_action_entry,
 | 
				
			||||||
 | 
					                                         G_N_ELEMENTS (toggle_action_entry), window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
 | 
				
			||||||
 | 
					    gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekBoardAddLayoutData data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data.action_group = gtk_action_group_new ("Layouts");
 | 
				
			||||||
 | 
					    gtk_ui_manager_insert_action_group (ui_manager, data.action_group, -1);
 | 
				
			||||||
 | 
					    data.merge_id = gtk_ui_manager_new_merge_id (ui_manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    XklEngine *engine;
 | 
				
			||||||
 | 
					    XklConfigRegistry *registry;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
 | 
				
			||||||
 | 
					    registry = xkl_config_registry_get_instance (engine);
 | 
				
			||||||
 | 
					    xkl_config_registry_load (registry, FALSE);
 | 
				
			||||||
 | 
					    data.ui_manager = ui_manager;
 | 
				
			||||||
 | 
					    data.action_group = action_group;
 | 
				
			||||||
 | 
					    xkl_config_registry_foreach_layout (registry, layout_callback, &data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_resize (GObject *object,
 | 
				
			||||||
 | 
						   GParamSpec *param_spec,
 | 
				
			||||||
 | 
						   gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GValue value = {0};
 | 
				
			||||||
 | 
					  gfloat width, height, scale;
 | 
				
			||||||
 | 
					  ClutterActor *stage = CLUTTER_ACTOR(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_object_get (G_OBJECT(stage), "width", &width, NULL);
 | 
				
			||||||
 | 
					  g_object_get (G_OBJECT(stage), "height", &height, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_value_init (&value, G_TYPE_DOUBLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scale = width > height ? width / stage_width : width / stage_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_value_set_double (&value, scale);
 | 
				
			||||||
 | 
					  g_object_set_property (G_OBJECT (stage),
 | 
				
			||||||
 | 
								 "scale-x",
 | 
				
			||||||
 | 
								 &value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_value_set_double (&value, scale);
 | 
				
			||||||
 | 
					  g_object_set_property (G_OBJECT (stage),
 | 
				
			||||||
 | 
								 "scale-y",
 | 
				
			||||||
 | 
								 &value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					main (int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ClutterActor *stage;
 | 
				
			||||||
 | 
					    ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
 | 
				
			||||||
 | 
					    GOptionContext *context;
 | 
				
			||||||
 | 
					    GtkWidget *menubar, *embed, *vbox, *window;
 | 
				
			||||||
 | 
					    GtkUIManager *ui_manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context = g_option_context_new ("eekboard");
 | 
				
			||||||
 | 
					    g_option_context_add_main_entries (context, options, NULL);
 | 
				
			||||||
 | 
					    g_option_context_parse (context, &argc, &argv, NULL);
 | 
				
			||||||
 | 
					    g_option_context_free (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clutter_init (&argc, &argv);
 | 
				
			||||||
 | 
					    gtk_init (&argc, &argv);
 | 
				
			||||||
 | 
					    display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 | 
				
			||||||
 | 
					    if (!display) {
 | 
				
			||||||
 | 
					        fprintf (stderr, "Can't open display\n");
 | 
				
			||||||
 | 
					        exit (1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (window_id) {
 | 
				
			||||||
 | 
					        if (strncmp (window_id, "0x", 2) == 0)
 | 
				
			||||||
 | 
					            target = strtol (window_id[2], NULL, 16);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            target = strtol (window_id, NULL, 10);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        int revert_to;
 | 
				
			||||||
 | 
					        XGetInputFocus (display, &target, &revert_to);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fakekey = fakekey_init (display);
 | 
				
			||||||
 | 
					    if (!fakekey) {
 | 
				
			||||||
 | 
					        fprintf (stderr, "Can't init fakekey\n");
 | 
				
			||||||
 | 
					        exit (1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 | 
				
			||||||
 | 
					    gtk_widget_set_can_focus (window, FALSE);
 | 
				
			||||||
 | 
					    g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL);
 | 
				
			||||||
 | 
					    gtk_window_set_title (GTK_WINDOW(window), "Keyboard");
 | 
				
			||||||
 | 
					    g_signal_connect (G_OBJECT (window), "destroy",
 | 
				
			||||||
 | 
					                      G_CALLBACK (gtk_main_quit), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vbox = gtk_vbox_new (FALSE, 0);
 | 
				
			||||||
 | 
					    ui_manager = gtk_ui_manager_new ();
 | 
				
			||||||
 | 
					    create_menus (window, ui_manager);
 | 
				
			||||||
 | 
					    menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
 | 
				
			||||||
 | 
					    gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    embed = gtk_clutter_embed_new ();
 | 
				
			||||||
 | 
					    gtk_widget_set_can_focus (embed, TRUE);
 | 
				
			||||||
 | 
					    gtk_container_add (GTK_CONTAINER(vbox), embed);
 | 
				
			||||||
 | 
					    gtk_container_add (GTK_CONTAINER(window), vbox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(embed));
 | 
				
			||||||
 | 
					    clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
 | 
				
			||||||
 | 
					    clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    layout = eek_xkl_layout_new ();
 | 
				
			||||||
 | 
					    if (!layout) {
 | 
				
			||||||
 | 
					        fprintf (stderr, "Failed to create layout\n");
 | 
				
			||||||
 | 
					        exit (1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keyboard = create_keyboard (stage, layout, CSW, CSH);
 | 
				
			||||||
 | 
					    if (!keyboard) {
 | 
				
			||||||
 | 
					        g_object_unref (layout);
 | 
				
			||||||
 | 
					        fprintf (stderr, "Failed to create keyboard\n");
 | 
				
			||||||
 | 
					        exit (1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    clutter_actor_get_size (stage, &stage_width, &stage_height);
 | 
				
			||||||
 | 
					    clutter_actor_show_all (stage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_signal_connect (layout, "changed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_changed), stage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_signal_connect (stage, 
 | 
				
			||||||
 | 
					                      "notify::width",
 | 
				
			||||||
 | 
					                      G_CALLBACK (on_resize),
 | 
				
			||||||
 | 
					                      NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_signal_connect (stage,
 | 
				
			||||||
 | 
					                      "notify::height",
 | 
				
			||||||
 | 
					                      G_CALLBACK (on_resize),
 | 
				
			||||||
 | 
					                      NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_widget_set_size_request (embed, stage_width, stage_height);
 | 
				
			||||||
 | 
					    gtk_widget_show_all (window);
 | 
				
			||||||
 | 
					    gtk_widget_set_size_request (embed, -1, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_main ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user