Compare commits

..

27 Commits

Author SHA1 Message Date
cf4d1109d3 Update to 0.0.7. 2010-12-06 14:44:01 +09:00
c7c6d06907 eekboard: Reset modifiers just after normal key press. 2010-12-06 14:42:14 +09:00
384d43bb80 libeek: Fix gtk keyboard rendering. 2010-12-06 13:06:11 +09:00
29c55b6ca3 Suppress compiler warnings. 2010-12-06 12:12:52 +09:00
910b0be5a5 eekboard: listen xklavier status events. 2010-12-06 12:09:17 +09:00
706fa6310b Define AM_SILENT_RULES. 2010-12-06 11:33:32 +09:00
248699d771 eekboard: change the default behavior to "standalone" mode. 2010-12-06 11:19:47 +09:00
6343e37bc1 eekboard: reduce the number of allocs when parsing a config file. 2010-12-06 11:18:18 +09:00
f562e8c212 0.0.6 released. 2010-11-15 14:37:57 +09:00
8ff00226e2 Correct GTK API version in *.pc.in. 2010-11-15 14:35:03 +09:00
c72c75083c Fix typo. 2010-11-15 12:49:12 +09:00
862a54eac3 Fix build against libnotify >= 0.7.0. 2010-11-15 12:49:01 +09:00
12bc18e1ba Add compatibility code for GTK2. 2010-11-15 12:01:17 +09:00
f045bd0d50 Add --with-gtk configure option. 2010-11-15 11:46:12 +09:00
dfe06468ed Fix build against 2.91.5. 2010-11-12 15:12:56 +09:00
3fda8da1a5 libeek: forward decl structs to let g-ir-scanner inspect their fields. 2010-10-13 16:58:31 +09:00
d0a5715f8c libeek: Add setter for position/size of EekElement. 2010-10-13 16:21:12 +09:00
6b83bb8503 Clean up action groups on quit. 2010-10-13 15:04:41 +09:00
69f1dba96a Require clutter-gtk-1.0. 2010-09-08 10:13:33 +09:00
dcbdd7ff63 eekboard: fix AltGr handling. 2010-08-25 18:46:02 +09:00
9b28a011e7 Ignore generated files. 2010-08-23 14:50:00 +09:00
350598dc55 eekboard: handle AltGr 2010-08-20 18:39:06 +09:00
ae9df021c2 libeek: eek_keyboard_find_key_by_position(): consider overlapped sections. 2010-08-13 11:43:10 +09:00
d7cb78ecf5 libeek: suppress debug message if DEBUG is not set. 2010-08-13 10:44:08 +09:00
ef2e9acf1e Update TODO. 2010-08-13 10:43:17 +09:00
7f52069e41 libeek: terminate args of eek_xkb_layout_set_names_full() with NULL instead of -1. 2010-08-13 08:11:40 +09:00
9a5c0d9cdc libeek: more distcheck fixes. 2010-08-13 08:10:47 +09:00
18 changed files with 603 additions and 337 deletions

4
.gitignore vendored
View File

@ -34,6 +34,8 @@ eek/eek-special-keysym-labels.h
eek/eek-unicode-keysym-labels.h eek/eek-unicode-keysym-labels.h
eek/eek-keyname-keysym-labels.h eek/eek-keyname-keysym-labels.h
eek/*.pc eek/*.pc
eek/*.gir
eek/*.typelib
tests/eek-simple-test tests/eek-simple-test
tests/eek-xkb-test tests/eek-xkb-test
src/eekboard src/eekboard
@ -51,4 +53,4 @@ po/*.gmo
po/Makefile.in.in po/Makefile.in.in
po/POTFILES po/POTFILES
po/stamp-it po/stamp-it
bindings/vala/*.vapi

5
TODO
View File

@ -3,13 +3,10 @@
-- add more tests -- add more tests
- eekboard - eekboard
-- a11y
-- display current configuration
-- notify user if there is no focused window
-- startup in the tray
-- rewrite in Vala -- rewrite in Vala
- libeek - libeek
-- CSS based themes
-- Caribou layout engine (XML) -- Caribou layout engine (XML)
-- matchbox-keyboard layout engine (XML) -- matchbox-keyboard layout engine (XML)
-- delay initialization of XKB and XKL layouts -- delay initialization of XKB and XKL layouts

View File

@ -19,6 +19,7 @@ which gnome-autogen.sh || {
} }
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
REQUIRED_AUTOMAKE_VERSION=1.8 REQUIRED_AUTOMAKE_VERSION=1.10
REQUIRED_AUTOCONF_VERSION=2.60
. gnome-autogen.sh . gnome-autogen.sh

View File

@ -16,15 +16,60 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
AC_INIT([eekboard], [0.0.5], [ueno@unixuser.org]) AC_INIT([eekboard], [0.0.7], [ueno@unixuser.org])
AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_SRCDIR([configure.ac])
AC_PREREQ(2.63) AC_PREREQ(2.63)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
LT_INIT LT_INIT
IT_PROG_INTLTOOL([0.35.0]) IT_PROG_INTLTOOL([0.35.0])
AC_MSG_CHECKING([which gtk+ version to compile against])
AC_ARG_WITH([gtk],
[AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against (default: 2.0)])],
[case "$with_gtk" in
2.0|3.0) ;;
*) AC_MSG_ERROR([invalid gtk version specified]) ;;
esac],
[with_gtk=2.0])
AC_MSG_RESULT([$with_gtk])
case "$with_gtk" in
2.0) GTK_API_VERSION=2.0
GTK_REQUIRED=2.14.0
EEK_API_VERSION=0.1
EEK_API_MAJOR_VERSION=0
EEK_API_MINOR_VERSION=1
EEK_API_PC_VERSION=0.1
EEK_LIBRARY_SUFFIX="-$EEK_API_VERSION"
;;
3.0) GTK_API_VERSION=3.0
GTK_REQUIRED=2.91.0
# EEK_API_VERSION=0.90
# EEK_API_MAJOR_VERSION=0
# EEK_API_MINOR_VERSION=90
# EEK_API_PC_VERSION=0.90
EEK_API_VERSION=0.1
EEK_API_MAJOR_VERSION=0
EEK_API_MINOR_VERSION=1
EEK_API_PC_VERSION=0.1
EEK_LIBRARY_SUFFIX="-$EEK_API_VERSION"
;;
esac
AC_SUBST([GTK_API_VERSION])
AC_SUBST([EEK_API_VERSION])
AC_SUBST([EEK_API_MAJOR_VERSION])
AC_SUBST([EEK_API_MINOR_VERSION])
AC_SUBST([EEK_API_PC_VERSION])
AC_SUBST([EEK_LIBRARY_SUFFIX])
AC_SUBST([EEK_LIBRARY_SUFFIX_U],[AS_TR_SH([$EEK_LIBRARY_SUFFIX])])
AM_CONDITIONAL([HAVE_GTK_2],[test "$with_gtk" = "2.0"])
AM_CONDITIONAL([HAVE_GTK_3],[test "$with_gtk" = "3.0"])
PKG_CHECK_MODULES([GLIB2], [glib-2.0], , PKG_CHECK_MODULES([GLIB2], [glib-2.0], ,
[AC_MSG_ERROR([GLib2 not found])]) [AC_MSG_ERROR([GLib2 not found])])
PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0], , PKG_CHECK_MODULES([GOBJECT2], [gobject-2.0], ,
@ -33,8 +78,10 @@ PKG_CHECK_MODULES([CAIRO], [cairo], ,
[AC_MSG_ERROR([Cairo not found])]) [AC_MSG_ERROR([Cairo not found])])
PKG_CHECK_MODULES([PANGO], [pango], , PKG_CHECK_MODULES([PANGO], [pango], ,
[AC_MSG_ERROR([Pango not found])]) [AC_MSG_ERROR([Pango not found])])
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 gdk-2.0], , PKG_CHECK_MODULES([GTK], [
[AC_MSG_ERROR([GTK2 not found])]) gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
gdk-$GTK_API_VERSION >= $GTK_REQUIRED], ,
[AC_MSG_ERROR([GTK not found])])
PKG_CHECK_MODULES([GCONF2], [gconf-2.0], , PKG_CHECK_MODULES([GCONF2], [gconf-2.0], ,
[AC_MSG_ERROR([GConf not found])]) [AC_MSG_ERROR([GConf not found])])
PKG_CHECK_MODULES([XKB], [x11], , PKG_CHECK_MODULES([XKB], [x11], ,
@ -45,9 +92,25 @@ PKG_CHECK_MODULES([LIBFAKEKEY], [libfakekey], ,
[AC_MSG_ERROR([libfakekey not found])]) [AC_MSG_ERROR([libfakekey not found])])
PKG_CHECK_MODULES([CSPI], [cspi-1.0], , PKG_CHECK_MODULES([CSPI], [cspi-1.0], ,
[AC_MSG_ERROR([AT-SPI C not found])]) [AC_MSG_ERROR([AT-SPI C not found])])
PKG_CHECK_MODULES([NOTIFY], [libnotify], , PKG_CHECK_MODULES([NOTIFY], [libnotify], ,
[AC_MSG_ERROR([libnotify not found])]) [AC_MSG_ERROR([libnotify not found])])
dnl libnotify >= 0.7.0 omitted the feature to attach notification to widget.
need_libnotify_attach_workaround=0
save_CFLAGS="$CFLAGS"
CFLAGS="$NOTIFY_CFLAGS"
save_LIBS="$LIBS"
LIBS="$NOTIFY_LIBS"
AC_TRY_LINK([#include <libnotify/notification.h>],
[notify_notification_new (NULL, NULL, NULL);], ,
[need_libnotify_attach_workaround=1])
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
AC_DEFINE_UNQUOTED([NEED_LIBNOTIFY_ATTACH_WORKAROUND],
$need_libnotify_attach_workaround,
[Define if notify_notification_new work around is needed])
AC_MSG_CHECKING([whether you enable Vala language support]) AC_MSG_CHECKING([whether you enable Vala language support])
AC_ARG_ENABLE(vala, AC_ARG_ENABLE(vala,
AS_HELP_STRING([--enable-vala=no/yes], AS_HELP_STRING([--enable-vala=no/yes],
@ -75,21 +138,20 @@ if test x$enable_clutter = xyes; then
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], , PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
[AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])]) [AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])])
AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found]) AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found])
need_swap_event_workaround=no have_clutter_gtk=0
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90],, need_swap_event_workaround=0
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-1.0], [have_clutter_gtk=1],
[PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10 clutter-x11-1.0], [PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10 clutter-x11-1.0],
[need_swap_event_workaround=yes])]) [have_clutter_gtk=1; need_swap_event_workaround=1])])
AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found]) AC_DEFINE_UNQUOTED([HAVE_CLUTTER_GTK], $have_clutter_gtk,
AC_DEFINE([NEED_SWAP_EVENT_WORKAROUND], [1], [Define if Clutter-Gtk is found])
AC_DEFINE_UNQUOTED([NEED_SWAP_EVENT_WORKAROUND], $need_swap_event_workaround,
[Define if GLX_INTEL_swap_event work around is needed]) [Define if GLX_INTEL_swap_event work around is needed])
fi fi
AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes]) AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
EEK_API_VERSION=0.1
AC_SUBST(EEK_API_VERSION)
dnl to re-generate eek/*-keysym-labels.txt dnl to re-generate eek/*-keysym-labels.txt
AC_CHECK_PROGS([PYTHON], [python]) AC_CHECK_PROGS([PYTHON], [python])

View File

@ -76,48 +76,48 @@ libeek_gtk_la_SOURCES = \
$(srcdir)/eek-drawing.c \ $(srcdir)/eek-drawing.c \
$(srcdir)/eek-gtk.h $(srcdir)/eek-gtk.h
libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS) $(CAIRO_LIBS) $(PANGO_LIBS) libeek_gtk_la_CFLAGS = $(GTK_CFLAGS) $(CAIRO_LIBS) $(PANGO_LIBS)
libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) libeek_gtk_la_LIBADD = libeek.la $(GTK_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS)
libeek_xkb_la_SOURCES = \ libeek_xkb_la_SOURCES = \
$(srcdir)/eek-xkb-layout.h \ $(srcdir)/eek-xkb-layout.h \
$(srcdir)/eek-xkb-layout.c $(srcdir)/eek-xkb-layout.c
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS) libeek_xkb_la_CFLAGS = $(XKB_CFLAGS) $(GTK_CFLAGS)
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS) libeek_xkb_la_LIBADD = libeek.la $(XKB_LIBS) $(GTK_LIBS)
libeek_xkl_la_SOURCES = \ libeek_xkl_la_SOURCES = \
$(srcdir)/eek-xkl-layout.h \ $(srcdir)/eek-xkl-layout.h \
$(srcdir)/eek-xkl-layout.c $(srcdir)/eek-xkl-layout.c
libeek_xkl_la_CFLAGS = $(GTK2_CFLAGS) $(LIBXKLAVIER_CFLAGS) libeek_xkl_la_CFLAGS = $(LIBXKLAVIER_CFLAGS) $(GTK_CFLAGS)
libeek_xkl_la_LIBADD = libeek-xkb.la $(GTK2_LIBS) $(LIBXKLAVIER_LIBS) libeek_xkl_la_LIBADD = libeek-xkb.la $(LIBXKLAVIER_LIBS) $(GTK_LIBS)
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
eek_HEADERS = \ eek_HEADERS = \
$(top_srcdir)/eek/eek-element.h \ $(srcdir)/eek-element.h \
$(top_srcdir)/eek/eek-container.h \ $(srcdir)/eek-container.h \
$(top_srcdir)/eek/eek-keyboard.h \ $(srcdir)/eek-keyboard.h \
$(top_srcdir)/eek/eek-section.h \ $(srcdir)/eek-section.h \
$(top_srcdir)/eek/eek-key.h \ $(srcdir)/eek-key.h \
$(top_srcdir)/eek/eek-layout.h \ $(srcdir)/eek-layout.h \
$(top_srcdir)/eek/eek-keysym.h \ $(srcdir)/eek-keysym.h \
$(top_srcdir)/eek/eek-types.h \ $(srcdir)/eek-types.h \
$(top_srcdir)/eek/eek-gtk-keyboard.h \ $(srcdir)/eek-gtk-keyboard.h \
$(top_srcdir)/eek/eek-xkb-layout.h \ $(srcdir)/eek-xkb-layout.h \
$(top_srcdir)/eek/eek-xkl-layout.h \ $(srcdir)/eek-xkl-layout.h \
$(top_srcdir)/eek/eek.h \ $(srcdir)/eek.h \
$(top_srcdir)/eek/eek-gtk.h \ $(srcdir)/eek-gtk.h \
$(top_srcdir)/eek/eek-xkb.h \ $(srcdir)/eek-xkb.h \
$(top_srcdir)/eek/eek-xkl.h $(srcdir)/eek-xkl.h
if HAVE_CLUTTER if HAVE_CLUTTER
eek_HEADERS += \ eek_HEADERS += \
$(top_srcdir)/eek/eek-clutter-keyboard.h \ $(srcdir)/eek-clutter-keyboard.h \
$(top_srcdir)/eek/eek-clutter-section.h \ $(srcdir)/eek-clutter-section.h \
$(top_srcdir)/eek/eek-clutter-key.h \ $(srcdir)/eek-clutter-key.h \
$(top_srcdir)/eek/eek-clutter-drawing-context.h \ $(srcdir)/eek-clutter-drawing-context.h \
$(top_srcdir)/eek/eek-clutter.h $(srcdir)/eek-clutter.h
endif endif
eek-keysym.c: eek-special-keysym-labels.h eek-unicode-keysym-labels.h eek-keyname-keysym-labels.h eek-keysym.c: eek-special-keysym-labels.h eek-unicode-keysym-labels.h eek-keyname-keysym-labels.h
@ -153,53 +153,53 @@ CLEANFILES =
-include $(INTROSPECTION_MAKEFILE) -include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS = INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) INTROSPECTION_SCANNER_ARGS = --add-include-path=$(builddir)
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
if HAVE_INTROSPECTION if HAVE_INTROSPECTION
Eek-0.1.gir: libeek.la Eek@EEK_LIBRARY_SUFFIX@.gir: libeek.la
Eek_0_1_gir_SCANNERFLAGS = --strip-prefix=Eek --pkg=glib-2.0 Eek@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = --strip-prefix=Eek --pkg=glib-2.0
Eek_0_1_gir_INCLUDES = GLib-2.0 GObject-2.0 Eek@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GLib-2.0 GObject-2.0
Eek_0_1_gir_CFLAGS = $(libeek_la_CFLAGS) Eek@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_la_CFLAGS)
Eek_0_1_gir_LIBS = libeek.la Eek@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek.la
Eek_0_1_gir_FILES = $(libeek_la_SOURCES) Eek@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_la_SOURCES)
EekGtk-0.1.gir: libeek-gtk.la Eek-0.1.gir EekGtk@EEK_LIBRARY_SUFFIX@.gir: libeek-gtk.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekGtk_0_1_gir_INCLUDES = GObject-2.0 Gtk-2.0 Eek-0.1 EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Gtk-@GTK_API_VERSION@ Eek@EEK_LIBRARY_SUFFIX@
EekGtk_0_1_gir_CFLAGS = $(libeek_gtk_la_CFLAGS) EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_gtk_la_CFLAGS)
EekGtk_0_1_gir_LIBS = libeek-gtk.la EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-gtk.la
EekGtk_0_1_gir_FILES = $(libeek_gtk_la_SOURCES) EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_gtk_la_SOURCES)
if HAVE_CLUTTER if HAVE_CLUTTER
EekClutter-0.1.gir: libeek-clutter.la Eek-0.1.gir EekClutter@EEK_LIBRARY_SUFFIX@.gir: libeek-clutter.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekClutter_0_1_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek-0.1 EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek@EEK_LIBRARY_SUFFIX@
EekClutter_0_1_gir_CFLAGS = $(libeek_clutter_la_CFLAGS) EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_clutter_la_CFLAGS)
EekClutter_0_1_gir_LIBS = libeek-clutter.la EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-clutter.la
EekClutter_0_1_gir_FILES = $(libeek_clutter_la_SOURCES) EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_clutter_la_SOURCES)
endif endif
EekXkb-0.1.gir: libeek-xkb.la Eek-0.1.gir EekXkb@EEK_LIBRARY_SUFFIX@.gir: libeek-xkb.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekXkb_0_1_gir_INCLUDES = GObject-2.0 Eek-0.1 EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Eek@EEK_LIBRARY_SUFFIX@
EekXkb_0_1_gir_CFLAGS = $(libeek_xkb_la_CFLAGS) EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_xkb_la_CFLAGS)
EekXkb_0_1_gir_LIBS = libeek-xkb.la EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-xkb.la
EekXkb_0_1_gir_FILES = $(libeek_xkb_la_SOURCES) EekXkb@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_xkb_la_SOURCES)
EekXkl-0.1.gir: libeek-xkl.la EekXkb-0.1.gir EekXkl@EEK_LIBRARY_SUFFIX@.gir: libeek-xkl.la EekXkb@EEK_LIBRARY_SUFFIX@.gir
EekXkl_0_1_gir_INCLUDES = GObject-2.0 EekXkb-0.1 EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 EekXkb@EEK_LIBRARY_SUFFIX@
EekXkl_0_1_gir_CFLAGS = $(libeek_xkl_la_CFLAGS) EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_xkl_la_CFLAGS)
EekXkl_0_1_gir_LIBS = libeek-xkl.la EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-xkl.la
EekXkl_0_1_gir_FILES = $(libeek_xkl_la_SOURCES) EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_xkl_la_SOURCES)
INTROSPECTION_GIRS += \ INTROSPECTION_GIRS += \
Eek-0.1.gir \ Eek@EEK_LIBRARY_SUFFIX@.gir \
EekGtk-0.1.gir \ EekGtk@EEK_LIBRARY_SUFFIX@.gir \
EekXkb-0.1.gir \ EekXkb@EEK_LIBRARY_SUFFIX@.gir \
EekXkl-0.1.gir EekXkl@EEK_LIBRARY_SUFFIX@.gir
if HAVE_CLUTTER if HAVE_CLUTTER
INTROSPECTION_GIRS += \ INTROSPECTION_GIRS += \
EekClutter-0.1.gir EekClutter@EEK_LIBRARY_SUFFIX@.gir
endif endif
girdir = $(datadir)/gir-1.0 girdir = $(datadir)/gir-1.0

View File

@ -351,3 +351,45 @@ eek_element_get_absolute_position (EekElement *element,
*x = ax; *x = ax;
*y = ay; *y = ay;
} }
/**
* eek_element_set_position:
* @element: an #EekElement
* @x: X coordinate of top left corner
* @y: Y coordinate of top left corner
*
* Set the relative position of @element.
*/
void
eek_element_set_position (EekElement *element,
gdouble x,
gdouble y)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.x = x;
bounds.y = y;
eek_element_set_bounds (element, &bounds);
}
/**
* eek_element_set_size:
* @element: an #EekElement
* @width: width of @element
* @height: height of @element
*
* Set the size of @element.
*/
void
eek_element_set_size (EekElement *element,
gdouble width,
gdouble height)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.width = width;
bounds.height = height;
eek_element_set_bounds (element, &bounds);
}

View File

@ -81,6 +81,13 @@ void eek_element_set_bounds (EekElement *element,
void eek_element_get_bounds (EekElement *element, void eek_element_get_bounds (EekElement *element,
EekBounds *bounds); EekBounds *bounds);
void eek_element_set_position (EekElement *element,
gdouble x,
gdouble y);
void eek_element_set_size (EekElement *element,
gdouble width,
gdouble height);
void eek_element_get_absolute_position (EekElement *element, void eek_element_get_absolute_position (EekElement *element,
gdouble *x, gdouble *x,
gdouble *y); gdouble *y);

View File

@ -25,6 +25,6 @@ Name: libeek-gtk
Description: A Library to Create Keyboard-like UI (GTK Support) Description: A Library to Create Keyboard-like UI (GTK Support)
URL: http://ueno.github.com/eekboard/ URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Requires: eek-@EEK_API_VERSION@ gtk+-2.0 Requires: eek-@EEK_API_VERSION@ gtk+-@GTK_API_VERSION@
Libs: -L${libdir} -leek-gtk Libs: -L${libdir} -leek-gtk
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -41,20 +41,23 @@ G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK_TYPE_KEYBOARD);
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \ #define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
#define SCALE 1.5 enum {
KEY_SURFACE_NORMAL = 0,
KEY_SURFACE_LARGE,
KEY_SURFACE_LAST
};
static const gdouble key_surface_scale[KEY_SURFACE_LAST] = {
1.0,
1.5
};
struct _EekGtkKeyboardPrivate struct _EekGtkKeyboardPrivate
{ {
GtkWidget *widget; GtkWidget *widget;
/* pixmap of entire keyboard (for expose event) */ cairo_surface_t *keyboard_surface;
GdkPixmap *pixmap; GHashTable *key_surfaces;
/* mapping from outline pointer to pixmap */
GHashTable *outline_textures;
/* mapping from outline pointer to large pixmap */
GHashTable *large_outline_textures;
PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST]; PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST];
@ -63,7 +66,7 @@ struct _EekGtkKeyboardPrivate
EekKey *key; EekKey *key;
}; };
static void prepare_keyboard_pixmap (EekGtkKeyboard *keyboard); static void prepare_keyboard_surface (EekGtkKeyboard *keyboard);
static void static void
eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self, eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self,
@ -79,21 +82,26 @@ eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self,
EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(self); EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(self);
EekGtkKeyboardPrivate *priv = EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
GtkStyle *style;
GtkStateType state; GtkStateType state;
GtkAllocation allocation; GtkAllocation allocation;
cairo_t *cr;
if (!priv->widget || !gtk_widget_get_realized (priv->widget)) if (!priv->widget || !gtk_widget_get_realized (priv->widget))
return; return;
prepare_keyboard_pixmap (keyboard); prepare_keyboard_surface (keyboard);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); gtk_widget_get_allocation (priv->widget, &allocation);
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation);
gdk_draw_drawable (gtk_widget_get_window (priv->widget), cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget)));
gtk_widget_get_style (priv->widget)->fg_gc[state], style = gtk_widget_get_style (priv->widget);
priv->pixmap, state = gtk_widget_get_state (priv->widget);
0, 0, gdk_cairo_set_source_color (cr, &style->fg[state]);
0, 0,
allocation.width, allocation.height); cairo_set_source_surface (cr, priv->keyboard_surface, 0, 0);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_fill (cr);
cairo_destroy (cr);
} }
} }
@ -115,8 +123,8 @@ eek_gtk_keyboard_finalize (GObject *object)
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object); EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
gint i; gint i;
g_hash_table_unref (priv->outline_textures); cairo_surface_destroy (priv->keyboard_surface);
g_hash_table_unref (priv->large_outline_textures); g_hash_table_destroy (priv->key_surfaces);
for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++) for (i = 0; i < EEK_KEYSYM_CATEGORY_LAST; i++)
pango_font_description_free (priv->fonts[i]); pango_font_description_free (priv->fonts[i]);
@ -137,6 +145,17 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
gobject_class->finalize = eek_gtk_keyboard_finalize; gobject_class->finalize = eek_gtk_keyboard_finalize;
} }
static void
key_surface_free (gpointer user_data)
{
cairo_surface_t **key_surfaces = user_data;
gint i;
for (i = 0; i < KEY_SURFACE_LAST; i++)
cairo_surface_destroy (key_surfaces[i]);
g_slice_free1 (sizeof (cairo_surface_t *) * KEY_SURFACE_LAST, key_surfaces);
}
static void static void
eek_gtk_keyboard_init (EekGtkKeyboard *self) eek_gtk_keyboard_init (EekGtkKeyboard *self)
{ {
@ -144,17 +163,12 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); priv = self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
priv->widget = NULL; priv->widget = NULL;
priv->pixmap = NULL; priv->keyboard_surface = NULL;
priv->outline_textures = priv->key_surfaces =
g_hash_table_new_full (g_direct_hash, g_hash_table_new_full (g_direct_hash,
g_direct_equal, g_direct_equal,
NULL, NULL,
g_object_unref); key_surface_free);
priv->large_outline_textures =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_object_unref);
memset (priv->fonts, 0, sizeof priv->fonts); memset (priv->fonts, 0, sizeof priv->fonts);
priv->scale = 1.0; priv->scale = 1.0;
priv->key = NULL; priv->key = NULL;
@ -192,7 +206,7 @@ prepare_keyboard_pixmap_key_callback (EekElement *element,
EekKey *key = EEK_KEY(element); EekKey *key = EEK_KEY(element);
EekBounds bounds; EekBounds bounds;
EekOutline *outline; EekOutline *outline;
GdkPixmap *texture; cairo_surface_t **key_surfaces;
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
@ -202,26 +216,34 @@ prepare_keyboard_pixmap_key_callback (EekElement *element,
context->keyboard); context->keyboard);
outline = eek_key_get_outline (key); outline = eek_key_get_outline (key);
texture = g_hash_table_lookup (priv->outline_textures, outline); key_surfaces = g_hash_table_lookup (priv->key_surfaces, outline);
if (!texture) { if (!key_surfaces) {
cairo_t *cr; cairo_t *cr;
gint i;
texture = key_surfaces = g_slice_alloc (sizeof (cairo_surface_t *) *
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)), KEY_SURFACE_LAST);
bounds.width, bounds.height, -1); for (i = 0; i < KEY_SURFACE_LAST; i++) {
cr = gdk_cairo_create (GDK_DRAWABLE (texture)); gdouble scale = key_surface_scale[i];
key_surfaces[i] = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
bounds.width * scale,
bounds.height * scale);
cr = cairo_create (key_surfaces[i]);
cairo_scale (cr, priv->scale * scale, priv->scale * scale);
gdk_cairo_set_source_color (cr, context->bg); gdk_cairo_set_source_color (cr, context->bg);
cairo_rectangle (cr, 0, 0, bounds.width, bounds.height); cairo_rectangle (cr, 0, 0, bounds.width, bounds.height);
gdk_cairo_set_source_color (cr, context->fg); gdk_cairo_set_source_color (cr, context->fg);
eek_draw_outline (cr, outline); eek_draw_outline (cr, outline);
cairo_destroy (cr); cairo_destroy (cr);
g_hash_table_insert (priv->outline_textures, outline, texture); }
g_hash_table_insert (priv->key_surfaces, outline, key_surfaces);
} }
cairo_save (context->cr); cairo_save (context->cr);
cairo_translate (context->cr, bounds.x, bounds.y);
gdk_cairo_set_source_pixmap (context->cr, texture, 0, 0); cairo_translate (context->cr, bounds.x, bounds.y);
cairo_set_source_surface (context->cr, key_surfaces[0], 0, 0);
cairo_rectangle (context->cr, 0, 0, bounds.width, bounds.height); cairo_rectangle (context->cr, 0, 0, bounds.width, bounds.height);
cairo_fill (context->cr); cairo_fill (context->cr);
@ -254,48 +276,119 @@ prepare_keyboard_pixmap_section_callback (EekElement *element,
} }
static void static void
drawing_context_init (DrawingContext *context, EekGtkKeyboard *keyboard) drawing_context_init (DrawingContext *context,
cairo_t *cr,
EekGtkKeyboard *keyboard)
{ {
EekGtkKeyboardPrivate *priv = keyboard->priv; EekGtkKeyboardPrivate *priv = keyboard->priv;
GtkStyle *style;
GtkStateType state; GtkStateType state;
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); context->cr = cr;
context->keyboard = keyboard; context->keyboard = keyboard;
context->fg = &gtk_widget_get_style (GTK_WIDGET (priv->widget))->fg[state];
context->bg = &gtk_widget_get_style (GTK_WIDGET (priv->widget))->bg[state]; style = gtk_widget_get_style (priv->widget);
state = gtk_widget_get_state (priv->widget);
context->fg = &style->fg[state];
context->bg = &style->bg[state];
} }
static void static void
prepare_keyboard_pixmap (EekGtkKeyboard *keyboard) prepare_keyboard_surface (EekGtkKeyboard *keyboard)
{ {
EekGtkKeyboardPrivate *priv = keyboard->priv; EekGtkKeyboardPrivate *priv = keyboard->priv;
GtkAllocation allocation; GtkAllocation allocation;
GtkStyle *style;
GtkStateType state; GtkStateType state;
DrawingContext context; DrawingContext context;
cairo_t *cr;
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation); gtk_widget_get_allocation (priv->widget, &allocation);
priv->pixmap = priv->keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)), allocation.width,
allocation.width, allocation.height, -1); allocation.height);
/* blank background */ /* blank background */
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); cr = cairo_create (priv->keyboard_surface);
gdk_draw_rectangle cairo_scale (cr, priv->scale, priv->scale);
(priv->pixmap,
gtk_widget_get_style (GTK_WIDGET(priv->widget))->base_gc[state], style = gtk_widget_get_style (priv->widget);
TRUE, state = gtk_widget_get_state (priv->widget);
0, 0, allocation.width, allocation.height); gdk_cairo_set_source_color (cr, &style->base[state]);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_fill (cr);
/* draw sections on the canvas */ /* draw sections on the canvas */
drawing_context_init (&context, keyboard); drawing_context_init (&context, cr, keyboard);
context.cr = gdk_cairo_create (GDK_DRAWABLE (priv->pixmap));
cairo_scale (context.cr, priv->scale, priv->scale);
eek_container_foreach_child (EEK_CONTAINER(keyboard), eek_container_foreach_child (EEK_CONTAINER(keyboard),
prepare_keyboard_pixmap_section_callback, prepare_keyboard_pixmap_section_callback,
&context); &context);
cairo_destroy (context.cr); cairo_destroy (cr);
} }
static void
redraw_keyboard (cairo_t *cr,
EekGtkKeyboard *keyboard,
gint x,
gint y,
gint width,
gint height)
{
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
GtkStyle *style;
GtkStateType state;
style = gtk_widget_get_style (priv->widget);
state = gtk_widget_get_state (priv->widget);
if (!priv->keyboard_surface) {
PangoFontDescription *base_font;
PangoContext *context;
PangoLayout *layout;
/* compute font sizes which fit in each key shape */
context = gtk_widget_get_pango_context (priv->widget);
layout = pango_layout_new (context);
base_font = style->font_desc;
pango_layout_set_font_description (layout, base_font);
eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts);
g_object_unref (layout);
prepare_keyboard_surface (keyboard);
}
g_return_if_fail (priv->keyboard_surface);
gdk_cairo_set_source_color (cr, &style->fg[state]);
cairo_set_source_surface (cr,
priv->keyboard_surface,
x, y);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);
}
#if GTK_CHECK_VERSION (2, 91, 2)
static gboolean
on_draw (GtkWidget *widget,
cairo_t *cr,
gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
GtkAllocation allocation;
g_return_val_if_fail (widget == priv->widget, FALSE);
gtk_widget_get_allocation (priv->widget, &allocation);
redraw_keyboard (cr, keyboard, 0, 0, allocation.width, allocation.height);
return TRUE;
}
#else
static gboolean static gboolean
on_expose_event (GtkWidget *widget, on_expose_event (GtkWidget *widget,
GdkEventExpose *event, GdkEventExpose *event,
@ -304,122 +397,79 @@ on_expose_event (GtkWidget *widget,
EekGtkKeyboard *keyboard = user_data; EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv = EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
GtkStateType state = gtk_widget_get_state (widget); cairo_t *cr;
if (!priv->pixmap) { g_return_val_if_fail (widget == priv->widget, FALSE);
/* compute font sizes which fit in each key shape */
PangoFontDescription *base_font;
PangoContext *context;
PangoLayout *layout;
context = gtk_widget_get_pango_context (priv->widget); cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget)));
layout = pango_layout_new (context); redraw_keyboard (cr, keyboard,
base_font = gtk_widget_get_style (priv->widget)->font_desc;
pango_layout_set_font_description (layout, base_font);
eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts);
g_object_unref (layout);
prepare_keyboard_pixmap (keyboard);
}
g_return_val_if_fail (priv->pixmap, FALSE);
gdk_draw_drawable (gtk_widget_get_window (widget),
gtk_widget_get_style (widget)->fg_gc[state],
priv->pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y, event->area.x, event->area.y,
event->area.width, event->area.height); event->area.width, event->area.height);
cairo_destroy (cr);
return TRUE; return TRUE;
} }
#endif
static void static void
key_enlarge (EekGtkKeyboard *keyboard, EekKey *key) redraw_key (cairo_t *cr,
EekKey *key,
gint key_surface_type,
EekGtkKeyboard *keyboard)
{ {
EekGtkKeyboardPrivate *priv = EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds; EekBounds bounds;
EekOutline *outline; EekOutline *outline;
gdouble ax, ay; gdouble x, y;
GdkPixmap *pixmap, *texture; int width, height;
DrawingContext context; GtkStyle *style;
GtkStateType state; GtkStateType state;
cairo_t *cr; cairo_surface_t **key_surfaces, *large_surface;
drawing_context_init (&context, keyboard); g_return_if_fail (priv->keyboard_surface);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
eek_element_get_absolute_position (EEK_ELEMENT(key), &ax, &ay);
outline = eek_key_get_outline (key); outline = eek_key_get_outline (key);
texture = g_hash_table_lookup (priv->large_outline_textures, outline); key_surfaces = g_hash_table_lookup (priv->key_surfaces, outline);
if (!texture) { g_return_if_fail (key_surfaces);
texture =
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)),
bounds.width * SCALE, bounds.height * SCALE, -1);
cr = gdk_cairo_create (GDK_DRAWABLE (texture));
cairo_scale (cr, SCALE, SCALE);
gdk_cairo_set_source_color (cr, context.bg);
cairo_rectangle (cr, 0, 0, bounds.width, bounds.height);
gdk_cairo_set_source_color (cr, context.fg);
eek_draw_outline (cr, outline);
cairo_destroy (cr);
g_hash_table_insert (priv->large_outline_textures, outline, texture);
}
pixmap = large_surface = key_surfaces[KEY_SURFACE_LARGE];
gdk_pixmap_new (gtk_widget_get_window (GTK_WIDGET (priv->widget)), width = cairo_image_surface_get_width (large_surface);
bounds.width * SCALE * priv->scale, height = cairo_image_surface_get_height (large_surface);
bounds.height * SCALE * priv->scale, -1);
cr = gdk_cairo_create (GDK_DRAWABLE (pixmap)); eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
eek_element_get_absolute_position (EEK_ELEMENT(key), &x, &y);
x -= (width - bounds.width) / 2;
y -= (height - bounds.height) / 2;
style = gtk_widget_get_style (priv->widget);
state = gtk_widget_get_state (priv->widget);
gdk_cairo_set_source_color (cr, &style->fg[state]);
switch (key_surface_type) {
case KEY_SURFACE_NORMAL:
cairo_set_source_surface (cr, priv->keyboard_surface, 0, 0);
cairo_scale (cr, priv->scale, priv->scale); cairo_scale (cr, priv->scale, priv->scale);
gdk_cairo_set_source_pixmap (cr, texture, 0, 0); cairo_rectangle (cr, x, y, width, height);
cairo_rectangle (cr, 0, 0, bounds.width * SCALE, bounds.height * SCALE); cairo_fill (cr);
break;
case KEY_SURFACE_LARGE:
cairo_scale (cr, priv->scale, priv->scale);
cairo_set_source_surface (cr, large_surface, x, y);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr); cairo_fill (cr);
cairo_move_to (cr, 0, 0); cairo_move_to (cr, x, y);
cairo_scale (cr, SCALE, SCALE); gdk_cairo_set_source_color (cr, &style->fg[state]);
gdk_cairo_set_source_color (cr, context.fg);
cairo_scale (cr,
priv->scale * key_surface_scale[KEY_SURFACE_LARGE],
priv->scale * key_surface_scale[KEY_SURFACE_LARGE]);
eek_draw_key_label (cr, key, priv->fonts); eek_draw_key_label (cr, key, priv->fonts);
cairo_destroy (cr); break;
}
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
gdk_draw_drawable (gtk_widget_get_window (priv->widget),
gtk_widget_get_style (priv->widget)->fg_gc[state],
pixmap,
0, 0,
(ax - (bounds.width * SCALE - bounds.width) / 2) *
priv->scale,
(ay - (bounds.height * SCALE - bounds.height) / 2) *
priv->scale,
bounds.width * SCALE * priv->scale,
bounds.height * SCALE * priv->scale);
g_object_unref (pixmap);
}
static void
key_shrink (EekGtkKeyboard *keyboard, EekKey *key)
{
EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds;
gdouble ax, ay;
GtkStateType state;
g_return_if_fail (priv->pixmap);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
eek_element_get_absolute_position (EEK_ELEMENT(key), &ax, &ay);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
ax -= (bounds.width * SCALE - bounds.width) / 2;
ay -= (bounds.height * SCALE - bounds.height) / 2;
gdk_draw_drawable (gtk_widget_get_window (priv->widget),
gtk_widget_get_style (priv->widget)->fg_gc[state],
priv->pixmap,
ax * priv->scale, ay * priv->scale,
ax * priv->scale, ay * priv->scale,
bounds.width * SCALE * priv->scale,
bounds.height * SCALE * priv->scale);
} }
static void static void
@ -427,8 +477,12 @@ on_key_pressed (EekKey *key, gpointer user_data)
{ {
EekGtkKeyboard *keyboard = user_data; EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
cairo_t *cr;
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget)));
redraw_key (cr, key, KEY_SURFACE_LARGE, keyboard);
cairo_destroy (cr);
key_enlarge (EEK_GTK_KEYBOARD(keyboard), key);
priv->key = key; priv->key = key;
} }
@ -437,12 +491,17 @@ on_key_released (EekKey *key, gpointer user_data)
{ {
EekGtkKeyboard *keyboard = user_data; EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
cairo_t *cr;
if (priv->key) { if (priv->key) {
key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(priv->key)); cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget)));
redraw_key (cr, priv->key, KEY_SURFACE_NORMAL, keyboard);
cairo_destroy (cr);
priv->key = NULL; priv->key = NULL;
} }
key_shrink (EEK_GTK_KEYBOARD(keyboard), key); cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (priv->widget)));
redraw_key (cr, key, KEY_SURFACE_NORMAL, keyboard);
cairo_destroy (cr);
} }
static void static void
@ -522,13 +581,12 @@ on_size_allocate (GtkWidget *widget,
EekGtkKeyboardPrivate *priv = EekGtkKeyboardPrivate *priv =
EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds; EekBounds bounds;
GdkPixmap *pixmap;
if (priv->pixmap) { if (priv->keyboard_surface) {
pixmap = priv->pixmap; cairo_surface_destroy (priv->keyboard_surface);
priv->pixmap = NULL; priv->keyboard_surface = NULL;
g_object_unref (pixmap);
} }
g_hash_table_remove_all (priv->key_surfaces);
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
priv->scale = allocation->width > allocation->height ? priv->scale = allocation->width > allocation->height ?
@ -553,8 +611,13 @@ eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard)
GDK_KEY_RELEASE_MASK | GDK_KEY_RELEASE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK); GDK_BUTTON_RELEASE_MASK);
#if GTK_CHECK_VERSION (2, 91, 2)
g_signal_connect (priv->widget, "draw",
G_CALLBACK (on_draw), keyboard);
#else
g_signal_connect (priv->widget, "expose_event", g_signal_connect (priv->widget, "expose_event",
G_CALLBACK (on_expose_event), keyboard); G_CALLBACK (on_expose_event), keyboard);
#endif
g_signal_connect (priv->widget, "size-allocate", g_signal_connect (priv->widget, "size-allocate",
G_CALLBACK (on_size_allocate), keyboard); G_CALLBACK (on_size_allocate), keyboard);
g_signal_connect (priv->widget, "key-press-event", g_signal_connect (priv->widget, "key-press-event",

View File

@ -20,6 +20,7 @@
#ifndef EEK_GTK_KEYBOARD_H #ifndef EEK_GTK_KEYBOARD_H
#define EEK_GTK_KEYBOARD_H 1 #define EEK_GTK_KEYBOARD_H 1
#include <glib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "eek-keyboard.h" #include "eek-keyboard.h"

View File

@ -226,13 +226,17 @@ eek_key_real_get_keysym_index (EekKey *self,
static void static void
eek_key_real_pressed (EekKey *key) eek_key_real_pressed (EekKey *key)
{ {
#if DEBUG
g_debug ("pressed %X", eek_key_get_keycode (key)); g_debug ("pressed %X", eek_key_get_keycode (key));
#endif
} }
static void static void
eek_key_real_released (EekKey *key) eek_key_real_released (EekKey *key)
{ {
#if DEBUG
g_debug ("released %X", eek_key_get_keycode (key)); g_debug ("released %X", eek_key_get_keycode (key));
#endif
} }
static void static void

View File

@ -485,6 +485,13 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
keycode); keycode);
} }
struct _FkbpData {
gdouble x;
gdouble y;
EekKey *key;
};
typedef struct _FkbpData FkbpData;
static gint static gint
compare_section_by_position (EekElement *element, gpointer user_data) compare_section_by_position (EekElement *element, gpointer user_data)
{ {
@ -507,22 +514,22 @@ compare_section_by_position (EekElement *element, gpointer user_data)
return -1; return -1;
} }
static EekSection * static void
eek_keyboard_find_section_by_position (EekKeyboard *keyboard, fkbp_foreach_child_callback (EekElement *element,
gdouble x, gpointer user_data)
gdouble y)
{ {
EekBounds bounds; FkbpData *data = user_data;
EekPoint point; EekPoint point;
EekElement *element;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); if (!data->key) {
point.x = x - bounds.x; point.x = data->x;
point.y = y - bounds.y; point.y = data->y;
element = eek_container_find (EEK_CONTAINER(keyboard), if (compare_section_by_position (element, &point) == 0) {
compare_section_by_position, data->key = eek_section_find_key_by_position (EEK_SECTION(element),
&point); point.x,
return EEK_SECTION(element); point.y);
}
}
} }
EekKey * EekKey *
@ -530,15 +537,16 @@ eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
gdouble x, gdouble x,
gdouble y) gdouble y)
{ {
EekSection *section; FkbpData data;
EekBounds bounds; EekBounds bounds;
section = eek_keyboard_find_section_by_position (keyboard, x, y);
if (!section)
return NULL;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds); eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
x -= bounds.x; data.x = x - bounds.x;
y -= bounds.y; data.y = y - bounds.y;
return eek_section_find_key_by_position (section, x, y); data.key = NULL;
/* eek_container_find() cannot be used here since sections may overlap. */
eek_container_foreach_child (EEK_CONTAINER(keyboard),
fkbp_foreach_child_callback,
&data);
return data.key;
} }

View File

@ -24,6 +24,12 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define EEK_TYPE_KEYSYM_MATRIX (eek_keysym_matrix_get_type ())
#define EEK_TYPE_POINT (eek_point_get_type ())
#define EEK_TYPE_BOUNDS (eek_bounds_get_type ())
#define EEK_TYPE_OUTLINE (eek_outline_get_type ())
/** /**
* EekOrientation: * EekOrientation:
* @EEK_ORIENTATION_VERTICAL: the elements will be arranged vertically * @EEK_ORIENTATION_VERTICAL: the elements will be arranged vertically
@ -45,6 +51,11 @@ typedef struct _EekKey EekKey;
typedef struct _EekSection EekSection; typedef struct _EekSection EekSection;
typedef struct _EekKeyboard EekKeyboard; typedef struct _EekKeyboard EekKeyboard;
typedef struct _EekKeysymMatrix EekKeysymMatrix;
typedef struct _EekPoint EekPoint;
typedef struct _EekBounds EekBounds;
typedef struct _EekOutline EekOutline;
/** /**
* EekKeysymMatrix: * EekKeysymMatrix:
* @data: array of keysyms * @data: array of keysyms
@ -59,9 +70,7 @@ struct _EekKeysymMatrix
gint num_groups; gint num_groups;
gint num_levels; gint num_levels;
}; };
typedef struct _EekKeysymMatrix EekKeysymMatrix;
#define EEK_TYPE_KEYSYM_MATRIX (eek_keysym_matrix_get_type ())
GType eek_keysym_matrix_get_type (void) G_GNUC_CONST; GType eek_keysym_matrix_get_type (void) G_GNUC_CONST;
/** /**
@ -76,9 +85,7 @@ struct _EekPoint
gdouble x; gdouble x;
gdouble y; gdouble y;
}; };
typedef struct _EekPoint EekPoint;
#define EEK_TYPE_POINT (eek_point_get_type ())
GType eek_point_get_type (void) G_GNUC_CONST; GType eek_point_get_type (void) G_GNUC_CONST;
void eek_point_rotate (EekPoint *point, void eek_point_rotate (EekPoint *point,
gint angle); gint angle);
@ -90,18 +97,17 @@ void eek_point_rotate (EekPoint *point,
* @width: width of the box * @width: width of the box
* @height: height of the box * @height: height of the box
* *
* 2D bounding box * The rectangle containing an element's bounding box.
*/ */
struct _EekBounds struct _EekBounds
{ {
/*< public >*/
gdouble x; gdouble x;
gdouble y; gdouble y;
gdouble width; gdouble width;
gdouble height; gdouble height;
}; };
typedef struct _EekBounds EekBounds;
#define EEK_TYPE_BOUNDS (eek_bounds_get_type ())
GType eek_bounds_get_type (void) G_GNUC_CONST; GType eek_bounds_get_type (void) G_GNUC_CONST;
G_INLINE_FUNC gdouble G_INLINE_FUNC gdouble
@ -124,9 +130,7 @@ struct _EekOutline
EekPoint *points; EekPoint *points;
gint num_points; gint num_points;
}; };
typedef struct _EekOutline EekOutline;
#define EEK_TYPE_OUTLINE (eek_outline_get_type ())
GType eek_outline_get_type (void) G_GNUC_CONST; GType eek_outline_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS

View File

@ -25,6 +25,6 @@ Name: libeek-xkb
Description: A Library to Create Keyboard-like UI (XKB Support) Description: A Library to Create Keyboard-like UI (XKB Support)
URL: http://ueno.github.com/eekboard/ URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Requires: eek-@EEK_API_VERSION@ gtk+-x11-2.0 Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
Libs: -L${libdir} -leek-xkb Libs: -L${libdir} -leek-xkb
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -614,7 +614,7 @@ eek_xkb_layout_set_names (EekXkbLayout *layout, XkbComponentNamesRec *names)
/** /**
* eek_xkb_layout_set_names_full: * eek_xkb_layout_set_names_full:
* @layout: an #EekXkbLayout * @layout: an #EekXkbLayout
* @Varargs: pairs of component name and value, terminated by -1. * @Varargs: pairs of component name and value, terminated by NULL.
* *
* Set the XKB component names to @layout. This function is merely a * Set the XKB component names to @layout. This function is merely a
* wrapper around eek_xkb_layout_set_names() to avoid passing a * wrapper around eek_xkb_layout_set_names() to avoid passing a
@ -632,9 +632,13 @@ eek_xkb_layout_set_names_full (EekXkbLayout *layout,
...) ...)
{ {
va_list var_args; va_list var_args;
gboolean retval;
va_start (var_args, layout); va_start (var_args, layout);
eek_xkb_layout_set_names_full_valist (layout, var_args); retval = eek_xkb_layout_set_names_full_valist (layout, var_args);
va_end (var_args); va_end (var_args);
return retval;
} }
/** /**
@ -656,7 +660,7 @@ eek_xkb_layout_set_names_full_valist (EekXkbLayout *layout,
memset (&names, 0, sizeof names); memset (&names, 0, sizeof names);
name = va_arg (var_args, gchar *); name = va_arg (var_args, gchar *);
while (name != (gchar *)-1) { while (name) {
value = va_arg (var_args, gchar *); value = va_arg (var_args, gchar *);
if (g_strcmp0 (name, "keymap") == 0) if (g_strcmp0 (name, "keymap") == 0)
names.keymap = (char *)value; names.keymap = (char *)value;

View File

@ -244,23 +244,6 @@ 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);
} }
/* Disabled since the current EekXklLayout implementation does not
change the server setting. */
#if 0
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);
}
#endif
static void static void
eek_xkl_layout_init (EekXklLayout *self) eek_xkl_layout_init (EekXklLayout *self)
{ {
@ -274,13 +257,6 @@ 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);
/* Disabled since the current EekXklLayout implementation does not
change the server setting. */
#if 0
g_signal_connect (priv->engine, "X-state-changed",
G_CALLBACK(on_state_changed), self);
xkl_engine_start_listen (priv->engine, XKLL_TRACK_KEYBOARD_STATE);
#endif
xkl_config_rec_get_from_server (priv->config, priv->engine); xkl_config_rec_get_from_server (priv->config, priv->engine);
set_xkb_component_names (self, priv->config); set_xkb_component_names (self, priv->config);
} }

View File

@ -151,7 +151,7 @@ static void on_options_menu (GtkAction *action,
GtkWidget *window); GtkWidget *window);
static void on_about (GtkAction *action, static void on_about (GtkAction *action,
GtkWidget *window); GtkWidget *window);
static void on_quit (GtkAction * action, static void on_quit_from_menu (GtkAction * action,
GtkWidget *window); GtkWidget *window);
static void eekboard_free (Eekboard *eekboard); static void eekboard_free (Eekboard *eekboard);
static GtkWidget *create_widget (Eekboard *eekboard, static GtkWidget *create_widget (Eekboard *eekboard,
@ -205,7 +205,7 @@ static const GtkActionEntry action_entry[] = {
{"FileMenu", NULL, N_("_File")}, {"FileMenu", NULL, N_("_File")},
{"KeyboardMenu", NULL, N_("_Keyboard")}, {"KeyboardMenu", NULL, N_("_Keyboard")},
{"HelpMenu", NULL, N_("_Help")}, {"HelpMenu", NULL, N_("_Help")},
{"Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (on_quit)}, {"Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (on_quit_from_menu)},
{"Country", NULL, N_("Country"), NULL, NULL, {"Country", NULL, N_("Country"), NULL, NULL,
G_CALLBACK(on_countries_menu)}, G_CALLBACK(on_countries_menu)},
{"Language", NULL, N_("Language"), NULL, NULL, {"Language", NULL, N_("Language"), NULL, NULL,
@ -229,7 +229,7 @@ static gboolean opt_version = FALSE;
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
static gchar *opt_toolkit = NULL; static gchar *opt_toolkit = NULL;
#endif #endif
static gboolean opt_standalone = FALSE; static gboolean opt_popup = FALSE;
static gchar *opt_config = NULL; static gchar *opt_config = NULL;
static const GOptionEntry options[] = { static const GOptionEntry options[] = {
@ -249,8 +249,8 @@ static const GOptionEntry options[] = {
{"toolkit", 't', 0, G_OPTION_ARG_STRING, &opt_toolkit, {"toolkit", 't', 0, G_OPTION_ARG_STRING, &opt_toolkit,
N_("Toolkit (\"clutter\" or \"gtk\")")}, N_("Toolkit (\"clutter\" or \"gtk\")")},
#endif #endif
{"standalone", 's', 0, G_OPTION_ARG_NONE, &opt_standalone, {"popup", 'p', 0, G_OPTION_ARG_NONE, &opt_popup,
N_("Start as a standalone application")}, N_("Start as a popup window")},
{"config", 'c', 0, G_OPTION_ARG_STRING, &opt_config, {"config", 'c', 0, G_OPTION_ARG_STRING, &opt_config,
N_("Specify configuration file")}, N_("Specify configuration file")},
{"version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, {"version", 'v', 0, G_OPTION_ARG_NONE, &opt_version,
@ -280,12 +280,25 @@ on_about (GtkAction * action, GtkWidget *window)
} }
static void static void
on_quit (GtkAction * action, GtkWidget *window) on_destroy (gpointer user_data)
{ {
Eekboard *eekboard = g_object_get_data (G_OBJECT(window), "eekboard"); gtk_main_quit ();
}
static gboolean
on_quit (gpointer user_data)
{
Eekboard *eekboard = user_data;
/* release the currently hold key */
if (eekboard->fakekey)
fakekey_release (eekboard->fakekey); fakekey_release (eekboard->fakekey);
eekboard_free (eekboard); eekboard_free (eekboard);
return TRUE;
}
static void
on_quit_from_menu (GtkAction * action, GtkWidget *window)
{
gtk_main_quit (); gtk_main_quit ();
} }
@ -358,6 +371,7 @@ a11y_keystroke_listener (const AccessibleKeystroke *stroke,
guint keysym; guint keysym;
guint ignored_keysyms[] = {XK_Shift_L, guint ignored_keysyms[] = {XK_Shift_L,
XK_Shift_R, XK_Shift_R,
XK_ISO_Level3_Shift,
XK_Control_L, XK_Control_L,
XK_Control_R, XK_Control_R,
XK_Alt_L, XK_Alt_L,
@ -403,24 +417,44 @@ on_key_pressed (EekKeyboard *keyboard,
gpointer user_data) gpointer user_data)
{ {
Eekboard *eekboard = user_data; Eekboard *eekboard = user_data;
gint group, level;
guint keysym; guint keysym;
keysym = eek_key_get_keysym (key); keysym = eek_key_get_keysym (key);
EEKBOARD_NOTE("%s %X", eek_keysym_to_string (keysym), eekboard->modifiers); EEKBOARD_NOTE("%s %X", eek_keysym_to_string (keysym), eekboard->modifiers);
if (keysym == XK_Shift_L || keysym == XK_Shift_R) { switch (keysym) {
gint group, level; case XK_Shift_L:
case XK_Shift_R:
eekboard->modifiers ^= ShiftMask; eekboard->modifiers |= ShiftMask;
eek_keyboard_get_keysym_index (keyboard, &group, &level); eek_keyboard_get_keysym_index (keyboard, &group, &level);
eek_keyboard_set_keysym_index (keyboard, group, eek_keyboard_set_keysym_index (keyboard, group,
eekboard->modifiers & ShiftMask ? 1 : 0); (eekboard->modifiers & Mod5Mask) ? 2 :
} else if (keysym == XK_Control_L || keysym == XK_Control_R) { (eekboard->modifiers & ShiftMask) ? 1 :
eekboard->modifiers ^= ControlMask; 0);
} else if (keysym == XK_Alt_L || keysym == XK_Alt_R) { break;
eekboard->modifiers ^= Mod1Mask; case XK_ISO_Level3_Shift:
} else eekboard->modifiers |= Mod5Mask;
eek_keyboard_get_keysym_index (keyboard, &group, &level);
eek_keyboard_set_keysym_index (keyboard, group,
(eekboard->modifiers & Mod5Mask) ? 2 :
(eekboard->modifiers & ShiftMask) ? 1 :
0);
break;
case XK_Control_L:
case XK_Control_R:
eekboard->modifiers |= ControlMask;
break;
case XK_Alt_L:
case XK_Alt_R:
eekboard->modifiers |= Mod1Mask;
break;
default:
fakekey_press_keysym (eekboard->fakekey, keysym, eekboard->modifiers); fakekey_press_keysym (eekboard->fakekey, keysym, eekboard->modifiers);
eekboard->modifiers = 0;
eek_keyboard_get_keysym_index (keyboard, &group, &level);
eek_keyboard_set_keysym_index (keyboard, group, 0);
}
} }
static void static void
@ -955,6 +989,7 @@ create_menus (Eekboard *eekboard,
gtk_ui_manager_insert_action_group (eekboard->ui_manager, action_group, 0); gtk_ui_manager_insert_action_group (eekboard->ui_manager, action_group, 0);
gtk_ui_manager_add_ui_from_string (eekboard->ui_manager, ui_description, -1, NULL); gtk_ui_manager_add_ui_from_string (eekboard->ui_manager, ui_description, -1, NULL);
g_object_unref (action_group);
eekboard->countries_action_group = gtk_action_group_new ("Countries"); eekboard->countries_action_group = gtk_action_group_new ("Countries");
gtk_ui_manager_insert_action_group (eekboard->ui_manager, gtk_ui_manager_insert_action_group (eekboard->ui_manager,
@ -1112,6 +1147,37 @@ parse_layouts (XklConfigRec *rec, const gchar *_layouts)
rec->variants = variants; rec->variants = variants;
} }
static GdkFilterReturn
filter_xkl_event (GdkXEvent * xev,
GdkEvent * event,
gpointer user_data)
{
XEvent *xevent = (XEvent *) xev;
Eekboard *eekboard = user_data;
xkl_engine_filter_events (eekboard->engine, xevent);
return GDK_FILTER_CONTINUE;
}
static void
on_xkl_config_changed (XklEngine *xklengine,
gpointer user_data)
{
}
static void
on_xkl_state_changed (XklEngine *xklengine,
XklEngineStateChange type,
gint value,
gboolean restore,
gpointer user_data)
{
Eekboard *eekboard = user_data;
if (type == GROUP_CHANGED)
g_signal_emit_by_name (eekboard->layout, "group_changed", value);
}
Eekboard * Eekboard *
eekboard_new (gboolean use_clutter, eekboard_new (gboolean use_clutter,
gboolean need_swap_event_workaround, gboolean need_swap_event_workaround,
@ -1169,6 +1235,18 @@ eekboard_new (gboolean use_clutter,
eekboard->engine = xkl_engine_get_instance (eekboard->display); eekboard->engine = xkl_engine_get_instance (eekboard->display);
eekboard->registry = xkl_config_registry_get_instance (eekboard->engine); eekboard->registry = xkl_config_registry_get_instance (eekboard->engine);
xkl_config_registry_load (eekboard->registry, FALSE); xkl_config_registry_load (eekboard->registry, FALSE);
g_signal_connect (eekboard->engine, "X-config-changed",
G_CALLBACK(on_xkl_config_changed), eekboard);
g_signal_connect (eekboard->engine, "X-state-changed",
G_CALLBACK(on_xkl_state_changed), eekboard);
gdk_window_add_filter (NULL,
(GdkFilterFunc)filter_xkl_event,
eekboard);
gdk_window_add_filter (gdk_get_default_root_window (),
(GdkFilterFunc) filter_xkl_event,
eekboard);
xkl_engine_start_listen (eekboard->engine, XKLL_TRACK_KEYBOARD_STATE);
return eekboard; return eekboard;
} }
@ -1186,6 +1264,20 @@ eekboard_free (Eekboard *eekboard)
g_object_unref (eekboard->registry); g_object_unref (eekboard->registry);
if (eekboard->engine) if (eekboard->engine)
g_object_unref (eekboard->engine); g_object_unref (eekboard->engine);
if (eekboard->gconfc)
g_object_unref (eekboard->gconfc);
if (eekboard->ui_manager)
g_object_unref (eekboard->ui_manager);
if (eekboard->countries_action_group)
g_object_unref (eekboard->countries_action_group);
if (eekboard->languages_action_group)
g_object_unref (eekboard->languages_action_group);
if (eekboard->models_action_group)
g_object_unref (eekboard->models_action_group);
if (eekboard->layouts_action_group)
g_object_unref (eekboard->layouts_action_group);
if (eekboard->options_action_group)
g_object_unref (eekboard->options_action_group);
g_slice_free (Eekboard, eekboard); g_slice_free (Eekboard, eekboard);
} }
@ -1318,7 +1410,7 @@ config_parser_start_element (GMarkupParseContext *pcontext,
config->rec = xkl_config_rec_new (); config->rec = xkl_config_rec_new ();
context->list = g_slist_prepend (context->list, config); context->list = g_slist_prepend (context->list, config);
} else } else
context->text = g_string_sized_new (100); context->text->len = 0;
} }
static void static void
@ -1343,8 +1435,7 @@ config_parser_end_element (GMarkupParseContext *pcontext,
if (!context->text) if (!context->text)
return; return;
text = g_string_free (context->text, FALSE); text = g_strndup (context->text->str, context->text->len);
context->text = NULL;
if (g_strcmp0 (element_name, "name") == 0) if (g_strcmp0 (element_name, "name") == 0)
config->name = text; config->name = text;
@ -1364,7 +1455,6 @@ config_parser_text (GMarkupParseContext *pcontext,
GError **error) GError **error)
{ {
ConfigContext *context = user_data; ConfigContext *context = user_data;
if (context->text)
context->text = g_string_append_len (context->text, text, text_len); context->text = g_string_append_len (context->text, text, text_len);
} }
@ -1486,7 +1576,6 @@ main (int argc, char *argv[])
GSList *head; GSList *head;
gint i; gint i;
memset (&context, 0, sizeof context);
file = g_file_new_for_path (opt_config); file = g_file_new_for_path (opt_config);
error = NULL; error = NULL;
@ -1497,6 +1586,8 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
context.list = NULL;
context.text = g_string_sized_new (BUFSIZ);
pcontext = g_markup_parse_context_new (&config_parser, pcontext = g_markup_parse_context_new (&config_parser,
0, 0,
&context, &context,
@ -1520,6 +1611,7 @@ main (int argc, char *argv[])
error = NULL; error = NULL;
g_markup_parse_context_end_parse (pcontext, &error); g_markup_parse_context_end_parse (pcontext, &error);
g_markup_parse_context_free (pcontext); g_markup_parse_context_free (pcontext);
g_string_free (context.text, TRUE);
g_object_unref (file); g_object_unref (file);
if (context.list) { if (context.list) {
@ -1531,21 +1623,21 @@ main (int argc, char *argv[])
} }
} }
window = gtk_window_new (opt_standalone ? window = gtk_window_new (opt_popup ?
GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP :
GTK_WINDOW_POPUP); GTK_WINDOW_TOPLEVEL);
gtk_widget_set_can_focus (window, FALSE); gtk_widget_set_can_focus (window, FALSE);
g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL); g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL);
gtk_window_set_title (GTK_WINDOW(window), "Keyboard"); gtk_window_set_title (GTK_WINDOW(window), "Keyboard");
g_signal_connect (G_OBJECT (window), "destroy", g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL); G_CALLBACK (on_destroy), eekboard);
vbox = gtk_vbox_new (FALSE, 0); vbox = gtk_vbox_new (FALSE, 0);
g_object_set_data (G_OBJECT(window), "eekboard", eekboard); g_object_set_data (G_OBJECT(window), "eekboard", eekboard);
widget = create_widget (eekboard, CSW, CSH); widget = create_widget (eekboard, CSW, CSH);
if (opt_standalone) { if (!opt_popup) {
create_menus (eekboard, window); create_menus (eekboard, window);
menubar = gtk_ui_manager_get_widget (eekboard->ui_manager, "/MainMenu"); menubar = gtk_ui_manager_get_widget (eekboard->ui_manager, "/MainMenu");
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
@ -1587,7 +1679,7 @@ main (int argc, char *argv[])
eekboard->window = window; eekboard->window = window;
eekboard->gconfc = gconfc; eekboard->gconfc = gconfc;
if (eekboard->accessibility_enabled) { if (eekboard->accessibility_enabled) {
if (!opt_standalone) { if (opt_popup) {
NotifyNotification *notification; NotifyNotification *notification;
error = NULL; error = NULL;
@ -1600,8 +1692,11 @@ main (int argc, char *argv[])
"eekboard is starting without a window.\n" "eekboard is starting without a window.\n"
"To make eekboard show up, click on some window with " "To make eekboard show up, click on some window with "
"an editable widget.", "an editable widget.",
"keyboard", "keyboard"
NULL); #if NEED_LIBNOTIFY_ATTACH_WORKAROUND
, NULL
#endif
);
notify_notification_add_action notify_notification_add_action
(notification, (notification,
"dont-ask", "dont-ask",
@ -1615,8 +1710,7 @@ main (int argc, char *argv[])
gtk_widget_hide (window); gtk_widget_hide (window);
focusListener = focusListener = SPI_createAccessibleEventListener ((AccessibleEventListenerCB)a11y_focus_listener,
SPI_createAccessibleEventListener (a11y_focus_listener,
eekboard); eekboard);
SPI_registerGlobalEventListener (focusListener, SPI_registerGlobalEventListener (focusListener,
"object:state-changed:focused"); "object:state-changed:focused");
@ -1646,6 +1740,7 @@ main (int argc, char *argv[])
if (combo) if (combo)
gtk_combo_box_set_active (GTK_COMBO_BOX(combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX(combo), 0);
gtk_quit_add (0, on_quit, eekboard);
gtk_main (); gtk_main ();
return 0; return 0;

View File

@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
INCLUDES = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS) INCLUDES = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(GTK_CFLAGS) $(XKB_CFLAGS)
TESTS = eek-simple-test eek-xkb-test TESTS = eek-simple-test eek-xkb-test
noinst_PROGRAMS = $(TESTS) noinst_PROGRAMS = $(TESTS)