Compare commits

..

51 Commits

Author SHA1 Message Date
551fb17e02 Fix for distcheck. 2010-08-12 17:10:34 +09:00
b5b9864033 0.0.5 released. 2010-08-12 16:54:06 +09:00
a2d2ef3a5e libeek: add eek_xkb_layout_set_names_full_valist(). 2010-08-12 12:03:21 +09:00
b09a586357 eekboard: add eekboard-sample.conf. 2010-08-12 10:19:54 +09:00
70f3bc5308 libeek: make GTK key event handling robuster. 2010-08-11 17:45:52 +09:00
8bc7b754bc eekboard: react to key events by default. 2010-08-11 17:36:33 +09:00
3d5160455a eekboard: error if config file cannot be read. 2010-08-11 16:50:10 +09:00
983cc22761 eekboard: config file support. 2010-08-11 16:45:57 +09:00
6d80e4cacb eekboard: add --toolkit and --standalone. 2010-08-11 11:49:52 +09:00
1c5a271177 eekboard: refile focus event handling. 2010-08-10 16:32:17 +09:00
e4891ccf6b eekboard: don't hide the eekboard window on a11y focus event. 2010-08-10 14:44:50 +09:00
48bfc7485f eekboard: set icon on notification. 2010-08-10 14:23:04 +09:00
2e297ab1ef Merge branch 'a11y' of github.com:ueno/eekboard into a11y 2010-08-09 12:14:30 +09:00
828fc553b4 eekboard: use libnotify to display notification. 2010-08-09 11:10:52 +09:00
08e1a6c69a Merge branch 'master' into a11y
Conflicts:
	eek/eek-gtk-keyboard.c
2010-08-05 12:38:01 +09:00
039ea44520 libeek: add eek_keyboard_find_key_by_position(). 2010-08-05 12:32:14 +09:00
65c1abbe27 eekboard: hide window by default if GNOME a11y is enabled. 2010-07-29 18:53:43 +09:00
0ab5a0f114 Implement "Monitor Key Typing" using AT-SPI C. 2010-07-22 17:34:09 +09:00
94219bd31e Ignore motion event when button is pressed. 2010-07-22 15:56:43 +09:00
7c2457e659 Remove workaround for Clutter Bug #2137. 2010-07-05 13:04:12 +09:00
a156453301 0.0.4 released. 2010-07-01 11:08:49 +09:00
c2e53ec9a9 Update translation. 2010-07-01 11:03:34 +09:00
687b2a83b4 Port GLX_INTEL_swap_event work around from Clutter-Gtk to eekboard.c. 2010-07-01 11:02:54 +09:00
a1f7d628bb Add more TODO. 2010-06-23 16:09:17 +09:00
789ee66836 Update TODO. 2010-06-23 16:06:02 +09:00
9ec42b66f3 eekboard: add command-line options 2010-06-23 16:05:52 +09:00
b2b44a0810 libeek: make temporary copies of config parameters in #set_model() etc. 2010-06-23 16:02:07 +09:00
59076afcb5 eekboard: release fakekey on quit 2010-06-23 12:14:52 +09:00
5ab24250bc libeek: check widget is realized when preparing pixmap 2010-06-23 12:14:07 +09:00
273b0653da 0.0.3 released. 2010-06-23 11:01:12 +09:00
b583cfb9f6 Fix parallel build. 2010-06-23 10:57:32 +09:00
84cdf6ec78 libeek: don't generate EekClutter-0.1.gir if --disable-clutter is given 2010-06-22 17:57:24 +09:00
4623d78e0d Cosmetic fix. 2010-06-22 17:29:55 +09:00
89cc9ffa46 0.0.2 released 2010-06-22 17:19:36 +09:00
27ddc144e0 libeek: add Since: doc-comment 2010-06-22 17:19:25 +09:00
6e54383d1d libeek: update the project URL in *.pc 2010-06-22 17:18:46 +09:00
e955bb11fa libeek: fix memory leak 2010-06-22 17:14:08 +09:00
f08c926945 eekboard: quit gracefully 2010-06-22 17:01:53 +09:00
fdb083bb12 libeek: supress compiler warning 2010-06-22 17:01:43 +09:00
e604e6af22 libeek: fix memory leak 2010-06-22 17:01:24 +09:00
9aabdc0812 Fix coding style. 2010-06-22 16:29:24 +09:00
a388d9e6e1 libeek: add wrapper functions to avoid exposing XKB/XKL structures to GIR 2010-06-22 16:14:28 +09:00
4dab7af44d Minor fix for Vala binding. 2010-06-22 14:07:44 +09:00
60a0c199eb Fix doc. 2010-06-22 13:06:42 +09:00
de7f31f067 Refine "Usage Overview". 2010-06-22 13:00:47 +09:00
ae4e29a968 Add Vala language binding. 2010-06-22 12:24:18 +09:00
f50a8a98f4 Generate gobject-introspection files. 2010-06-22 10:44:19 +09:00
b3903bcc7f libeek: draw rotated section with GTK UI 2010-06-22 10:10:24 +09:00
bc38ac837b Add a TODO entry. 2010-06-21 17:52:04 +09:00
c2c1a79046 Add more TODO entries. 2010-06-21 17:48:41 +09:00
b902e759cb eekboard: use widget allocation size for initial keyboard size 2010-06-21 17:46:44 +09:00
56 changed files with 2478 additions and 335 deletions

View File

@ -17,4 +17,6 @@
# 02110-1301 USA # 02110-1301 USA
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = eek src tests docs po SUBDIRS = eek src tests bindings docs po
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-introspection
EXTRA_DIST = eekboard-sample.conf

11
TODO
View File

@ -1,12 +1,17 @@
- packaging - packaging
-- GIR
-- .spec
-- debian -- debian
-- add more tests -- add more tests
- eekboard - eekboard
-- a11y -- a11y
-- display current configuration
-- notify user if there is no focused window
-- startup in the tray
-- rewrite in Vala
- libeek - libeek
-- matchbox-keyboard layout engine -- Caribou layout engine (XML)
-- matchbox-keyboard layout engine (XML)
-- delay initialization of XKB and XKL layouts -- delay initialization of XKB and XKL layouts
-- add mechanism to change appearances (colors?) of UI widgets
depending on modifier states

23
bindings/Makefile.am Normal file
View File

@ -0,0 +1,23 @@
# 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
if ENABLE_VALA
SUBDIRS = vala
else
SUBDIRS =
endif

50
bindings/vala/Makefile.am Normal file
View File

@ -0,0 +1,50 @@
# 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
vapidir = $(datadir)/vala/vapi
dist_vapi_DATA = \
eek-$(EEK_API_VERSION).vapi \
eek-clutter-$(EEK_API_VERSION).vapi \
eek-gtk-$(EEK_API_VERSION).vapi \
eek-xkb-$(EEK_API_VERSION).vapi \
eek-xkl-$(EEK_API_VERSION).vapi
MAINTAINERCLEANFILES = $(dist_vapi_DATA)
eek-$(EEK_API_VERSION).vapi:
vapigen --library eek-$(EEK_API_VERSION) \
eek-$(EEK_API_VERSION)/eek-$(EEK_API_VERSION).gi
eek-clutter-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-clutter-$(EEK_API_VERSION) \
--pkg eek-0.1 --pkg clutter-1.0 \
eek-clutter-$(EEK_API_VERSION)/eek-clutter-$(EEK_API_VERSION).gi
eek-gtk-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-gtk-$(EEK_API_VERSION) \
--pkg eek-0.1 --pkg gtk+-2.0 \
eek-gtk-$(EEK_API_VERSION)/eek-gtk-$(EEK_API_VERSION).gi
eek-xkb-$(EEK_API_VERSION).vapi: eek-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-xkb-$(EEK_API_VERSION) \
--pkg eek-0.1 \
eek-xkb-$(EEK_API_VERSION)/eek-xkb-$(EEK_API_VERSION).gi
eek-xkl-$(EEK_API_VERSION).vapi: eek-xkb-$(EEK_API_VERSION).vapi
vapigen --vapidir=$(builddir) --library eek-xkl-$(EEK_API_VERSION) \
--pkg eek-0.1 --pkg eek-xkb-0.1 \
eek-xkl-$(EEK_API_VERSION)/eek-xkl-$(EEK_API_VERSION).gi

View File

@ -0,0 +1,9 @@
include/eek-0.1/eek/eek-layout.h
include/eek-0.1/eek/eek-element.h
include/eek-0.1/eek/eek-container.h
include/eek-0.1/eek/eek-keyboard.h
include/eek-0.1/eek/eek-section.h
include/eek-0.1/eek/eek-key.h
include/eek-0.1/eek/eek-types.h
include/eek-0.1/eek/eek-keysym.h
lib/libeek.so

View File

@ -0,0 +1,680 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="Eek">
<function name="keysym_get_category" symbol="eek_keysym_get_category">
<return-type type="EekKeysymCategory"/>
<parameters>
<parameter name="keysym" type="guint"/>
</parameters>
</function>
<function name="keysym_to_string" symbol="eek_keysym_to_string">
<return-type type="gchar*"/>
<parameters>
<parameter name="keysym" type="guint"/>
</parameters>
</function>
<callback name="EekCallback">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</callback>
<callback name="EekCompareFunc">
<return-type type="gint"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</callback>
<boxed name="EekBounds" type-name="EekBounds" get-type="eek_bounds_get_type">
<field name="x" type="gdouble"/>
<field name="y" type="gdouble"/>
<field name="width" type="gdouble"/>
<field name="height" type="gdouble"/>
</boxed>
<boxed name="EekKeysymMatrix" type-name="EekKeysymMatrix" get-type="eek_keysym_matrix_get_type">
<field name="data" type="guint*"/>
<field name="num_groups" type="gint"/>
<field name="num_levels" type="gint"/>
</boxed>
<boxed name="EekOutline" type-name="EekOutline" get-type="eek_outline_get_type">
<field name="corner_radius" type="gdouble"/>
<field name="points" type="EekPoint*"/>
<field name="num_points" type="gint"/>
</boxed>
<boxed name="EekPoint" type-name="EekPoint" get-type="eek_point_get_type">
<field name="x" type="gdouble"/>
<field name="y" type="gdouble"/>
</boxed>
<enum name="EekKeysymCategory">
<member name="EEK_KEYSYM_CATEGORY_LETTER" value="0"/>
<member name="EEK_KEYSYM_CATEGORY_FUNCTION" value="1"/>
<member name="EEK_KEYSYM_CATEGORY_KEYNAME" value="2"/>
<member name="EEK_KEYSYM_CATEGORY_UNKNOWN" value="3"/>
<member name="EEK_KEYSYM_CATEGORY_LAST" value="3"/>
</enum>
<enum name="EekOrientation">
<member name="EEK_ORIENTATION_VERTICAL" value="0"/>
<member name="EEK_ORIENTATION_HORIZONTAL" value="1"/>
<member name="EEK_ORIENTATION_INVALID" value="-1"/>
</enum>
<object name="EekContainer" parent="EekElement" type-name="EekContainer" get-type="eek_container_get_type">
<method name="find" symbol="eek_container_find">
<return-type type="EekElement*"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="func" type="EekCompareFunc"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</method>
<method name="find_by_position" symbol="eek_container_find_by_position">
<return-type type="EekElement*"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="x" type="gdouble"/>
<parameter name="y" type="gdouble"/>
</parameters>
</method>
<method name="foreach_child" symbol="eek_container_foreach_child">
<return-type type="void"/>
<parameters>
<parameter name="container" type="EekContainer*"/>
<parameter name="callback" type="EekCallback"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</method>
<signal name="child-added" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</signal>
<signal name="child-removed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</signal>
<vfunc name="add_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="find">
<return-type type="EekElement*"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="func" type="EekCompareFunc"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</vfunc>
<vfunc name="foreach_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="callback" type="EekCallback"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
</vfunc>
<vfunc name="remove_child">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekContainer*"/>
<parameter name="element" type="EekElement*"/>
</parameters>
</vfunc>
</object>
<object name="EekElement" parent="GInitiallyUnowned" type-name="EekElement" get-type="eek_element_get_type">
<method name="get_absolute_position" symbol="eek_element_get_absolute_position">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="x" type="gdouble*"/>
<parameter name="y" type="gdouble*"/>
</parameters>
</method>
<method name="get_bounds" symbol="eek_element_get_bounds">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</method>
<method name="get_name" symbol="eek_element_get_name">
<return-type type="gchar*"/>
<parameters>
<parameter name="element" type="EekElement*"/>
</parameters>
</method>
<method name="get_parent" symbol="eek_element_get_parent">
<return-type type="EekElement*"/>
<parameters>
<parameter name="element" type="EekElement*"/>
</parameters>
</method>
<method name="set_bounds" symbol="eek_element_set_bounds">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</method>
<method name="set_name" symbol="eek_element_set_name">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="name" type="gchar*"/>
</parameters>
</method>
<method name="set_parent" symbol="eek_element_set_parent">
<return-type type="void"/>
<parameters>
<parameter name="element" type="EekElement*"/>
<parameter name="parent" type="EekElement*"/>
</parameters>
</method>
<property name="bounds" type="EekBounds*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="name" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<vfunc name="get_bounds">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</vfunc>
<vfunc name="get_name">
<return-type type="gchar*"/>
<parameters>
<parameter name="self" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="get_parent">
<return-type type="EekElement*"/>
<parameters>
<parameter name="self" type="EekElement*"/>
</parameters>
</vfunc>
<vfunc name="set_bounds">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="bounds" type="EekBounds*"/>
</parameters>
</vfunc>
<vfunc name="set_name">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="name" type="gchar*"/>
</parameters>
</vfunc>
<vfunc name="set_parent">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekElement*"/>
<parameter name="parent" type="EekElement*"/>
</parameters>
</vfunc>
</object>
<object name="EekKey" parent="EekElement" type-name="EekKey" get-type="eek_key_get_type">
<method name="get_index" symbol="eek_key_get_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="column" type="gint*"/>
<parameter name="row" type="gint*"/>
</parameters>
</method>
<method name="get_keycode" symbol="eek_key_get_keycode">
<return-type type="guint"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="get_keysym" symbol="eek_key_get_keysym">
<return-type type="guint"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="get_keysym_index" symbol="eek_key_get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</method>
<method name="get_keysyms" symbol="eek_key_get_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keysyms" type="guint**"/>
<parameter name="num_groups" type="gint*"/>
<parameter name="num_levels" type="gint*"/>
</parameters>
</method>
<method name="get_outline" symbol="eek_key_get_outline">
<return-type type="EekOutline*"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</method>
<method name="set_index" symbol="eek_key_set_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</method>
<method name="set_keycode" symbol="eek_key_set_keycode">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="set_keysym_index" symbol="eek_key_set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</method>
<method name="set_keysyms" symbol="eek_key_set_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="keysyms" type="guint*"/>
<parameter name="num_groups" type="gint"/>
<parameter name="num_levels" type="gint"/>
</parameters>
</method>
<method name="set_outline" symbol="eek_key_set_outline">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</method>
<property name="column" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="group" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keycode" type="guint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keysyms" type="EekKeysymMatrix*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="level" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="outline" type="gpointer" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="row" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</signal>
<signal name="released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="key" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="get_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="column" type="gint*"/>
<parameter name="row" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_keycode">
<return-type type="guint"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="get_keysym">
<return-type type="guint"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keysyms" type="guint**"/>
<parameter name="num_groups" type="gint*"/>
<parameter name="num_levels" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="get_outline">
<return-type type="EekOutline*"/>
<parameters>
<parameter name="self" type="EekKey*"/>
</parameters>
</vfunc>
<vfunc name="set_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_keycode">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_keysyms">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="keysyms" type="guint*"/>
<parameter name="num_groups" type="gint"/>
<parameter name="num_levels" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_outline">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKey*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</vfunc>
</object>
<object name="EekKeyboard" parent="EekContainer" type-name="EekKeyboard" get-type="eek_keyboard_get_type">
<method name="create_section" symbol="eek_keyboard_create_section">
<return-type type="EekSection*"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="find_key_by_keycode" symbol="eek_keyboard_find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="get_keysym_index" symbol="eek_keyboard_get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</method>
<method name="realize" symbol="eek_keyboard_realize">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="set_keysym_index" symbol="eek_keyboard_set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</method>
<method name="set_layout" symbol="eek_keyboard_set_layout">
<return-type type="void"/>
<parameters>
<parameter name="keyboard" type="EekKeyboard*"/>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</method>
<property name="group" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="level" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="key-pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekKeyboard*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<signal name="key-released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekKeyboard*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="create_section">
<return-type type="EekSection*"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="get_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="group" type="gint*"/>
<parameter name="level" type="gint*"/>
</parameters>
</vfunc>
<vfunc name="realize">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="set_keysym_index">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="group" type="gint"/>
<parameter name="level" type="gint"/>
</parameters>
</vfunc>
<vfunc name="set_layout">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekKeyboard*"/>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</vfunc>
</object>
<object name="EekSection" parent="EekContainer" type-name="EekSection" get-type="eek_section_get_type">
<method name="add_row" symbol="eek_section_add_row">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="num_columns" type="gint"/>
<parameter name="orientation" type="EekOrientation"/>
</parameters>
</method>
<method name="create_key" symbol="eek_section_create_key">
<return-type type="EekKey*"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</method>
<method name="find_key_by_keycode" symbol="eek_section_find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</method>
<method name="get_angle" symbol="eek_section_get_angle">
<return-type type="gint"/>
<parameters>
<parameter name="section" type="EekSection*"/>
</parameters>
</method>
<method name="get_n_rows" symbol="eek_section_get_n_rows">
<return-type type="gint"/>
<parameters>
<parameter name="section" type="EekSection*"/>
</parameters>
</method>
<method name="get_row" symbol="eek_section_get_row">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="index" type="gint"/>
<parameter name="num_columns" type="gint*"/>
<parameter name="orientation" type="EekOrientation*"/>
</parameters>
</method>
<method name="set_angle" symbol="eek_section_set_angle">
<return-type type="void"/>
<parameters>
<parameter name="section" type="EekSection*"/>
<parameter name="angle" type="gint"/>
</parameters>
</method>
<property name="angle" type="gint" readable="1" writable="1" construct="0" construct-only="0"/>
<signal name="key-pressed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekSection*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<signal name="key-released" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="object" type="EekSection*"/>
<parameter name="p0" type="EekKey*"/>
</parameters>
</signal>
<vfunc name="add_row">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="num_columns" type="gint"/>
<parameter name="orientation" type="EekOrientation"/>
</parameters>
</vfunc>
<vfunc name="create_key">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="row" type="gint"/>
<parameter name="column" type="gint"/>
</parameters>
</vfunc>
<vfunc name="find_key_by_keycode">
<return-type type="EekKey*"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="keycode" type="guint"/>
</parameters>
</vfunc>
<vfunc name="get_angle">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekSection*"/>
</parameters>
</vfunc>
<vfunc name="get_n_rows">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekSection*"/>
</parameters>
</vfunc>
<vfunc name="get_row">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="index" type="gint"/>
<parameter name="num_columns" type="gint*"/>
<parameter name="orientation" type="EekOrientation*"/>
</parameters>
</vfunc>
<vfunc name="set_angle">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekSection*"/>
<parameter name="angle" type="gint"/>
</parameters>
</vfunc>
</object>
<interface name="EekLayout" type-name="EekLayout" get-type="eek_layout_get_type">
<method name="apply" symbol="eek_layout_apply">
<return-type type="void"/>
<parameters>
<parameter name="layout" type="EekLayout*"/>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</method>
<method name="get_group" symbol="eek_layout_get_group">
<return-type type="gint"/>
<parameters>
<parameter name="layout" type="EekLayout*"/>
</parameters>
</method>
<signal name="changed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
</parameters>
</signal>
<signal name="group-changed" when="FIRST">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
<parameter name="group" type="gint"/>
</parameters>
</signal>
<vfunc name="apply">
<return-type type="void"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
<parameter name="keyboard" type="EekKeyboard*"/>
</parameters>
</vfunc>
<vfunc name="get_group">
<return-type type="gint"/>
<parameters>
<parameter name="self" type="EekLayout*"/>
</parameters>
</vfunc>
</interface>
<constant name="EEK_CONTAINER_H" type="int" value="1"/>
<constant name="EEK_ELEMENT_H" type="int" value="1"/>
<constant name="EEK_KEYBOARD_H" type="int" value="1"/>
<constant name="EEK_KEYSYM_H" type="int" value="1"/>
<constant name="EEK_KEY_H" type="int" value="1"/>
<constant name="EEK_LAYOUT_H" type="int" value="1"/>
<constant name="EEK_SECTION_H" type="int" value="1"/>
<constant name="EEK_TYPES_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
Eek cheader_filename="eek/eek.h"

View File

@ -0,0 +1 @@
Eek

View File

@ -0,0 +1,6 @@
include/eek-0.1/eek/eek-clutter-keyboard.h
include/eek-0.1/eek/eek-clutter-section.h
include/eek-0.1/eek/eek-clutter-key.h
include/eek-0.1/eek/eek-clutter-drawing-context.h
lib/libeek-clutter.so

View File

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekClutter">
<object name="EekClutterDrawingContext" parent="GInitiallyUnowned" type-name="EekClutterDrawingContext" get-type="eek_clutter_drawing_context_get_type">
<method name="get_category_font" symbol="eek_clutter_drawing_context_get_category_font">
<return-type type="PangoFontDescription*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="category" type="EekKeysymCategory"/>
</parameters>
</method>
<method name="get_outline_texture" symbol="eek_clutter_drawing_context_get_outline_texture">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="outline" type="EekOutline*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_drawing_context_new">
<return-type type="EekClutterDrawingContext*"/>
</constructor>
<method name="set_category_font" symbol="eek_clutter_drawing_context_set_category_font">
<return-type type="void"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="category" type="EekKeysymCategory"/>
<parameter name="fonts" type="PangoFontDescription*"/>
</parameters>
</method>
<method name="set_outline_texture" symbol="eek_clutter_drawing_context_set_outline_texture">
<return-type type="void"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="outline" type="EekOutline*"/>
<parameter name="texture" type="ClutterActor*"/>
</parameters>
</method>
</object>
<object name="EekClutterKey" parent="EekKey" type-name="EekClutterKey" get-type="eek_clutter_key_get_type">
<method name="get_actor" symbol="eek_clutter_key_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="key" type="EekClutterKey*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_key_new">
<return-type type="EekKey*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
<parameter name="column" type="gint"/>
<parameter name="row" type="gint"/>
</parameters>
</constructor>
</object>
<object name="EekClutterKeyboard" parent="EekKeyboard" type-name="EekClutterKeyboard" get-type="eek_clutter_keyboard_get_type">
<method name="get_actor" symbol="eek_clutter_keyboard_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="keyboard" type="EekClutterKeyboard*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_keyboard_new">
<return-type type="EekKeyboard*"/>
</constructor>
</object>
<object name="EekClutterSection" parent="EekSection" type-name="EekClutterSection" get-type="eek_clutter_section_get_type">
<method name="get_actor" symbol="eek_clutter_section_get_actor">
<return-type type="ClutterActor*"/>
<parameters>
<parameter name="section" type="EekClutterSection*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_clutter_section_new">
<return-type type="EekSection*"/>
<parameters>
<parameter name="context" type="EekClutterDrawingContext*"/>
</parameters>
</constructor>
</object>
<constant name="EEK_CLUTTER_DRAWING_CONTEXT_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_KEYBOARD_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_KEY_H" type="int" value="1"/>
<constant name="EEK_CLUTTER_SECTION_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekClutter cheader_filename="eek/eek-clutter.h"

View File

@ -0,0 +1 @@
EekClutter

View File

@ -0,0 +1,3 @@
include/eek-0.1/eek/eek-gtk-keyboard.h
include/eek-0.1/eek/eek-gtk.h
lib/libeek-gtk.so

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekGtk">
<object name="EekGtkKeyboard" parent="EekKeyboard" type-name="EekGtkKeyboard" get-type="eek_gtk_keyboard_get_type">
<method name="get_widget" symbol="eek_gtk_keyboard_get_widget">
<return-type type="GtkWidget*"/>
<parameters>
<parameter name="keyboard" type="EekGtkKeyboard*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_gtk_keyboard_new">
<return-type type="EekKeyboard*"/>
</constructor>
</object>
<constant name="EEK_GTK_H" type="int" value="1"/>
<constant name="EEK_GTK_KEYBOARD_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekGtk cheader_filename="eek/eek-gtk.h"

View File

@ -0,0 +1 @@
EekGtk

View File

@ -0,0 +1,2 @@
include/eek-0.1/eek/eek-xkb-layout.h
lib/libeek-xkb.so

View File

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekXkb">
<object name="EekXkbLayout" parent="GInitiallyUnowned" type-name="EekXkbLayout" get-type="eek_xkb_layout_get_type">
<implements>
<interface name="EekLayout"/>
</implements>
<method name="get_geometry" symbol="eek_xkb_layout_get_geometry">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<method name="get_keycodes" symbol="eek_xkb_layout_get_keycodes">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<method name="get_symbols" symbol="eek_xkb_layout_get_symbols">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_xkb_layout_new">
<return-type type="EekLayout*"/>
</constructor>
<method name="set_geometry" symbol="eek_xkb_layout_set_geometry">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="geometry" type="gchar*"/>
</parameters>
</method>
<method name="set_keycodes" symbol="eek_xkb_layout_set_keycodes">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="keycodes" type="gchar*"/>
</parameters>
</method>
<!--
<method name="set_names" symbol="eek_xkb_layout_set_names">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="names" type="XkbComponentNamesRec*"/>
</parameters>
</method>
-->
<method name="set_symbols" symbol="eek_xkb_layout_set_symbols">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXkbLayout*"/>
<parameter name="symbols" type="gchar*"/>
</parameters>
</method>
<property name="geometry" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="keycodes" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="symbols" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
</object>
<constant name="EEK_XKB_LAYOUT_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekXkb cheader_filename="eek/eek-xkb.h"

View File

@ -0,0 +1 @@
EekXkb

View File

@ -0,0 +1,3 @@
include/eek-0.1/eek/eek-xkl-layout.h
lib/libeek-xkl.so

View File

@ -0,0 +1,91 @@
<?xml version="1.0"?>
<api version="1.0">
<namespace name="EekXkl">
<object name="EekXklLayout" parent="EekXkbLayout" type-name="EekXklLayout" get-type="eek_xkl_layout_get_type">
<implements>
<interface name="EekLayout"/>
</implements>
<method name="disable_option" symbol="eek_xkl_layout_disable_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="enable_option" symbol="eek_xkl_layout_enable_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="get_layouts" symbol="eek_xkl_layout_get_layouts">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_model" symbol="eek_xkl_layout_get_model">
<return-type type="gchar*"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_option" symbol="eek_xkl_layout_get_option">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="option" type="gchar*"/>
</parameters>
</method>
<method name="get_options" symbol="eek_xkl_layout_get_options">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<method name="get_variants" symbol="eek_xkl_layout_get_variants">
<return-type type="gchar**"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
</parameters>
</method>
<constructor name="new" symbol="eek_xkl_layout_new">
<return-type type="EekLayout*"/>
</constructor>
<method name="set_layouts" symbol="eek_xkl_layout_set_layouts">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="layouts" type="gchar**"/>
</parameters>
</method>
<method name="set_model" symbol="eek_xkl_layout_set_model">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="model" type="gchar*"/>
</parameters>
</method>
<method name="set_options" symbol="eek_xkl_layout_set_options">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="options" type="gchar**"/>
</parameters>
</method>
<method name="set_variants" symbol="eek_xkl_layout_set_variants">
<return-type type="gboolean"/>
<parameters>
<parameter name="layout" type="EekXklLayout*"/>
<parameter name="variants" type="gchar**"/>
</parameters>
</method>
<property name="layouts" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="model" type="char*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="options" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
<property name="variants" type="GStrv*" readable="1" writable="1" construct="0" construct-only="0"/>
</object>
<constant name="EEK_XKL_LAYOUT_H" type="int" value="1"/>
</namespace>
</api>

View File

@ -0,0 +1 @@
EekXkl cheader_filename="eek/eek-xkl.h"

View File

@ -0,0 +1 @@
EekXkl

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
AC_INIT([eekboard], [0.0.1], [ueno@unixuser.org]) AC_INIT([eekboard], [0.0.5], [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
@ -35,12 +35,26 @@ 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([GTK2], [gtk+-2.0 gdk-2.0], ,
[AC_MSG_ERROR([GTK2 not found])]) [AC_MSG_ERROR([GTK2 not found])])
PKG_CHECK_MODULES([GCONF2], [gconf-2.0], ,
[AC_MSG_ERROR([GConf 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], , PKG_CHECK_MODULES([LIBFAKEKEY], [libfakekey], ,
[AC_MSG_ERROR([libfakekey not found])]) [AC_MSG_ERROR([libfakekey not found])])
PKG_CHECK_MODULES([CSPI], [cspi-1.0], ,
[AC_MSG_ERROR([AT-SPI C not found])])
PKG_CHECK_MODULES([NOTIFY], [libnotify], ,
[AC_MSG_ERROR([libnotify not found])])
AC_MSG_CHECKING([whether you enable Vala language support])
AC_ARG_ENABLE(vala,
AS_HELP_STRING([--enable-vala=no/yes],
[Enable Vala language binding default=yes]),,
enable_vala=yes)
AC_MSG_RESULT($enable_vala)
AM_CONDITIONAL(ENABLE_VALA, [test x$enable_vala = xyes])
AC_MSG_CHECKING([whether you enable eekboard]) AC_MSG_CHECKING([whether you enable eekboard])
AC_ARG_ENABLE(eekboard, AC_ARG_ENABLE(eekboard,
@ -61,18 +75,15 @@ 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])
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90], need_swap_event_workaround=no
[enable_clutter_gtk=yes]) PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90],,
if test x$enable_clutter_gtk = xno; then [PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10 clutter-x11-1.0],
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10], [need_swap_event_workaround=yes])])
[enable_clutter_gtk=yes]) AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found])
fi AC_DEFINE([NEED_SWAP_EVENT_WORKAROUND], [1],
if test x$enable_clutter_gtk = xyes; then [Define if GLX_INTEL_swap_event work around is needed])
AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found])
fi
fi fi
AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes]) AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes])
AM_CONDITIONAL(HAVE_CLUTTER_GTK, [test x$enable_clutter_gtk = xyes])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
@ -89,18 +100,22 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only
AM_GLIB_GNU_GETTEXT AM_GLIB_GNU_GETTEXT
AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR) AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR)
GOBJECT_INTROSPECTION_CHECK([0.6.7])
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 src/Makefile
tests/Makefile tests/Makefile
bindings/Makefile
bindings/vala/Makefile
docs/Makefile docs/Makefile
docs/reference/Makefile docs/reference/Makefile
docs/reference/eek/Makefile docs/reference/eek/Makefile
po/Makefile.in po/Makefile.in
eek/libeek.pc eek/eek-${EEK_API_VERSION}.pc
eek/libeek-clutter.pc eek/eek-clutter-${EEK_API_VERSION}.pc
eek/libeek-gtk.pc eek/eek-gtk-${EEK_API_VERSION}.pc
eek/libeek-xkb.pc eek/eek-xkb-${EEK_API_VERSION}.pc
eek/libeek-xkl.pc]) eek/eek-xkl-${EEK_API_VERSION}.pc])
AC_OUTPUT AC_OUTPUT

View File

@ -8,7 +8,7 @@
<bookinfo> <bookinfo>
<title>libeek Reference Manual</title> <title>libeek Reference Manual</title>
<releaseinfo> <releaseinfo>
for libeek 0.0.1. for libeek 0.0.5.
</releaseinfo> </releaseinfo>
<copyright> <copyright>
<year>2010</year> <year>2010</year>

View File

@ -4,23 +4,25 @@
<para>libeek is a library to create keyboard-like user interface. <para>libeek is a library to create keyboard-like user interface.
Since it is designed as simple as possible, it provides only two Since it is designed as simple as possible, it provides only two
kinds of objects. One is <emphasis>keyboard element</emphasis> kind of objects. One is <emphasis>keyboard element</emphasis>
(derived from #EekElement) and another is <emphasis>keyboard (objects derived from #EekElement) and another is
layout engine</emphasis> (which implements the #EekLayout <emphasis>keyboard layout engine</emphasis> (objects which
interface).</para> implements the #EekLayout interface).</para>
<para>A keyboard element represents either a keyboard <para>A keyboard element represents either a keyboard
(#EekKeyboard), a section (#EekSection), or a key (#EekKey). Each (#EekKeyboard), a section (#EekSection), or a key (#EekKey). Each
element implements the Builder design pattern so that it can be element implements the Builder design pattern so that it can map
converted into a UI widget (#ClutterActor, #GtkDrawingArea, itself to different UI widgets (#ClutterActor, #GtkDrawingArea,
aso).</para> aso).</para>
<para>A layout engine arranges keyboard elements using information <para>A layout engine arranges keyboard elements using information
from external configuration mechanisms (libxklavier, XKB, from external configuration mechanisms (libxklavier, XKB,
matchbox-keyboard layouts in XML, aso)</para> matchbox-keyboard layouts in XML, aso)</para>
<para>Here is a sample code which creates a keyboard-like #ClutterActor using the system keyboard layout using libxklavier:</para> <para>Here is a sample code which demonstrates (1) keyboard
elements are arranged with the system keyboard layout using
libxklavier and (2) keyboard elements are mapped into
#ClutterActor:</para>
<informalexample> <informalexample>
<programlisting> <programlisting>
EekKeyboard *keyboard; EekKeyboard *keyboard;
@ -40,14 +42,26 @@ clutter_group_add (CLUTTER_GROUP(stage),
</programlisting> </programlisting>
</informalexample> </informalexample>
<para>One of the most interesting features of libeek is that UI <para>The most interesting feature of libeek is that developer can
backends can be switched easily. For example, to create a choose arbitrary combination of UI toolkits and layout engine
keyboard-like #GtkWidget instead of #ClutterActor, all you need is supported by libeek. For example, to create a keyboard-like
to replace eek_clutter_keyboard_new() with eek_gtk_keyboard_new() #GtkWidget instead of #ClutterActor, all you need is to replace
and eek_clutter_keyboard_get_actor() with eek_clutter_keyboard_new() with eek_gtk_keyboard_new() and
eek_gtk_keyboard_get_widget().</para> eek_clutter_keyboard_get_actor() with
eek_gtk_keyboard_get_widget(). Similarly, if you want to use XKB
configuration directly (without libxklavier), you will only need to
replace eek_xkl_layout_new () with eek_xkb_layout_new().</para>
<para>There is logical represention (model) of keyboard distinct from the UI widget (view). More precisely, a keyboard is represented as a tree of #EekElement -- #EekKeyboard contains one or more #EekSection's and #EekSection contains one or more #EekKey's. Each element can be event source when user events on the UI widget occurs. For example, with the following code, when a user pushed a key widget with keycode 0x38 assigned, on_a_pressed will be called.</para> <para>To achieve portability across different UI toolkits,
there is a seperate represention of keyboard elements apart from
the actual UI widgets. For example, a keyboard is represented as a tree of
#EekElement -- #EekKeyboard contains one or more #EekSection's and
#EekSection contains one or more #EekKey's. Each element may emit
events when user pushes the corresponding UI widget.</para>
<para>
Here is another sample code which demonstrates logical events on
#EekElement:
</para>
<informalexample> <informalexample>
<programlisting> <programlisting>
/* Find a key element in the logical keyboard. */ /* Find a key element in the logical keyboard. */
@ -55,6 +69,6 @@ EekKey *key = eek_keyboard_find_key_by_keycode (keyboard, 0x38);
g_signal_connect (key, "pressed", on_a_pressed); g_signal_connect (key, "pressed", on_a_pressed);
</programlisting> </programlisting>
</informalexample> </informalexample>
<para>In this way, application developers do not need to know the differences between the underlying UI widgets after creation.</para> <para>When user pushed a widget which looks like "a" key (i.e. keycode 0x38), on_a_pressed will be called.</para>
</partintro> </partintro>
</part> </part>

View File

@ -123,6 +123,7 @@ EekXklLayoutClass
EekXklLayoutPrivate EekXklLayoutPrivate
eek_xkl_layout_new eek_xkl_layout_new
eek_xkl_layout_set_config eek_xkl_layout_set_config
eek_xkl_layout_set_config_full
eek_xkl_layout_set_model eek_xkl_layout_set_model
eek_xkl_layout_set_layouts eek_xkl_layout_set_layouts
eek_xkl_layout_set_variants eek_xkl_layout_set_variants
@ -131,6 +132,9 @@ eek_xkl_layout_get_model
eek_xkl_layout_get_layouts eek_xkl_layout_get_layouts
eek_xkl_layout_get_variants eek_xkl_layout_get_variants
eek_xkl_layout_get_options eek_xkl_layout_get_options
eek_xkl_layout_disable_option
eek_xkl_layout_enable_option
eek_xkl_layout_get_option
<SUBSECTION Standard> <SUBSECTION Standard>
EEK_XKL_LAYOUT EEK_XKL_LAYOUT
EEK_IS_XKL_LAYOUT EEK_IS_XKL_LAYOUT
@ -149,6 +153,7 @@ EekXkbLayoutClass
EekXkbLayoutPrivate EekXkbLayoutPrivate
eek_xkb_layout_new eek_xkb_layout_new
eek_xkb_layout_set_names eek_xkb_layout_set_names
eek_xkb_layout_set_names_full
eek_xkb_layout_set_keycodes eek_xkb_layout_set_keycodes
eek_xkb_layout_set_geometry eek_xkb_layout_set_geometry
eek_xkb_layout_set_symbols eek_xkb_layout_set_symbols

View File

@ -27,69 +27,68 @@ lib_LTLIBRARIES += libeek-clutter.la
endif endif
libeek_la_SOURCES = \ libeek_la_SOURCES = \
eek-layout.c \ $(srcdir)/eek-layout.c \
eek-layout.h \ $(srcdir)/eek-layout.h \
eek-element.c \ $(srcdir)/eek-element.c \
eek-element.h \ $(srcdir)/eek-element.h \
eek-container.c \ $(srcdir)/eek-container.c \
eek-container.h \ $(srcdir)/eek-container.h \
eek-keyboard.c \ $(srcdir)/eek-keyboard.c \
eek-keyboard.h \ $(srcdir)/eek-keyboard.h \
eek-section.c \ $(srcdir)/eek-section.c \
eek-section.h \ $(srcdir)/eek-section.h \
eek-key.c \ $(srcdir)/eek-key.c \
eek-key.h \ $(srcdir)/eek-key.h \
eek-types.h \ $(srcdir)/eek-types.h \
eek-types.c \ $(srcdir)/eek-types.c \
eek-keysym.h \ $(srcdir)/eek-keysym.h \
eek-keysym.c \ $(srcdir)/eek-keysym.c \
eek-special-keysym-labels.h \ $(srcdir)/eek-special-keysym-labels.h \
eek-unicode-keysym-labels.h \ $(srcdir)/eek-unicode-keysym-labels.h \
eek-keyname-keysym-labels.h $(srcdir)/eek-keyname-keysym-labels.h
libeek_la_CFLAGS = $(GOBJECT2_CFLAGS)
libeek_la_CFLAGS = $(GOBJECT2_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) libeek_la_LIBADD = $(GOBJECT2_LIBS) -lm
libeek_la_LIBADD = $(GOBJECT2_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS)
if HAVE_CLUTTER if HAVE_CLUTTER
libeek_clutter_la_SOURCES = \ libeek_clutter_la_SOURCES = \
eek-clutter-keyboard.c \ $(srcdir)/eek-clutter-keyboard.c \
eek-clutter-keyboard.h \ $(srcdir)/eek-clutter-keyboard.h \
eek-clutter-section.c \ $(srcdir)/eek-clutter-section.c \
eek-clutter-section.h \ $(srcdir)/eek-clutter-section.h \
eek-clutter-key.c \ $(srcdir)/eek-clutter-key.c \
eek-clutter-key.h \ $(srcdir)/eek-clutter-key.h \
eek-clutter-key-actor.c \ $(srcdir)/eek-clutter-key-actor.c \
eek-clutter-key-actor.h \ $(srcdir)/eek-clutter-key-actor.h \
eek-clutter-drawing-context.c \ $(srcdir)/eek-clutter-drawing-context.c \
eek-clutter-drawing-context.h \ $(srcdir)/eek-clutter-drawing-context.h \
eek-drawing.h \ $(srcdir)/eek-drawing.h \
eek-drawing.c \ $(srcdir)/eek-drawing.c \
eek-clutter.h $(srcdir)/eek-clutter.h
libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS) libeek_clutter_la_CFLAGS = $(CLUTTER_CFLAGS) $(CAIRO_LIBS) $(PANGO_LIBS)
libeek_clutter_la_LIBADD = libeek.la $(CLUTTER_LIBS) libeek_clutter_la_LIBADD = libeek.la $(CLUTTER_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS)
endif endif
libeek_gtk_la_SOURCES = \ libeek_gtk_la_SOURCES = \
eek-gtk-keyboard.c \ $(srcdir)/eek-gtk-keyboard.c \
eek-gtk-keyboard.h \ $(srcdir)/eek-gtk-keyboard.h \
eek-drawing.h \ $(srcdir)/eek-drawing.h \
eek-drawing.c \ $(srcdir)/eek-drawing.c \
eek-gtk.h $(srcdir)/eek-gtk.h
libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS) libeek_gtk_la_CFLAGS = $(GTK2_CFLAGS) $(CAIRO_LIBS) $(PANGO_LIBS)
libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS) libeek_gtk_la_LIBADD = libeek.la $(GTK2_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS)
libeek_xkb_la_SOURCES = \ libeek_xkb_la_SOURCES = \
eek-xkb-layout.h \ $(srcdir)/eek-xkb-layout.h \
eek-xkb-layout.c $(srcdir)/eek-xkb-layout.c
libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS) libeek_xkb_la_CFLAGS = $(GTK2_CFLAGS) $(XKB_CFLAGS)
libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS) libeek_xkb_la_LIBADD = libeek.la $(GTK2_LIBS) $(XKB_LIBS)
libeek_xkl_la_SOURCES = \ libeek_xkl_la_SOURCES = \
eek-xkl-layout.h \ $(srcdir)/eek-xkl-layout.h \
eek-xkl-layout.c $(srcdir)/eek-xkl-layout.c
libeek_xkl_la_CFLAGS = $(GTK2_CFLAGS) $(LIBXKLAVIER_CFLAGS) libeek_xkl_la_CFLAGS = $(GTK2_CFLAGS) $(LIBXKLAVIER_CFLAGS)
libeek_xkl_la_LIBADD = libeek-xkb.la $(GTK2_LIBS) $(LIBXKLAVIER_LIBS) libeek_xkl_la_LIBADD = libeek-xkb.la $(GTK2_LIBS) $(LIBXKLAVIER_LIBS)
@ -104,9 +103,11 @@ eek_HEADERS = \
$(top_srcdir)/eek/eek-layout.h \ $(top_srcdir)/eek/eek-layout.h \
$(top_srcdir)/eek/eek-keysym.h \ $(top_srcdir)/eek/eek-keysym.h \
$(top_srcdir)/eek/eek-types.h \ $(top_srcdir)/eek/eek-types.h \
$(top_srcdir)/eek/eek-gtk-keyboard.h \
$(top_srcdir)/eek/eek-xkb-layout.h \ $(top_srcdir)/eek/eek-xkb-layout.h \
$(top_srcdir)/eek/eek-xkl-layout.h \ $(top_srcdir)/eek/eek-xkl-layout.h \
$(top_srcdir)/eek/eek.h \ $(top_srcdir)/eek/eek.h \
$(top_srcdir)/eek/eek-gtk.h \
$(top_srcdir)/eek/eek-xkb.h \ $(top_srcdir)/eek/eek-xkb.h \
$(top_srcdir)/eek/eek-xkl.h $(top_srcdir)/eek/eek-xkl.h
@ -115,6 +116,7 @@ eek_HEADERS += \
$(top_srcdir)/eek/eek-clutter-keyboard.h \ $(top_srcdir)/eek/eek-clutter-keyboard.h \
$(top_srcdir)/eek/eek-clutter-section.h \ $(top_srcdir)/eek/eek-clutter-section.h \
$(top_srcdir)/eek/eek-clutter-key.h \ $(top_srcdir)/eek/eek-clutter-key.h \
$(top_srcdir)/eek/eek-clutter-drawing-context.h \
$(top_srcdir)/eek/eek-clutter.h $(top_srcdir)/eek/eek-clutter.h
endif endif
@ -128,11 +130,12 @@ eek-keyname-keysym-labels.h: keyname-keysym-labels.txt
$(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@ $(PYTHON) ./gen-keysym-labels.py keyname_keysym_labels < $< > $@
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libeek.pc \ pkgconfig_DATA = \
libeek-clutter.pc \ eek-$(EEK_API_VERSION).pc \
libeek-gtk.pc \ eek-clutter-$(EEK_API_VERSION).pc \
libeek-xkb.pc \ eek-gtk-$(EEK_API_VERSION).pc \
libeek-xkl.pc eek-xkb-$(EEK_API_VERSION).pc \
eek-xkl-$(EEK_API_VERSION).pc
DISTCLEANFILES = \ DISTCLEANFILES = \
eek-special-keysym-labels.h \ eek-special-keysym-labels.h \
@ -145,3 +148,65 @@ EXTRA_DIST = \
special-keysym-labels.txt \ special-keysym-labels.txt \
unicode-keysym-labels.txt \ unicode-keysym-labels.txt \
keyname-keysym-labels.txt keyname-keysym-labels.txt
CLEANFILES =
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
if HAVE_INTROSPECTION
Eek-0.1.gir: libeek.la
Eek_0_1_gir_SCANNERFLAGS = --strip-prefix=Eek --pkg=glib-2.0
Eek_0_1_gir_INCLUDES = GLib-2.0 GObject-2.0
Eek_0_1_gir_CFLAGS = $(libeek_la_CFLAGS)
Eek_0_1_gir_LIBS = libeek.la
Eek_0_1_gir_FILES = $(libeek_la_SOURCES)
EekGtk-0.1.gir: libeek-gtk.la Eek-0.1.gir
EekGtk_0_1_gir_INCLUDES = GObject-2.0 Gtk-2.0 Eek-0.1
EekGtk_0_1_gir_CFLAGS = $(libeek_gtk_la_CFLAGS)
EekGtk_0_1_gir_LIBS = libeek-gtk.la
EekGtk_0_1_gir_FILES = $(libeek_gtk_la_SOURCES)
if HAVE_CLUTTER
EekClutter-0.1.gir: libeek-clutter.la Eek-0.1.gir
EekClutter_0_1_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek-0.1
EekClutter_0_1_gir_CFLAGS = $(libeek_clutter_la_CFLAGS)
EekClutter_0_1_gir_LIBS = libeek-clutter.la
EekClutter_0_1_gir_FILES = $(libeek_clutter_la_SOURCES)
endif
EekXkb-0.1.gir: libeek-xkb.la Eek-0.1.gir
EekXkb_0_1_gir_INCLUDES = GObject-2.0 Eek-0.1
EekXkb_0_1_gir_CFLAGS = $(libeek_xkb_la_CFLAGS)
EekXkb_0_1_gir_LIBS = libeek-xkb.la
EekXkb_0_1_gir_FILES = $(libeek_xkb_la_SOURCES)
EekXkl-0.1.gir: libeek-xkl.la EekXkb-0.1.gir
EekXkl_0_1_gir_INCLUDES = GObject-2.0 EekXkb-0.1
EekXkl_0_1_gir_CFLAGS = $(libeek_xkl_la_CFLAGS)
EekXkl_0_1_gir_LIBS = libeek-xkl.la
EekXkl_0_1_gir_FILES = $(libeek_xkl_la_SOURCES)
INTROSPECTION_GIRS += \
Eek-0.1.gir \
EekGtk-0.1.gir \
EekXkb-0.1.gir \
EekXkl-0.1.gir
if HAVE_CLUTTER
INTROSPECTION_GIRS += \
EekClutter-0.1.gir
endif
girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(libdir)/girepository-1.0
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
CLEANFILES += $(gir_DATA) $(typelib_DATA)
endif

View File

@ -23,8 +23,8 @@ includedir=@includedir@
Name: EEK Name: EEK
Description: A Library to Create Keyboard-like UI Description: A Library to Create Keyboard-like UI
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Requires: gobject-2.0
Libs: -L${libdir} -leek Libs: -L${libdir} -leek
Libs.private: @GOBJECT2_LIBS@
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-clutter Name: libeek-clutter
Description: A Library to Create Keyboard-like UI (Clutter Support) Description: A Library to Create Keyboard-like UI (Clutter Support)
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -leek -leek-clutter Requires: eek-@EEK_API_VERSION@ clutter-1.0
Libs.private: @GOBJECT2_LIBS@ @CLUTTER_LIBS@ Libs: -L${libdir} -leek-clutter
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -52,6 +52,7 @@ struct _EekClutterKeyActorPrivate
EekClutterDrawingContext *context; EekClutterDrawingContext *context;
EekKey *key; EekKey *key;
ClutterActor *texture; ClutterActor *texture;
gboolean is_pressed;
}; };
static ClutterActor *get_texture (EekClutterKeyActor *actor); static ClutterActor *get_texture (EekClutterKeyActor *actor);
@ -103,28 +104,6 @@ eek_clutter_key_actor_real_paint (ClutterActor *self)
g_object_unref (layout); g_object_unref (layout);
} }
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
static void
eek_clutter_key_actor_real_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
PangoLayout *layout;
/* Draw the label on the key - just to validate the glyph cache. */
layout = clutter_actor_create_pango_layout (self, NULL);
draw_key_on_layout (EEK_CLUTTER_KEY_ACTOR(self), layout);
cogl_pango_ensure_glyph_cache_for_layout (layout);
g_object_unref (layout);
CLUTTER_ACTOR_CLASS (eek_clutter_key_actor_parent_class)->
get_preferred_width (self, for_height, min_width_p, natural_width_p);
}
static void static void
eek_clutter_key_actor_real_pressed (EekClutterKeyActor *self) eek_clutter_key_actor_real_pressed (EekClutterKeyActor *self)
{ {
@ -181,12 +160,6 @@ eek_clutter_key_actor_class_init (EekClutterKeyActorClass *klass)
sizeof (EekClutterKeyActorPrivate)); sizeof (EekClutterKeyActorPrivate));
actor_class->paint = eek_clutter_key_actor_real_paint; actor_class->paint = eek_clutter_key_actor_real_paint;
/* FIXME: This is a workaround for the bug
* http://bugzilla.openedhand.com/show_bug.cgi?id=2137 A developer
* says this is not a right way to solve the original problem.
*/
actor_class->get_preferred_width =
eek_clutter_key_actor_real_get_preferred_width;
gobject_class->dispose = eek_clutter_key_actor_dispose; gobject_class->dispose = eek_clutter_key_actor_dispose;
@ -223,8 +196,11 @@ on_button_press_event (ClutterActor *actor,
EekClutterKeyActorPrivate *priv = EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor); EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
/* priv->key will send back PRESSED event of actor. */ if (!priv->is_pressed) {
g_signal_emit_by_name (priv->key, "pressed"); priv->is_pressed = TRUE;
/* priv->key will send back PRESSED event of actor. */
g_signal_emit_by_name (priv->key, "pressed");
}
} }
static void static void
@ -235,8 +211,27 @@ on_button_release_event (ClutterActor *actor,
EekClutterKeyActorPrivate *priv = EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor); EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
/* priv->key will send back RELEASED event of actor. */ if (priv->is_pressed) {
g_signal_emit_by_name (priv->key, "released"); priv->is_pressed = FALSE;
/* priv->key will send back RELEASED event of actor. */
g_signal_emit_by_name (priv->key, "released");
}
}
static gboolean
on_leave_event (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{
EekClutterKeyActorPrivate *priv =
EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(actor);
if (priv->is_pressed) {
priv->is_pressed = FALSE;
/* priv->key will send back RELEASED event of actor. */
g_signal_emit_by_name (priv->key, "released");
}
return FALSE;
} }
static void static void
@ -247,12 +242,15 @@ eek_clutter_key_actor_init (EekClutterKeyActor *self)
priv = self->priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(self); priv = self->priv = EEK_CLUTTER_KEY_ACTOR_GET_PRIVATE(self);
priv->key = NULL; priv->key = NULL;
priv->texture = NULL; priv->texture = NULL;
clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE); clutter_actor_set_reactive (CLUTTER_ACTOR(self), TRUE);
g_signal_connect (self, "button-press-event", g_signal_connect (self, "button-press-event",
G_CALLBACK (on_button_press_event), NULL); G_CALLBACK (on_button_press_event), NULL);
g_signal_connect (self, "button-release-event", g_signal_connect (self, "button-release-event",
G_CALLBACK (on_button_release_event), NULL); G_CALLBACK (on_button_release_event), NULL);
g_signal_connect (self, "leave-event",
G_CALLBACK (on_leave_event), NULL);
} }
ClutterActor * ClutterActor *

View File

@ -231,23 +231,16 @@ eek_container_find (EekContainer *container,
user_data); user_data);
} }
struct _FbpData
{
EekKey *key;
gint x, y;
};
typedef struct _FbpData FbpData;
static gint static gint
compare_element_by_position (EekElement *element, gpointer user_data) compare_element_by_position (EekElement *element, gpointer user_data)
{ {
EekBounds bounds; EekBounds bounds;
FbpData *data = user_data; EekPoint *point = user_data;
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
if (bounds.x <= data->x && bounds.y <= data->y && if (bounds.x <= point->x && bounds.y <= point->y &&
data->x <= (bounds.x + bounds.width) && point->x <= (bounds.x + bounds.width) &&
data->y <= (bounds.y + bounds.height)) point->y <= (bounds.y + bounds.height))
return 0; return 0;
return -1; return -1;
} }
@ -258,13 +251,13 @@ eek_container_find_by_position (EekContainer *container,
gdouble y) gdouble y)
{ {
EekBounds bounds; EekBounds bounds;
FbpData data; EekPoint point;
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL); g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
eek_element_get_bounds (EEK_ELEMENT(container), &bounds); eek_element_get_bounds (EEK_ELEMENT(container), &bounds);
data.x = x - bounds.x; point.x = x - bounds.x;
data.y = y - bounds.y; point.y = y - bounds.y;
return eek_container_find (container, return eek_container_find (container,
compare_element_by_position, compare_element_by_position,
&data); &point);
} }

View File

@ -90,7 +90,7 @@ egf_key_callback (EekElement *element,
gdouble font_size; gdouble font_size;
guint keysym; guint keysym;
EekBounds bounds; EekBounds bounds;
const gchar *label; gchar *label;
keysym = eek_key_get_keysym (key); keysym = eek_key_get_keysym (key);
if (keysym == EEK_INVALID_KEYSYM || if (keysym == EEK_INVALID_KEYSYM ||
@ -99,9 +99,12 @@ egf_key_callback (EekElement *element,
eek_element_get_bounds (EEK_ELEMENT(key), &bounds); eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
label = eek_keysym_to_string (keysym); label = eek_keysym_to_string (keysym);
if (!label)
return;
font_size = get_font_size (label, &bounds, data->layout); font_size = get_font_size (label, &bounds, data->layout);
if (font_size < data->font_size && font_size >= data->minimum_font_size) if (font_size < data->font_size && font_size >= data->minimum_font_size)
data->font_size = font_size; data->font_size = font_size;
g_free (label);
} }
static void static void
@ -214,7 +217,7 @@ eek_draw_key_label (cairo_t *cr,
{ {
guint keysym; guint keysym;
EekKeysymCategory category; EekKeysymCategory category;
const gchar *label; gchar *label;
PangoLayout *layout; PangoLayout *layout;
PangoRectangle logical_rect = { 0, }; PangoRectangle logical_rect = { 0, };
EekBounds bounds; EekBounds bounds;
@ -242,6 +245,7 @@ eek_draw_key_label (cairo_t *cr,
(bounds.width - logical_rect.width / PANGO_SCALE) / 2, (bounds.width - logical_rect.width / PANGO_SCALE) / 2,
(bounds.height - logical_rect.height / PANGO_SCALE) / 2); (bounds.height - logical_rect.height / PANGO_SCALE) / 2);
pango_cairo_show_layout (cr, layout); pango_cairo_show_layout (cr, layout);
g_free (label);
g_object_unref (layout); g_object_unref (layout);
} }

View File

@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-gtk 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://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -leek -leek-gtk Requires: eek-@EEK_API_VERSION@ gtk+-2.0
Libs.private: @GOBJECT2_LIBS@ @GTK2_LIBS@ Libs: -L${libdir} -leek-gtk
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -23,6 +23,7 @@
* @short_description: #EekKeyboard that can be converted into a #GtkWidget * @short_description: #EekKeyboard that can be converted into a #GtkWidget
*/ */
#include <string.h> #include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -58,6 +59,8 @@ struct _EekGtkKeyboardPrivate
PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST]; PangoFontDescription *fonts[EEK_KEYSYM_CATEGORY_LAST];
gdouble scale; gdouble scale;
EekKey *key;
}; };
static void prepare_keyboard_pixmap (EekGtkKeyboard *keyboard); static void prepare_keyboard_pixmap (EekGtkKeyboard *keyboard);
@ -79,6 +82,9 @@ eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self,
GtkStateType state; GtkStateType state;
GtkAllocation allocation; GtkAllocation allocation;
if (!priv->widget || !gtk_widget_get_realized (priv->widget))
return;
prepare_keyboard_pixmap (keyboard); prepare_keyboard_pixmap (keyboard);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation); gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation);
@ -114,6 +120,7 @@ eek_gtk_keyboard_finalize (GObject *object)
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]);
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->finalize (object);
} }
static void static void
@ -150,6 +157,7 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
g_object_unref); 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;
} }
/** /**
@ -171,6 +179,9 @@ struct _DrawingContext
}; };
typedef struct _DrawingContext DrawingContext; typedef struct _DrawingContext DrawingContext;
static void on_key_pressed (EekKey *key, gpointer user_data);
static void on_key_released (EekKey *key, gpointer user_data);
static void static void
prepare_keyboard_pixmap_key_callback (EekElement *element, prepare_keyboard_pixmap_key_callback (EekElement *element,
gpointer user_data) gpointer user_data)
@ -185,6 +196,11 @@ prepare_keyboard_pixmap_key_callback (EekElement *element,
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
g_signal_connect (key, "pressed", G_CALLBACK(on_key_pressed),
context->keyboard);
g_signal_connect (key, "released", G_CALLBACK(on_key_released),
context->keyboard);
outline = eek_key_get_outline (key); outline = eek_key_get_outline (key);
texture = g_hash_table_lookup (priv->outline_textures, outline); texture = g_hash_table_lookup (priv->outline_textures, outline);
if (!texture) { if (!texture) {
@ -222,12 +238,15 @@ prepare_keyboard_pixmap_section_callback (EekElement *element,
{ {
DrawingContext *context = user_data; DrawingContext *context = user_data;
EekBounds bounds; EekBounds bounds;
gint angle;
eek_element_get_bounds (element, &bounds); eek_element_get_bounds (element, &bounds);
angle = eek_section_get_angle (EEK_SECTION(element));
cairo_save (context->cr); cairo_save (context->cr);
cairo_translate (context->cr, cairo_translate (context->cr,
bounds.x, bounds.x,
bounds.y); bounds.y);
cairo_rotate (context->cr, angle * M_PI / 180);
eek_container_foreach_child (EEK_CONTAINER(element), eek_container_foreach_child (EEK_CONTAINER(element),
prepare_keyboard_pixmap_key_callback, prepare_keyboard_pixmap_key_callback,
context); context);
@ -298,6 +317,7 @@ on_expose_event (GtkWidget *widget,
base_font = gtk_widget_get_style (priv->widget)->font_desc; base_font = gtk_widget_get_style (priv->widget)->font_desc;
pango_layout_set_font_description (layout, base_font); pango_layout_set_font_description (layout, base_font);
eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts); eek_get_fonts (EEK_KEYBOARD(keyboard), layout, priv->fonts);
g_object_unref (layout);
prepare_keyboard_pixmap (keyboard); prepare_keyboard_pixmap (keyboard);
} }
@ -402,42 +422,97 @@ key_shrink (EekGtkKeyboard *keyboard, EekKey *key)
bounds.height * SCALE * priv->scale); bounds.height * SCALE * priv->scale);
} }
static void
on_key_pressed (EekKey *key, gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
key_enlarge (EEK_GTK_KEYBOARD(keyboard), key);
priv->key = key;
}
static void
on_key_released (EekKey *key, gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
if (priv->key) {
key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(priv->key));
priv->key = NULL;
}
key_shrink (EEK_GTK_KEYBOARD(keyboard), key);
}
static void
press_key (EekGtkKeyboard *keyboard, EekKey *key)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
if (priv->key != key)
g_signal_emit_by_name (key, "pressed", keyboard);
}
static void
release_key (EekGtkKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
if (priv->key)
g_signal_emit_by_name (priv->key, "released", keyboard);
}
static gboolean
on_key_event (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data)
{
EekGtkKeyboard *keyboard = user_data;
EekKey *key;
key = eek_keyboard_find_key_by_keycode (EEK_KEYBOARD(keyboard),
event->hardware_keycode);
if (!key)
return FALSE;
switch (event->type) {
case GDK_KEY_PRESS:
press_key (keyboard, key);
return TRUE;
case GDK_KEY_RELEASE:
release_key (keyboard);
return TRUE;
default:
return FALSE;
}
}
static gboolean static gboolean
on_button_event (GtkWidget *widget, on_button_event (GtkWidget *widget,
GdkEventButton *event, GdkEventButton *event,
gpointer user_data) gpointer user_data)
{ {
EekElement *keyboard = user_data, *section, *key; EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD(user_data);
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard); EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
EekBounds bounds; EekKey *key;
gdouble x, y; gdouble x, y;
x = (gdouble)event->x / priv->scale; x = (gdouble)event->x / priv->scale;
y = (gdouble)event->y / priv->scale; y = (gdouble)event->y / priv->scale;
section = eek_container_find_by_position (EEK_CONTAINER(keyboard), x, y); key = eek_keyboard_find_key_by_position (EEK_KEYBOARD(keyboard), x, y);
if (section) { if (key)
eek_element_get_bounds (keyboard, &bounds); switch (event->type) {
x -= bounds.x; case GDK_BUTTON_PRESS:
y -= bounds.y; press_key (EEK_GTK_KEYBOARD(keyboard), key);
key = eek_container_find_by_position (EEK_CONTAINER(section), return TRUE;
x, case GDK_BUTTON_RELEASE:
y); release_key (EEK_GTK_KEYBOARD(keyboard));
if (key) return TRUE;
switch (event->type) { default:
case GDK_BUTTON_PRESS: return FALSE;
key_enlarge (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key)); }
g_signal_emit_by_name (keyboard, "key-pressed", key);
return TRUE;
case GDK_BUTTON_RELEASE:
key_shrink (EEK_GTK_KEYBOARD(keyboard), EEK_KEY(key));
g_signal_emit_by_name (keyboard, "key-released", key);
return TRUE;
default:
return FALSE;
}
}
return FALSE; return FALSE;
} }
static void static void
on_size_allocate (GtkWidget *widget, on_size_allocate (GtkWidget *widget,
GtkAllocation *allocation, GtkAllocation *allocation,
@ -460,6 +535,7 @@ on_size_allocate (GtkWidget *widget,
allocation->width / bounds.width : allocation->width / bounds.width :
allocation->height / bounds.height; allocation->height / bounds.height;
} }
GtkWidget * GtkWidget *
eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard) eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard)
{ {
@ -474,12 +550,17 @@ eek_gtk_keyboard_get_widget (EekGtkKeyboard *keyboard)
gtk_widget_set_events (priv->widget, gtk_widget_set_events (priv->widget,
GDK_EXPOSURE_MASK | GDK_EXPOSURE_MASK |
GDK_KEY_PRESS_MASK | GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK); GDK_BUTTON_RELEASE_MASK);
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);
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_CALLBACK (on_key_event), keyboard);
g_signal_connect (priv->widget, "key-release-event",
G_CALLBACK (on_key_event), keyboard);
g_signal_connect (priv->widget, "button-press-event", g_signal_connect (priv->widget, "button-press-event",
G_CALLBACK (on_button_event), keyboard); G_CALLBACK (on_button_event), keyboard);
g_signal_connect (priv->widget, "button-release-event", g_signal_connect (priv->widget, "button-release-event",

View File

@ -484,3 +484,61 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard, return EEK_KEYBOARD_GET_CLASS(keyboard)->find_key_by_keycode (keyboard,
keycode); keycode);
} }
static gint
compare_section_by_position (EekElement *element, gpointer user_data)
{
EekSection *section = EEK_SECTION(element);
EekPoint *point = user_data;
gint angle;
EekBounds bounds;
EekPoint rotated;
eek_element_get_bounds (element, &bounds);
rotated.x = point->x - bounds.x;
rotated.y = point->y - bounds.y;
angle = eek_section_get_angle (section);
eek_point_rotate (&rotated, -angle);
if (0 <= rotated.x && 0 <= rotated.y &&
rotated.x <= bounds.width &&
rotated.y <= bounds.height)
return 0;
return -1;
}
static EekSection *
eek_keyboard_find_section_by_position (EekKeyboard *keyboard,
gdouble x,
gdouble y)
{
EekBounds bounds;
EekPoint point;
EekElement *element;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
point.x = x - bounds.x;
point.y = y - bounds.y;
element = eek_container_find (EEK_CONTAINER(keyboard),
compare_section_by_position,
&point);
return EEK_SECTION(element);
}
EekKey *
eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
gdouble x,
gdouble y)
{
EekSection *section;
EekBounds bounds;
section = eek_keyboard_find_section_by_position (keyboard, x, y);
if (!section)
return NULL;
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
x -= bounds.x;
y -= bounds.y;
return eek_section_find_key_by_position (section, x, y);
}

View File

@ -83,22 +83,25 @@ struct _EekKeyboardClass
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_keyboard_get_type (void) G_GNUC_CONST; GType eek_keyboard_get_type (void) G_GNUC_CONST;
void eek_keyboard_set_keysym_index (EekKeyboard *keyboard, void eek_keyboard_set_keysym_index (EekKeyboard *keyboard,
gint group, gint group,
gint level); gint level);
void eek_keyboard_get_keysym_index (EekKeyboard *keyboard, void eek_keyboard_get_keysym_index (EekKeyboard *keyboard,
gint *group, gint *group,
gint *level); gint *level);
EekSection *eek_keyboard_create_section (EekKeyboard *keyboard); EekSection *eek_keyboard_create_section (EekKeyboard *keyboard);
void eek_keyboard_set_layout (EekKeyboard *keyboard, void eek_keyboard_set_layout (EekKeyboard *keyboard,
EekLayout *layout); EekLayout *layout);
void eek_keyboard_realize (EekKeyboard *keyboard); void eek_keyboard_realize (EekKeyboard *keyboard);
EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, EekKey *eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
guint keycode); guint keycode);
EekKey *eek_keyboard_find_key_by_position (EekKeyboard *keyboard,
gdouble x,
gdouble y);
G_END_DECLS G_END_DECLS
#endif /* EEK_KEYBOARD_H */ #endif /* EEK_KEYBOARD_H */

View File

@ -41,7 +41,7 @@ struct eek_keysym_label {
#include "eek-unicode-keysym-labels.h" #include "eek-unicode-keysym-labels.h"
#include "eek-keyname-keysym-labels.h" #include "eek-keyname-keysym-labels.h"
static G_CONST_RETURN gchar * static gchar *
unichar_to_utf8 (gunichar uc) unichar_to_utf8 (gunichar uc)
{ {
if (g_unichar_isgraph (uc)) { if (g_unichar_isgraph (uc)) {
@ -65,7 +65,7 @@ keysym_label_compare (const void *key0, const void *key1)
static gboolean static gboolean
find_keysym (guint keysym, find_keysym (guint keysym,
const gchar **label, gchar **label,
EekKeysymCategory *category) EekKeysymCategory *category)
{ {
struct eek_keysym_label bsearch_key, *bsearch_val; struct eek_keysym_label bsearch_key, *bsearch_val;
@ -144,10 +144,10 @@ find_keysym (guint keysym,
* *
* Return a string representation of @keysym. * Return a string representation of @keysym.
*/ */
G_CONST_RETURN gchar * gchar *
eek_keysym_to_string (guint keysym) eek_keysym_to_string (guint keysym)
{ {
const gchar *label; gchar *label;
if (find_keysym (keysym, &label, NULL)) if (find_keysym (keysym, &label, NULL))
return label; return label;

View File

@ -51,10 +51,11 @@ typedef enum {
EEK_KEYSYM_CATEGORY_FUNCTION, EEK_KEYSYM_CATEGORY_FUNCTION,
EEK_KEYSYM_CATEGORY_KEYNAME, EEK_KEYSYM_CATEGORY_KEYNAME,
EEK_KEYSYM_CATEGORY_UNKNOWN, EEK_KEYSYM_CATEGORY_UNKNOWN,
/*< private >*/
EEK_KEYSYM_CATEGORY_LAST = EEK_KEYSYM_CATEGORY_UNKNOWN EEK_KEYSYM_CATEGORY_LAST = EEK_KEYSYM_CATEGORY_UNKNOWN
} EekKeysymCategory; } EekKeysymCategory;
G_CONST_RETURN gchar *eek_keysym_to_string (guint keysym); gchar *eek_keysym_to_string (guint keysym);
EekKeysymCategory eek_keysym_get_category (guint keysym); EekKeysymCategory eek_keysym_get_category (guint keysym);
#endif /* EEK_KEYSYM_H */ #endif /* EEK_KEYSYM_H */

View File

@ -438,3 +438,26 @@ eek_section_find_key_by_keycode (EekSection *section,
return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section, return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section,
keycode); keycode);
} }
EekKey *
eek_section_find_key_by_position (EekSection *section,
gdouble x,
gdouble y)
{
gint angle;
EekBounds bounds;
EekPoint point;
EekElement *key;
eek_element_get_bounds (EEK_ELEMENT(section), &bounds);
point.x = x - bounds.x;
point.y = y - bounds.y;
angle = eek_section_get_angle (section);
eek_point_rotate (&point, -angle);
key = eek_container_find_by_position (EEK_CONTAINER(section),
point.x + bounds.x,
point.y + bounds.y);
if (!key)
return NULL;
return EEK_KEY(key);
}

View File

@ -86,27 +86,30 @@ struct _EekSectionClass
gpointer pdummy[24]; gpointer pdummy[24];
}; };
GType eek_section_get_type (void) G_GNUC_CONST; GType eek_section_get_type (void) G_GNUC_CONST;
void eek_section_set_angle (EekSection *section, void eek_section_set_angle (EekSection *section,
gint angle); gint angle);
gint eek_section_get_angle (EekSection *section); gint eek_section_get_angle (EekSection *section);
gint eek_section_get_n_rows (EekSection *section); gint eek_section_get_n_rows (EekSection *section);
void eek_section_add_row (EekSection *section, void eek_section_add_row (EekSection *section,
gint num_columns, gint num_columns,
EekOrientation orientation); EekOrientation orientation);
void eek_section_get_row (EekSection *section, void eek_section_get_row (EekSection *section,
gint index, gint index,
gint *num_columns, gint *num_columns,
EekOrientation *orientation); EekOrientation *orientation);
EekKey *eek_section_create_key (EekSection *section, EekKey *eek_section_create_key (EekSection *section,
gint column, gint column,
gint row); gint row);
EekKey *eek_section_find_key_by_keycode (EekSection *section, EekKey *eek_section_find_key_by_keycode (EekSection *section,
guint keycode); guint keycode);
EekKey *eek_section_find_key_by_position (EekSection *section,
gdouble x,
gdouble y);
G_END_DECLS G_END_DECLS
#endif /* EEK_SECTION_H */ #endif /* EEK_SECTION_H */

View File

@ -28,6 +28,7 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include "eek-types.h" #include "eek-types.h"
#include <math.h>
/* EekKeysymMatrix */ /* EekKeysymMatrix */
static EekKeysymMatrix * static EekKeysymMatrix *
@ -81,6 +82,18 @@ eek_point_get_type (void)
return our_type; return our_type;
} }
void
eek_point_rotate (EekPoint *point, gint angle)
{
gdouble r, phi;
phi = atan2 (point->y, point->x);
r = sqrt (point->x * point->x + point->y * point->y);
phi += angle * M_PI / 180;
point->x = r * cos (phi);
point->y = r * sin (phi);
}
/* EekBounds */ /* EekBounds */
static EekBounds * static EekBounds *
eek_bounds_copy (const EekBounds *bounds) eek_bounds_copy (const EekBounds *bounds)

View File

@ -80,6 +80,8 @@ typedef struct _EekPoint EekPoint;
#define EEK_TYPE_POINT (eek_point_get_type ()) #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,
gint angle);
/** /**
* EekBounds: * EekBounds:

View File

@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-xkb 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://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Libs: -L${libdir} -leek -leek-xkb Requires: eek-@EEK_API_VERSION@ gtk+-x11-2.0
Libs.private: @GTK2_LIBS@ @XKB_LIBS@ Libs: -L${libdir} -leek-xkb
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -31,6 +31,7 @@
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/extensions/XKBgeom.h> #include <X11/extensions/XKBgeom.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -169,8 +170,10 @@ create_key (EekXkbLayout *layout,
outline->num_points = xkboutline->num_points; outline->num_points = xkboutline->num_points;
outline->points = g_new0 (EekPoint, outline->num_points); outline->points = g_new0 (EekPoint, outline->num_points);
for (i = 0; i < xkboutline->num_points; i++) { for (i = 0; i < xkboutline->num_points; i++) {
outline->points[i].x = xkb_to_pixmap_coord(layout, xkboutline->points[i].x); outline->points[i].x =
outline->points[i].y = xkb_to_pixmap_coord(layout, xkboutline->points[i].y); xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
outline->points[i].y =
xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
} }
} }
g_hash_table_insert (priv->outline_hash, xkbshape, outline); g_hash_table_insert (priv->outline_hash, xkbshape, outline);
@ -418,7 +421,8 @@ eek_xkb_layout_real_get_group (EekLayout *self)
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self); EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
XkbStateRec state; XkbStateRec state;
g_return_val_if_fail (XkbGetState (priv->display, XkbUseCoreKbd, &state), -1); g_return_val_if_fail (XkbGetState (priv->display, XkbUseCoreKbd, &state),
-1);
return state.group; return state.group;
} }
@ -564,7 +568,7 @@ eek_xkb_layout_new (void)
} }
/** /**
* eek_xkb_layout_set_names: * eek_xkb_layout_set_names: (skip)
* @layout: an #EekXkbLayout * @layout: an #EekXkbLayout
* @names: XKB component names * @names: XKB component names
* *
@ -607,6 +611,70 @@ eek_xkb_layout_set_names (EekXkbLayout *layout, XkbComponentNamesRec *names)
return TRUE; return TRUE;
} }
/**
* eek_xkb_layout_set_names_full:
* @layout: an #EekXkbLayout
* @Varargs: pairs of component name and value, terminated by -1.
*
* Set the XKB component names to @layout. This function is merely a
* wrapper around eek_xkb_layout_set_names() to avoid passing a
* pointer of XkbComponentNamesRec, which is not currently available
* in the gobject-introspection repository.
*
* Available component names are: keymap, keycodes, types, compat,
* symbols, geometry.
*
* Returns: %TRUE if the component name is successfully set, %FALSE otherwise
* Since: 0.0.2
*/
gboolean
eek_xkb_layout_set_names_full (EekXkbLayout *layout,
...)
{
va_list var_args;
va_start (var_args, layout);
eek_xkb_layout_set_names_full_valist (layout, var_args);
va_end (var_args);
}
/**
* eek_xkb_layout_set_names_full_valist:
* @layout: an #EekXkbLayout
* @var_args: <type>va_list</type> of pairs of component name and value.
*
* See eek_xkb_layout_set_names_full(), this version takes a
* <type>va_list</type> for language bindings to use.
*
* Since: 0.0.5
*/
gboolean
eek_xkb_layout_set_names_full_valist (EekXkbLayout *layout,
va_list var_args)
{
XkbComponentNamesRec names;
gchar *name, *value;
memset (&names, 0, sizeof names);
name = va_arg (var_args, gchar *);
while (name != (gchar *)-1) {
value = va_arg (var_args, gchar *);
if (g_strcmp0 (name, "keymap") == 0)
names.keymap = (char *)value;
else if (g_strcmp0 (name, "keycodes") == 0)
names.keycodes = (char *)value;
else if (g_strcmp0 (name, "types") == 0)
names.types = (char *)value;
else if (g_strcmp0 (name, "compat") == 0)
names.compat = (char *)value;
else if (g_strcmp0 (name, "symbols") == 0)
names.symbols = (char *)value;
else if (g_strcmp0 (name, "geometry") == 0)
names.geometry = (char *)value;
name = va_arg (var_args, gchar *);
}
return eek_xkb_layout_set_names (layout, &names);
}
/** /**
* eek_xkb_layout_set_keycodes: * eek_xkb_layout_set_keycodes:
* @layout: an #EekXkbLayout * @layout: an #EekXkbLayout

View File

@ -60,6 +60,14 @@ EekLayout *eek_xkb_layout_new (void);
gboolean eek_xkb_layout_set_names (EekXkbLayout *layout, gboolean eek_xkb_layout_set_names (EekXkbLayout *layout,
XkbComponentNamesRec *names); XkbComponentNamesRec *names);
gboolean eek_xkb_layout_set_names_full
(EekXkbLayout *layout,
...);
gboolean eek_xkb_layout_set_names_full_valist
(EekXkbLayout *layout,
va_list var_args);
gboolean eek_xkb_layout_set_keycodes gboolean eek_xkb_layout_set_keycodes
(EekXkbLayout *layout, (EekXkbLayout *layout,
const gchar *keycodes); const gchar *keycodes);

View File

@ -23,8 +23,8 @@ includedir=@includedir@
Name: libeek-xkl Name: libeek-xkl
Description: A Library to Create Keyboard-like UI (Libxklavier Support) Description: A Library to Create Keyboard-like UI (Libxklavier Support)
URL: http://github.com/ueno/eekboard URL: http://ueno.github.com/eekboard/
Version: @VERSION@ Version: @VERSION@
Requires: eek-xkb-@EEK_API_VERSION@ libxklavier
Libs: -L${libdir} -leek-xkl Libs: -L${libdir} -leek-xkl
Libs.private: @GTK2_LIBS@ @LIBXKLAVIER_LIBS@
Cflags: -I${includedir}/eek-@EEK_API_VERSION@ Cflags: -I${includedir}/eek-@EEK_API_VERSION@

View File

@ -318,7 +318,7 @@ merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
} }
/** /**
* eek_xkl_layout_set_config: * eek_xkl_layout_set_config: (skip)
* @layout: an #EekXklLayout * @layout: an #EekXklLayout
* @config: Libxklavier configuration * @config: Libxklavier configuration
* *
@ -345,6 +345,43 @@ eek_xkl_layout_set_config (EekXklLayout *layout,
return FALSE; return FALSE;
} }
/**
* eek_xkl_layout_set_config_full:
* @layout: an #EekXklLayout
* @model: Libxklavier model name
* @layouts: Libxklavier layouts
* @variants: Libxklavier variants
* @options: Libxklavier options
*
* Reconfigure @layout with @model, @layouts, @variants, and @options.
* This function is merely a wrapper around
* eek_xkl_layout_set_config() to avoid passing a pointer of
* XklConfigRec, which is not currently available in the
* gobject-introspection repository.
*
* Returns: %TRUE if the component name is successfully set, %FALSE otherwise
* Since: 0.0.2
*/
gboolean
eek_xkl_layout_set_config_full (EekXklLayout *layout,
gchar *model,
gchar **layouts,
gchar **variants,
gchar **options)
{
XklConfigRec *config;
gboolean success;
config = xkl_config_rec_new ();
config->model = g_strdup (model);
config->layouts = g_strdupv (layouts);
config->variants = g_strdupv (variants);
config->options = g_strdupv (options);
success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config);
return success;
}
/** /**
* eek_xkl_layout_set_model: * eek_xkl_layout_set_model:
* @layout: an #EekXklLayout * @layout: an #EekXklLayout
@ -363,7 +400,11 @@ eek_xkl_layout_set_model (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->model = (gchar *)model; /* config->model will be freed on g_object_unref (config) */
if (model)
config->model = g_strdup (model);
else
config->model = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -387,7 +428,11 @@ eek_xkl_layout_set_layouts (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->layouts = layouts; /* config->layouts will be freed on g_object_unref (config) */
if (layouts)
config->layouts = g_strdupv (layouts);
else
config->layouts = layouts;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -411,7 +456,11 @@ eek_xkl_layout_set_variants (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->variants = variants; /* config->variants will be freed on g_object_unref (config) */
if (variants)
config->variants = g_strdupv (variants);
else
config->variants = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -435,7 +484,11 @@ eek_xkl_layout_set_options (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->options = options; /* config->options will be freed on g_object_unref (config) */
if (options)
config->options = options;
else
config->options = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -512,7 +565,7 @@ eek_xkl_layout_get_model (EekXklLayout *layout)
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout); EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
return priv->config->model; return g_strdup (priv->config->model);
} }
/** /**
@ -528,7 +581,7 @@ eek_xkl_layout_get_layouts (EekXklLayout *layout)
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout); EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
return priv->config->layouts; return g_strdupv (priv->config->layouts);
} }
/** /**
@ -544,7 +597,7 @@ eek_xkl_layout_get_variants (EekXklLayout *layout)
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout); EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
return priv->config->variants; return g_strdupv (priv->config->variants);
} }
/** /**
@ -560,7 +613,7 @@ eek_xkl_layout_get_options (EekXklLayout *layout)
EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout); EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
g_return_val_if_fail (priv, NULL); g_return_val_if_fail (priv, NULL);
return priv->config->options; return g_strdupv (priv->config->options);
} }
static gboolean static gboolean

View File

@ -20,6 +20,7 @@
#ifndef EEK_XKL_LAYOUT_H #ifndef EEK_XKL_LAYOUT_H
#define EEK_XKL_LAYOUT_H 1 #define EEK_XKL_LAYOUT_H 1
#include <libxklavier/xklavier.h>
#include "eek-xkb-layout.h" #include "eek-xkb-layout.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -53,32 +54,38 @@ struct _EekXklLayoutClass
gpointer pdummy[24]; gpointer pdummy[24];
}; };
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 (void); EekLayout *eek_xkl_layout_new (void);
gboolean eek_xkl_layout_set_config (EekXklLayout *layout, gboolean eek_xkl_layout_set_config (EekXklLayout *layout,
XklConfigRec *config); XklConfigRec *config);
gboolean eek_xkl_layout_set_model (EekXklLayout *layout, gboolean eek_xkl_layout_set_config_full (EekXklLayout *layout,
const gchar *model); gchar *model,
gboolean eek_xkl_layout_set_layouts (EekXklLayout *layout, gchar **layouts,
gchar **layouts); gchar **variants,
gboolean eek_xkl_layout_set_variants (EekXklLayout *layout, gchar **options);
gchar **variants);
gboolean eek_xkl_layout_set_options (EekXklLayout *layout,
gchar **options);
gboolean eek_xkl_layout_enable_option (EekXklLayout *layout,
const gchar *option);
gboolean eek_xkl_layout_disable_option (EekXklLayout *layout,
const gchar *option);
gchar *eek_xkl_layout_get_model (EekXklLayout *layout); gboolean eek_xkl_layout_set_model (EekXklLayout *layout,
gchar **eek_xkl_layout_get_layouts (EekXklLayout *layout); const gchar *model);
gchar **eek_xkl_layout_get_variants (EekXklLayout *layout); gboolean eek_xkl_layout_set_layouts (EekXklLayout *layout,
gchar **eek_xkl_layout_get_options (EekXklLayout *layout); gchar **layouts);
gboolean eek_xkl_layout_get_option (EekXklLayout *layout, gboolean eek_xkl_layout_set_variants (EekXklLayout *layout,
const gchar *option); gchar **variants);
gboolean eek_xkl_layout_set_options (EekXklLayout *layout,
gchar **options);
gboolean eek_xkl_layout_enable_option (EekXklLayout *layout,
const gchar *option);
gboolean eek_xkl_layout_disable_option (EekXklLayout *layout,
const gchar *option);
gchar *eek_xkl_layout_get_model (EekXklLayout *layout);
gchar **eek_xkl_layout_get_layouts (EekXklLayout *layout);
gchar **eek_xkl_layout_get_variants (EekXklLayout *layout);
gchar **eek_xkl_layout_get_options (EekXklLayout *layout);
gboolean eek_xkl_layout_get_option (EekXklLayout *layout,
const gchar *option);
G_END_DECLS G_END_DECLS
#endif /* #ifndef EEK_XKL_LAYOUT_H */ #endif /* #ifndef EEK_XKL_LAYOUT_H */

23
eekboard-sample.conf Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<eekboard>
<config>
<name>Thai Kinesis</name>
<model>kinesis</model>
<layouts>pc+us+th(pat)</layouts>
</config>
<config>
<name>Tifinagh Typematrix</name>
<model>tm2030USB-106</model>
<layouts>pc+us+ma(tifinagh-extended-phonetic)</layouts>
</config>
<config>
<name>Indic Bengali Microsoft Natural</name>
<model>microsoft</model>
<layouts>pc+us+in(ben)</layouts>
</config>
<config>
<name>US Generic 104-key PC</name>
<model>pc104</model>
<layouts>pc+us</layouts>
</config>
</eekboard>

View File

@ -6,10 +6,10 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: eekboard 0.0.0\n" "Project-Id-Version: eekboard 0.0.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-06-21 12:42+0900\n" "POT-Creation-Date: 2010-06-23 16:52+0900\n"
"PO-Revision-Date: 2010-06-21 12:45+0900\n" "PO-Revision-Date: 2010-06-23 16:55+0900\n"
"Last-Translator: Daiki Ueno <ueno@unixuser.org>\n" "Last-Translator: Daiki Ueno <ueno@unixuser.org>\n"
"Language-Team: Japanese\n" "Language-Team: Japanese\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -17,46 +17,74 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../src/eekboard.c:195 #: ../src/eekboard.c:198
msgid "_File" msgid "_File"
msgstr "ファイル" msgstr "ファイル"
#: ../src/eekboard.c:196 #: ../src/eekboard.c:199
msgid "_Keyboard" msgid "_Keyboard"
msgstr "キーボード" msgstr "キーボード"
#: ../src/eekboard.c:197 #: ../src/eekboard.c:200
msgid "_Help" msgid "_Help"
msgstr "ヘルプ" msgstr "ヘルプ"
#: ../src/eekboard.c:199 #: ../src/eekboard.c:202
msgid "Country" msgid "Country"
msgstr "国" msgstr "国"
#: ../src/eekboard.c:201 #: ../src/eekboard.c:204
msgid "Language" msgid "Language"
msgstr "言語" msgstr "言語"
#: ../src/eekboard.c:203 #: ../src/eekboard.c:206
msgid "Model" msgid "Model"
msgstr "モデル" msgstr "モデル"
#: ../src/eekboard.c:205 #: ../src/eekboard.c:208
msgid "Layout" msgid "Layout"
msgstr "レイアウト" msgstr "レイアウト"
#: ../src/eekboard.c:207 #: ../src/eekboard.c:210
msgid "Option" msgid "Option"
msgstr "オプション" msgstr "オプション"
#: ../src/eekboard.c:214 #: ../src/eekboard.c:217
msgid "Monitor Key Typing" msgid "Monitor Key Typing"
msgstr "打鍵をモニタ" msgstr "打鍵をモニタ"
#: ../src/eekboard.c:232 #: ../src/eekboard.c:232
msgid "Keyboard model to display"
msgstr "表示するキーボードのモデル"
#: ../src/eekboard.c:234
msgid "Keyboard layouts to display, separated with commas"
msgstr "表示するキーボードのレイアウト,カンマ区切り"
#: ../src/eekboard.c:236
msgid "Keyboard layout options to display, separated with commas"
msgstr "表示するキーボードのオプション,カンマ区切り"
#: ../src/eekboard.c:238
msgid "List keyboard models"
msgstr "キーボードのモデルを一覧"
#: ../src/eekboard.c:240
msgid "List all available keyboard layouts and variants"
msgstr "利用可能なキーボードのレイアウトとバリアントを一覧"
#: ../src/eekboard.c:242
msgid "List all available keyboard layout options"
msgstr "利用可能なキーボードのレイアウトオプションを一覧"
#: ../src/eekboard.c:244
msgid "Display version"
msgstr "バージョンを表示"
#: ../src/eekboard.c:261
msgid "A virtual keyboard for GNOME" msgid "A virtual keyboard for GNOME"
msgstr "GNOME 向け仮想キーボード" msgstr "GNOME 向け仮想キーボード"
#: ../src/eekboard.c:236 #: ../src/eekboard.c:265
msgid "Eekboard web site" msgid "Eekboard web site"
msgstr "Eekboard のウェブサイト" msgstr "Eekboard のウェブサイト"

View File

@ -22,27 +22,28 @@ eekboard_CFLAGS = \
-I$(top_srcdir) \ -I$(top_srcdir) \
$(GOBJECT2_CFLAGS) \ $(GOBJECT2_CFLAGS) \
$(GTK2_CFLAGS) \ $(GTK2_CFLAGS) \
$(GCONF2_CFLAGS) \
$(XKB_CFLAGS) \ $(XKB_CFLAGS) \
$(LIBXKLAVIER_CFLAGS) \ $(LIBXKLAVIER_CFLAGS) \
$(LIBFAKEKEY_CFLAGS) $(LIBFAKEKEY_CFLAGS) \
$(CSPI_CFLAGS) \
$(NOTIFY_CFLAGS)
eekboard_LDFLAGS = \ eekboard_LDFLAGS = \
$(top_builddir)/eek/libeek.la \ $(top_builddir)/eek/libeek.la \
$(top_builddir)/eek/libeek-xkl.la \ $(top_builddir)/eek/libeek-xkl.la \
$(top_builddir)/eek/libeek-gtk.la \ $(top_builddir)/eek/libeek-gtk.la \
$(GOBJECT2_LIBS) \ $(GOBJECT2_LIBS) \
$(GTK2_CFLAGS) \ $(GTK2_LIBS) \
$(GCONF2_LIBS) \
$(XKB_LIBS) \ $(XKB_LIBS) \
$(LIBXKLAVIER_LIBS) \ $(LIBXKLAVIER_LIBS) \
$(LIBFAKEKEY_LIBS) $(LIBFAKEKEY_LIBS) \
$(CSPI_LIBS) \
$(NOTIFY_LIBS)
if HAVE_CLUTTER if HAVE_CLUTTER
eekboard_CFLAGS += $(CLUTTER_CFLAGS) eekboard_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS)
eekboard_LDFLAGS += $(CLUTTER_LIBS) eekboard_LDFLAGS += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
endif
if HAVE_CLUTTER_GTK
eekboard_CFLAGS += $(CLUTTER_GTK_CFLAGS)
eekboard_LDFLAGS += $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
endif endif
endif endif

View File

@ -22,16 +22,19 @@
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
#include <clutter-gtk/clutter-gtk.h> #include <clutter-gtk/clutter-gtk.h>
#if NEED_SWAP_EVENT_WORKAROUND
#include <clutter/x11/clutter-x11.h>
#endif
#endif #endif
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gconf/gconf-client.h>
#include <libxklavier/xklavier.h> #include <libxklavier/xklavier.h>
#include <fakekey/fakekey.h> #include <fakekey/fakekey.h>
#if 0 #include <cspi/spi.h>
#include <atk/atk.h> #include <libnotify/notify.h>
#endif
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -73,16 +76,28 @@
"You should have received a copy of the GNU General Public License " \ "You should have received a copy of the GNU General Public License " \
"along with this program. If not, see <http://www.gnu.org/licenses/>. " \ "along with this program. If not, see <http://www.gnu.org/licenses/>. " \
struct _Config {
gchar *name;
XklConfigRec *rec;
};
typedef struct _Config Config;
struct _Eekboard { struct _Eekboard {
gboolean use_clutter; gboolean use_clutter;
gboolean need_swap_event_workaround;
gboolean accessibility_enabled;
Config **config;
gint active_config;
Display *display; Display *display;
FakeKey *fakekey; FakeKey *fakekey;
GtkWidget *widget; GConfClient *gconfc;
Accessible *acc;
GtkWidget *widget, *window, *combo;
gint width, height; gint width, height;
guint key_event_listener;
XklEngine *engine; XklEngine *engine;
XklConfigRegistry *registry; XklConfigRegistry *registry;
GtkUIManager *ui_manager; GtkUIManager *ui_manager;
gulong on_key_pressed_id, on_key_released_id;
guint countries_merge_id; guint countries_merge_id;
GtkActionGroup *countries_action_group; GtkActionGroup *countries_action_group;
@ -136,11 +151,9 @@ 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);
#if 0 static void on_quit (GtkAction * action,
static void on_monitor_key_event_toggled
(GtkToggleAction *action,
GtkWidget *window); GtkWidget *window);
#endif static void eekboard_free (Eekboard *eekboard);
static GtkWidget *create_widget (Eekboard *eekboard, static GtkWidget *create_widget (Eekboard *eekboard,
gint initial_width, gint initial_width,
gint initial_height); gint initial_height);
@ -159,9 +172,6 @@ static const char ui_description[] =
" <menuitem action='Quit'/>" " <menuitem action='Quit'/>"
" </menu>" " </menu>"
" <menu action='KeyboardMenu'>" " <menu action='KeyboardMenu'>"
#if 0
" <menuitem action='MonitorKeyEvent'/>"
#endif
" <menu action='Country'>" " <menu action='Country'>"
" <placeholder name='CountriesPH'/>" " <placeholder name='CountriesPH'/>"
" </menu>" " </menu>"
@ -195,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 (gtk_main_quit)}, {"Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (on_quit)},
{"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,
@ -209,12 +219,44 @@ static const GtkActionEntry action_entry[] = {
{"About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK (on_about)} {"About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK (on_about)}
}; };
#if 0 static gchar *opt_model = NULL;
static const GtkToggleActionEntry toggle_action_entry[] = { static gchar *opt_layouts = NULL;
{"MonitorKeyEvent", NULL, N_("Monitor Key Typing"), NULL, NULL, static gchar *opt_options = NULL;
G_CALLBACK(on_monitor_key_event_toggled), FALSE} static gboolean opt_list_models = FALSE;
}; static gboolean opt_list_layouts = FALSE;
static gboolean opt_list_options = FALSE;
static gboolean opt_version = FALSE;
#if HAVE_CLUTTER_GTK
static gchar *opt_toolkit = NULL;
#endif #endif
static gboolean opt_standalone = FALSE;
static gchar *opt_config = NULL;
static const GOptionEntry options[] = {
{"model", 'M', 0, G_OPTION_ARG_STRING, &opt_model,
N_("Keyboard model to display")},
{"layouts", 'L', 0, G_OPTION_ARG_STRING, &opt_layouts,
N_("Keyboard layouts to display, separated with commas")},
{"options", 'O', 0, G_OPTION_ARG_STRING, &opt_options,
N_("Keyboard layout options to display, separated with commas")},
{"list-models", '\0', 0, G_OPTION_ARG_NONE, &opt_list_models,
N_("List keyboard models")},
{"list-layouts", '\0', 0, G_OPTION_ARG_NONE, &opt_list_layouts,
N_("List all available keyboard layouts and variants")},
{"list-options", 'O', 0, G_OPTION_ARG_NONE, &opt_list_options,
N_("List all available keyboard layout options")},
#if HAVE_CLUTTER_GTK
{"toolkit", 't', 0, G_OPTION_ARG_STRING, &opt_toolkit,
N_("Toolkit (\"clutter\" or \"gtk\")")},
#endif
{"standalone", 's', 0, G_OPTION_ARG_NONE, &opt_standalone,
N_("Start as a standalone application")},
{"config", 'c', 0, G_OPTION_ARG_STRING, &opt_config,
N_("Specify configuration file")},
{"version", 'v', 0, G_OPTION_ARG_NONE, &opt_version,
N_("Display version")},
{NULL}
};
static void static void
on_about (GtkAction * action, GtkWidget *window) on_about (GtkAction * action, GtkWidget *window)
@ -237,32 +279,123 @@ on_about (GtkAction * action, GtkWidget *window)
"wrap-license", TRUE, NULL); "wrap-license", TRUE, NULL);
} }
#if 0 static void
static gint on_quit (GtkAction * action, GtkWidget *window)
key_snoop (AtkKeyEventStruct *event, gpointer func_data)
{ {
return FALSE; Eekboard *eekboard = g_object_get_data (G_OBJECT(window), "eekboard");
fakekey_release (eekboard->fakekey);
eekboard_free (eekboard);
gtk_main_quit ();
} }
static void static void
on_monitor_key_event_toggled (GtkToggleAction *action, set_location (Eekboard *eekboard,
GtkWidget *window) Accessible *acc)
{ {
AccessibleComponent *component = Accessible_getComponent (acc);
long int x, y, width, height;
Eekboard *eekboard = g_object_get_data (G_OBJECT(window), "eekboard"); AccessibleComponent_getExtents (component,
&x, &y, &width, &height,
if (gtk_toggle_action_get_active (action)) { SPI_COORD_TYPE_SCREEN);
if (eekboard->key_event_listener == 0) gtk_window_move (GTK_WINDOW(eekboard->window), x, y + height);
eekboard->key_event_listener =
atk_add_key_event_listener (key_snoop, eekboard);
g_warning ("failed to enable ATK key event listener");
} else
if (eekboard->key_event_listener != 0) {
atk_remove_key_event_listener (eekboard->key_event_listener);
eekboard->key_event_listener = 0;
}
} }
#endif
static SPIBoolean
a11y_focus_listener (const AccessibleEvent *event,
void *user_data)
{
Eekboard *eekboard = user_data;
Accessible *acc = event->source;
AccessibleStateSet *state_set = Accessible_getStateSet (acc);
AccessibleRole role = Accessible_getRole (acc);
/* Ignore focus on eekboard itself since eekboard itself has GTK+
widgets. */
if (gtk_widget_has_focus (eekboard->window))
return FALSE;
/* The logic is borrowed from Caribou. */
if (AccessibleStateSet_contains (state_set, SPI_STATE_EDITABLE) ||
role == SPI_ROLE_TERMINAL) {
switch (role) {
case SPI_ROLE_TEXT:
case SPI_ROLE_PARAGRAPH:
case SPI_ROLE_PASSWORD_TEXT:
case SPI_ROLE_TERMINAL:
if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
set_location (eekboard, acc);
gtk_widget_show (eekboard->window);
eekboard->acc = acc;
} else if (event->detail1 == 0 && acc == eekboard->acc) {
gtk_widget_hide (eekboard->window);
eekboard->acc = NULL;
}
case SPI_ROLE_ENTRY:
if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
set_location (eekboard, acc);
gtk_widget_show (eekboard->window);
eekboard->acc = acc;
} else if (event->detail1 == 0 && acc == eekboard->acc) {
gtk_widget_hide (eekboard->window);
eekboard->acc = NULL;
}
default:
;
}
}
return FALSE;
}
static SPIBoolean
a11y_keystroke_listener (const AccessibleKeystroke *stroke,
void *user_data)
{
Eekboard *eekboard = user_data;
EekKey *key;
guint keysym;
guint ignored_keysyms[] = {XK_Shift_L,
XK_Shift_R,
XK_Control_L,
XK_Control_R,
XK_Alt_L,
XK_Alt_R};
gint i;
key = eek_keyboard_find_key_by_keycode (eekboard->keyboard,
stroke->keycode);
if (!key)
return FALSE;
/* XXX: Ignore modifier keys since there is no way to receive
SPI_KEY_RELEASED event for them. */
keysym = eek_key_get_keysym (key);
for (i = 0; i < G_N_ELEMENTS(ignored_keysyms) &&
keysym != ignored_keysyms[i]; i++)
;
if (i != G_N_ELEMENTS(ignored_keysyms))
return FALSE;
if (stroke->type == SPI_KEY_PRESSED) {
g_signal_handler_block (eekboard->keyboard,
eekboard->on_key_pressed_id);
g_signal_emit_by_name (key, "pressed");
g_signal_handler_unblock (eekboard->keyboard,
eekboard->on_key_pressed_id);
} else {
g_signal_handler_block (eekboard->keyboard,
eekboard->on_key_released_id);
g_signal_emit_by_name (key, "released");
g_signal_handler_unblock (eekboard->keyboard,
eekboard->on_key_released_id);
}
return TRUE;
}
static AccessibleEventListener* focusListener;
static AccessibleEventListener* keystrokeListener;
static void static void
on_key_pressed (EekKeyboard *keyboard, on_key_pressed (EekKeyboard *keyboard,
@ -274,6 +407,7 @@ on_key_pressed (EekKeyboard *keyboard,
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) { if (keysym == XK_Shift_L || keysym == XK_Shift_R) {
gint group, level; gint group, level;
@ -325,13 +459,15 @@ on_changed (EekLayout *layout, gpointer user_data)
{ {
Eekboard *eekboard = user_data; Eekboard *eekboard = user_data;
GtkWidget *vbox, *widget; GtkWidget *vbox, *widget;
GtkAllocation allocation;
gtk_widget_get_allocation (GTK_WIDGET (eekboard->widget), &allocation);
vbox = gtk_widget_get_parent (eekboard->widget); vbox = gtk_widget_get_parent (eekboard->widget);
/* gtk_widget_destroy() seems not usable for GtkClutterEmbed */ /* gtk_widget_destroy() seems not usable for GtkClutterEmbed */
gtk_container_remove (GTK_CONTAINER(vbox), eekboard->widget); gtk_container_remove (GTK_CONTAINER(vbox), eekboard->widget);
g_object_unref (eekboard->keyboard); g_object_unref (eekboard->keyboard);
widget = create_widget (eekboard, eekboard->width, eekboard->height); widget = create_widget (eekboard, allocation.width, allocation.height);
gtk_container_add (GTK_CONTAINER(vbox), widget); gtk_container_add (GTK_CONTAINER(vbox), widget);
gtk_widget_show_all (vbox); gtk_widget_show_all (vbox);
} }
@ -816,11 +952,6 @@ create_menus (Eekboard *eekboard,
gtk_action_group_add_actions (action_group, action_entry, gtk_action_group_add_actions (action_group, action_entry,
G_N_ELEMENTS (action_entry), window); G_N_ELEMENTS (action_entry), window);
#if 0
gtk_action_group_add_toggle_actions (action_group, toggle_action_entry,
G_N_ELEMENTS (toggle_action_entry),
window);
#endif
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);
@ -865,10 +996,12 @@ create_widget_gtk (Eekboard *eekboard,
eekboard->keyboard = eek_gtk_keyboard_new (); eekboard->keyboard = eek_gtk_keyboard_new ();
eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout);
eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds);
g_signal_connect (eekboard->keyboard, "key-pressed", eekboard->on_key_pressed_id =
G_CALLBACK(on_key_pressed), eekboard); g_signal_connect (eekboard->keyboard, "key-pressed",
g_signal_connect (eekboard->keyboard, "key-released", G_CALLBACK(on_key_pressed), eekboard);
G_CALLBACK(on_key_released), eekboard); eekboard->on_key_released_id =
g_signal_connect (eekboard->keyboard, "key-released",
G_CALLBACK(on_key_released), eekboard);
eekboard->widget = eekboard->widget =
eek_gtk_keyboard_get_widget (EEK_GTK_KEYBOARD (eekboard->keyboard)); eek_gtk_keyboard_get_widget (EEK_GTK_KEYBOARD (eekboard->keyboard));
@ -879,6 +1012,26 @@ create_widget_gtk (Eekboard *eekboard,
} }
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
#if NEED_SWAP_EVENT_WORKAROUND
static GdkFilterReturn
gtk_clutter_filter_func (GdkXEvent *native_event,
GdkEvent *event,
gpointer user_data)
{
XEvent *xevent = native_event;
clutter_x11_handle_event (xevent);
return GDK_FILTER_CONTINUE;
}
static void
on_gtk_clutter_embed_realize (GtkWidget *widget, gpointer user_data)
{
gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget);
}
#endif
static GtkWidget * static GtkWidget *
create_widget_clutter (Eekboard *eekboard, create_widget_clutter (Eekboard *eekboard,
gint initial_width, gint initial_width,
@ -895,12 +1048,19 @@ create_widget_clutter (Eekboard *eekboard,
eekboard->keyboard = eek_clutter_keyboard_new (); eekboard->keyboard = eek_clutter_keyboard_new ();
eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout);
eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds);
g_signal_connect (eekboard->keyboard, "key-pressed", eekboard->on_key_pressed_id =
G_CALLBACK(on_key_pressed), eekboard); g_signal_connect (eekboard->keyboard, "key-pressed",
g_signal_connect (eekboard->keyboard, "key-released", G_CALLBACK(on_key_pressed), eekboard);
G_CALLBACK(on_key_released), eekboard); eekboard->on_key_released_id =
g_signal_connect (eekboard->keyboard, "key-released",
G_CALLBACK(on_key_released), eekboard);
eekboard->widget = gtk_clutter_embed_new (); eekboard->widget = gtk_clutter_embed_new ();
#if NEED_SWAP_EVENT_WORKAROUND
if (eekboard->need_swap_event_workaround)
g_signal_connect (eekboard->widget, "realize",
G_CALLBACK(on_gtk_clutter_embed_realize), NULL);
#endif
stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget)); stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget));
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
@ -927,13 +1087,43 @@ create_widget (Eekboard *eekboard,
} }
#endif #endif
static void
parse_layouts (XklConfigRec *rec, const gchar *_layouts)
{
gchar **layouts, **variants;
gint i;
layouts = g_strsplit (_layouts, ",", -1);
variants = g_strdupv (layouts);
for (i = 0; layouts[i]; i++) {
gchar *layout = layouts[i], *variant = variants[i],
*variant_start, *variant_end;
variant_start = strchr (layout, '(');
variant_end = strrchr (layout, ')');
if (variant_start && variant_end) {
*variant_start++ = '\0';
g_strlcpy (variant, variant_start,
variant_end - variant_start + 1);
} else
*variant = '\0';
}
rec->layouts = layouts;
rec->variants = variants;
}
Eekboard * Eekboard *
eekboard_new (gboolean use_clutter) eekboard_new (gboolean use_clutter,
gboolean need_swap_event_workaround,
gboolean accessibility_enabled)
{ {
Eekboard *eekboard; Eekboard *eekboard;
eekboard = g_slice_new0 (Eekboard); eekboard = g_slice_new0 (Eekboard);
eekboard->use_clutter = use_clutter; eekboard->use_clutter = use_clutter;
eekboard->need_swap_event_workaround = need_swap_event_workaround;
eekboard->accessibility_enabled = accessibility_enabled;
eekboard->active_config = -1;
eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (!eekboard->display) { if (!eekboard->display) {
g_slice_free (Eekboard, eekboard); g_slice_free (Eekboard, eekboard);
@ -954,6 +1144,24 @@ eekboard_new (gboolean use_clutter)
g_warning ("Can't create layout"); g_warning ("Can't create layout");
return NULL; return NULL;
} }
if (opt_model)
eek_xkl_layout_set_model (EEK_XKL_LAYOUT(eekboard->layout), opt_model);
if (opt_layouts) {
XklConfigRec *rec = xkl_config_rec_new ();
parse_layouts (rec, opt_layouts);
eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(eekboard->layout),
rec->layouts);
eek_xkl_layout_set_variants (EEK_XKL_LAYOUT(eekboard->layout),
rec->variants);
g_object_unref (rec);
}
if (opt_options) {
gchar **options;
options = g_strsplit (opt_options, ",", -1);
eek_xkl_layout_set_options (EEK_XKL_LAYOUT(eekboard->layout), options);
g_strfreev (options);
}
g_signal_connect (eekboard->layout, "changed", g_signal_connect (eekboard->layout, "changed",
G_CALLBACK(on_changed), eekboard); G_CALLBACK(on_changed), eekboard);
@ -962,34 +1170,280 @@ eekboard_new (gboolean use_clutter)
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);
create_widget (eekboard, CSW, CSH);
return eekboard; return eekboard;
} }
static void
eekboard_free (Eekboard *eekboard)
{
if (eekboard->layout)
g_object_unref (eekboard->layout);
#if 0
if (eekboard->keyboard)
g_object_unref (eekboard->keyboard);
#endif
if (eekboard->registry)
g_object_unref (eekboard->registry);
if (eekboard->engine)
g_object_unref (eekboard->engine);
g_slice_free (Eekboard, eekboard);
}
static void
print_layout (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
GSList *variants = NULL;
xkl_config_registry_foreach_layout_variant (registry,
item->name,
collect_variant,
&variants);
if (!variants)
printf ("%s: %s\n", item->name, item->description);
else {
GSList *head;
for (head = variants; head; head = head->next) {
XklConfigItem *_item = head->data;
printf ("%s(%s): %s %s\n",
item->name,
_item->name,
item->description,
_item->description);
g_slice_free (XklConfigItem, _item);
}
g_slist_free (variants);
}
}
static void
print_item (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
printf ("%s: %s\n", item->name, item->description);
}
static void
print_option_group (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
xkl_config_registry_foreach_option (registry,
item->name,
print_item,
NULL);
}
static void
on_notify_never_show (NotifyNotification *notification,
char *action,
gpointer user_data)
{
Eekboard *eekboard = user_data;
GError *error;
gconf_client_set_bool (eekboard->gconfc,
"/apps/eekboard/inhibit-startup-notify",
TRUE,
&error);
}
static void
on_layout_changed (GtkComboBox *combo,
gpointer user_data)
{
Eekboard *eekboard = user_data;
GtkTreeModel *model;
GtkTreeIter iter;
gint active;
model = gtk_combo_box_get_model (combo);
gtk_combo_box_get_active_iter (combo, &iter);
gtk_tree_model_get (model, &iter, 1, &active, -1);
if (eekboard->active_config != active) {
XklConfigRec *config, *config_base = eekboard->config[active]->rec;
config = xkl_config_rec_new ();
if (config_base->model)
config->model = g_strdup (config_base->model);
else
config->model =
eek_xkl_layout_get_model (EEK_XKL_LAYOUT(eekboard->layout));
if (config_base->layouts)
config->layouts = g_strdupv (config_base->layouts);
else
config->layouts =
eek_xkl_layout_get_layouts (EEK_XKL_LAYOUT(eekboard->layout));
if (config_base->variants)
config->variants = g_strdupv (config_base->variants);
else
config->variants =
eek_xkl_layout_get_variants (EEK_XKL_LAYOUT(eekboard->layout));
if (config_base->options)
config->options = g_strdupv (config_base->options);
else
config->options =
eek_xkl_layout_get_options (EEK_XKL_LAYOUT(eekboard->layout));
eek_xkl_layout_set_config (EEK_XKL_LAYOUT(eekboard->layout), config);
g_object_unref (config);
eekboard->active_config = active;
}
}
struct _ConfigContext {
GSList *list;
GString *text;
};
typedef struct _ConfigContext ConfigContext;
static void
config_parser_start_element (GMarkupParseContext *pcontext,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
ConfigContext *context = user_data;
if (g_strcmp0 (element_name, "config") == 0) {
Config *config = g_slice_new0 (Config);
config->rec = xkl_config_rec_new ();
context->list = g_slist_prepend (context->list, config);
} else
context->text = g_string_sized_new (100);
}
static void
config_parser_end_element (GMarkupParseContext *pcontext,
const gchar *element_name,
gpointer user_data,
GError **error)
{
ConfigContext *context = user_data;
Config *config = context->list->data;
gchar *text;
if (g_strcmp0 (element_name, "config") == 0 &&
!config->name) {
if (error)
*error = g_error_new (G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"\"name\" is missing");
return;
}
if (!context->text)
return;
text = g_string_free (context->text, FALSE);
context->text = NULL;
if (g_strcmp0 (element_name, "name") == 0)
config->name = text;
else if (g_strcmp0 (element_name, "model") == 0)
config->rec->model = text;
else if (g_strcmp0 (element_name, "layouts") == 0)
parse_layouts (config->rec, text);
else if (g_strcmp0 (element_name, "options") == 0)
config->rec->options = g_strsplit (text, ",", -1);
}
static void
config_parser_text (GMarkupParseContext *pcontext,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error)
{
ConfigContext *context = user_data;
if (context->text)
context->text = g_string_append_len (context->text, text, text_len);
}
GMarkupParser config_parser = {
.start_element = config_parser_start_element,
.end_element = config_parser_end_element,
.text = config_parser_text
};
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
const gchar *env; const gchar *env;
gboolean use_clutter = USE_CLUTTER; gboolean use_clutter = USE_CLUTTER;
gboolean need_swap_event_workaround = FALSE;
gboolean accessibility_enabled = FALSE;
Eekboard *eekboard; Eekboard *eekboard;
GtkWidget *widget, *vbox, *menubar, *window; GtkWidget *widget, *vbox, *menubar, *window, *combo = NULL;
GOptionContext *context;
GConfClient *gconfc;
GError *error;
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);
if (opt_version) {
g_print ("eekboard %s\n", VERSION);
exit (0);
}
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, EEKBOARD_LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, EEKBOARD_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif #endif
error = NULL;
gconfc = gconf_client_get_default ();
if (gconf_client_get_bool (gconfc,
"/desktop/gnome/interface/accessibility",
&error) ||
gconf_client_get_bool (gconfc,
"/desktop/gnome/interface/accessibility2",
&error)) {
if (SPI_init () == 0)
accessibility_enabled = TRUE;
else
g_warning("AT-SPI initialization failed");
}
env = g_getenv ("EEKBOARD_DISABLE_CLUTTER"); env = g_getenv ("EEKBOARD_DISABLE_CLUTTER");
if (env && g_strcmp0 (env, "1") == 0) if (env && g_strcmp0 (env, "1") == 0)
use_clutter = FALSE; use_clutter = FALSE;
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
if (opt_toolkit) {
if (g_strcmp0 (opt_toolkit, "clutter") == 0)
use_clutter = TRUE;
else if (g_strcmp0 (opt_toolkit, "gtk") == 0)
use_clutter = FALSE;
else {
g_print ("Invalid toolkit \"%s\"\n", opt_toolkit);
exit (0);
}
}
if (use_clutter && if (use_clutter &&
gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) { gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
g_warning ("Can't init Clutter-Gtk...fallback to GTK"); g_warning ("Can't init Clutter-Gtk...fallback to GTK");
use_clutter = FALSE; use_clutter = FALSE;
} }
#ifdef NEED_SWAP_EVENT_WORKAROUND
if (use_clutter &&
clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) {
g_warning ("Enabling GLX_INTEL_swap_event workaround for Clutter-Gtk");
need_swap_event_workaround = TRUE;
}
#endif
#endif #endif
if (!use_clutter && !gtk_init_check (&argc, &argv)) { if (!use_clutter && !gtk_init_check (&argc, &argv)) {
@ -997,7 +1451,89 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); eekboard = eekboard_new (use_clutter,
need_swap_event_workaround,
accessibility_enabled);
if (opt_list_models) {
xkl_config_registry_foreach_model (eekboard->registry,
print_item,
NULL);
eekboard_free (eekboard);
exit (0);
}
if (opt_list_layouts) {
xkl_config_registry_foreach_layout (eekboard->registry,
print_layout,
NULL);
eekboard_free (eekboard);
exit (0);
}
if (opt_list_options) {
xkl_config_registry_foreach_option_group (eekboard->registry,
print_option_group,
NULL);
eekboard_free (eekboard);
exit (0);
}
if (opt_config) {
ConfigContext context;
GMarkupParseContext *pcontext;
GFile *file;
GError *error;
GFileInputStream *stream;
gchar buf[BUFSIZ];
GSList *head;
gint i;
memset (&context, 0, sizeof context);
file = g_file_new_for_path (opt_config);
error = NULL;
stream = g_file_read (file, NULL, &error);
if (!stream) {
eekboard_free (eekboard);
g_print ("Can't read configuration file: %s\n", opt_config);
exit (1);
}
pcontext = g_markup_parse_context_new (&config_parser,
0,
&context,
NULL);
while (1) {
gssize len;
error = NULL;
len = g_input_stream_read (G_INPUT_STREAM(stream),
buf, sizeof buf, NULL,
&error);
if (len <= 0)
break;
error = NULL;
if (!g_markup_parse_context_parse (pcontext, buf, len, &error))
break;
}
g_object_unref (stream);
error = NULL;
g_markup_parse_context_end_parse (pcontext, &error);
g_markup_parse_context_free (pcontext);
g_object_unref (file);
if (context.list) {
eekboard->config =
g_slice_alloc0 ((g_slist_length (context.list) + 1) *
sizeof (*eekboard->config));
for (i = 0, head = context.list; head; head = head->next)
eekboard->config[i++] = head->data;
}
}
window = gtk_window_new (opt_standalone ?
GTK_WINDOW_TOPLEVEL :
GTK_WINDOW_POPUP);
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");
@ -1006,13 +1542,39 @@ main (int argc, char *argv[])
vbox = gtk_vbox_new (FALSE, 0); vbox = gtk_vbox_new (FALSE, 0);
eekboard = eekboard_new (use_clutter);
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);
create_menus (eekboard, window); if (opt_standalone) {
menubar = gtk_ui_manager_get_widget (eekboard->ui_manager, "/MainMenu"); create_menus (eekboard, window);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); menubar = gtk_ui_manager_get_widget (eekboard->ui_manager, "/MainMenu");
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
}
if (eekboard->config) {
GtkListStore *store;
GtkTreeIter iter;
GtkCellRenderer *renderer;
int i;
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
for (i = 0; eekboard->config[i]; i++) {
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, eekboard->config[i]->name,
1, i,
-1);
}
combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo),
renderer, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(combo),
renderer, "text", 0, NULL);
gtk_box_pack_end (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
g_signal_connect (combo, "changed", G_CALLBACK(on_layout_changed),
eekboard);
}
gtk_container_add (GTK_CONTAINER(vbox), widget); gtk_container_add (GTK_CONTAINER(vbox), widget);
gtk_container_add (GTK_CONTAINER(window), vbox); gtk_container_add (GTK_CONTAINER(window), vbox);
@ -1021,6 +1583,69 @@ main (int argc, char *argv[])
gtk_widget_show_all (window); gtk_widget_show_all (window);
gtk_widget_set_size_request (widget, -1, -1); gtk_widget_set_size_request (widget, -1, -1);
notify_init ("eekboard");
eekboard->window = window;
eekboard->gconfc = gconfc;
if (eekboard->accessibility_enabled) {
if (!opt_standalone) {
NotifyNotification *notification;
error = NULL;
if (!gconf_client_get_bool (eekboard->gconfc,
"/apps/eekboard/inhibit-startup-notify",
&error)) {
notification = notify_notification_new
("eekboard started in background",
"As GNOME accessibility support enabled, "
"eekboard is starting without a window.\n"
"To make eekboard show up, click on some window with "
"an editable widget.",
"keyboard",
NULL);
notify_notification_add_action
(notification,
"dont-ask",
"Don't show up",
NOTIFY_ACTION_CALLBACK(on_notify_never_show),
eekboard,
NULL);
error = NULL;
notify_notification_show (notification, &error);
}
gtk_widget_hide (window);
focusListener =
SPI_createAccessibleEventListener (a11y_focus_listener,
eekboard);
SPI_registerGlobalEventListener (focusListener,
"object:state-changed:focused");
SPI_registerGlobalEventListener (focusListener,
"focus:");
}
/* monitor key events */
if (!keystrokeListener) {
keystrokeListener =
SPI_createAccessibleKeystrokeListener (a11y_keystroke_listener,
eekboard);
}
if (!SPI_registerAccessibleKeystrokeListener
(keystrokeListener,
SPI_KEYSET_ALL_KEYS,
0,
SPI_KEY_PRESSED |
SPI_KEY_RELEASED,
SPI_KEYLISTENER_NOSYNC))
g_warning ("failed to register keystroke listener");
}
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
if (combo)
gtk_combo_box_set_active (GTK_COMBO_BOX(combo), 0);
gtk_main (); gtk_main ();
return 0; return 0;

View File

@ -17,7 +17,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
*/ */
#include "eek.h" #include "eek/eek.h"
static void static void
test_create (void) test_create (void)

View File

@ -17,7 +17,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
*/ */
#include "eek-xkb.h" #include "eek/eek-xkb.h"
/* For gdk_x11_display_get_xdisplay(). See main(). */ /* For gdk_x11_display_get_xdisplay(). See main(). */
#include <gtk/gtk.h> #include <gtk/gtk.h>