Make fakekey and CSPI optional.

This commit is contained in:
Daiki Ueno
2011-02-02 06:48:49 +09:00
parent d2fc32f2a7
commit 56abc55bb2
8 changed files with 129 additions and 46 deletions

13
README
View File

@ -1,17 +1,14 @@
eekboard - an easy to use virtual keyboard library -*- outline -*- eekboard - an easy to use virtual keyboard toolkit -*- outline -*-
eekboard is a virtual keyboard software package, including a set of eekboard is a virtual keyboard software package, including a set of
tools to implement desktop virtual keyboard solutions. tools to implement desktop virtual keyboards.
* How to build * How to build
** Requirements ** Dependencies
* GLib2, GTK, GConf2, PangoCairo, libxklavier, libfakekey, CSPI REQUIRED: GLib2, GTK, GConf2, PangoCairo, libxklavier
* Clutter (optional) OPTIONAL: fakekey, CSPI, Clutter, Clutter-Gtk, Vala, gobject-introspection
* Clutter-Gtk (optional)
* Vala (optional)
* gobject-introspection (optional)
** Build from git repo ** Build from git repo

View File

@ -85,7 +85,7 @@ AM_CONDITIONAL([HAVE_GTK_2],[test "$with_gtk" = "2.0"])
AM_CONDITIONAL([HAVE_GTK_3],[test "$with_gtk" = "3.0"]) AM_CONDITIONAL([HAVE_GTK_3],[test "$with_gtk" = "3.0"])
AM_PATH_GLIB_2_0 AM_PATH_GLIB_2_0
PKG_CHECK_MODULES([GLIB2], [glib-2.0], , PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.25.4], ,
[AC_MSG_ERROR([GLib2 not found])]) [AC_MSG_ERROR([GLib2 not found])])
PKG_CHECK_MODULES([GIO2], [gio-2.0], , PKG_CHECK_MODULES([GIO2], [gio-2.0], ,
[AC_MSG_ERROR([Gio2 not found])]) [AC_MSG_ERROR([Gio2 not found])])
@ -101,10 +101,36 @@ PKG_CHECK_MODULES([XKB], [x11], ,
[AC_MSG_ERROR([XKB support not found])]) [AC_MSG_ERROR([XKB support not found])])
PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], , PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
[AC_MSG_ERROR([Libxklavier not found])]) [AC_MSG_ERROR([Libxklavier not found])])
PKG_CHECK_MODULES([LIBFAKEKEY], [libfakekey], ,
[AC_MSG_ERROR([libfakekey not found])]) dnl use libfakekey to generate key events
AC_MSG_CHECKING([whether you enable fakekey])
AC_ARG_ENABLE(fakekey,
AS_HELP_STRING([--enable-fakekey=no/yes],
[Enable fakekey default=yes]),,
enable_fakekey=yes)
if test x$enable_fakekey = xyes; then
PKG_CHECK_MODULES([FAKEKEY], [libfakekey], ,
[AC_MSG_ERROR([fakekey not found])])
AC_DEFINE([HAVE_FAKEKEY], [1], [Define if fakekey is found])
fi
AM_CONDITIONAL(ENABLE_FAKEKEY, [test x$enable_fakekey = xyes])
AC_MSG_RESULT($enable_fakekey)
dnl use AT-SPI to capture focus/keystroke events
AC_MSG_CHECKING([whether you enable AT-SPI event handling])
AC_ARG_ENABLE(cspi,
AS_HELP_STRING([--enable-cspi=no/yes],
[Enable AT-SPI event handling default=yes]),,
enable_cspi=yes)
if test x$enable_cspi = xyes; then
PKG_CHECK_MODULES([CSPI], [cspi-1.0], , PKG_CHECK_MODULES([CSPI], [cspi-1.0], ,
[AC_MSG_ERROR([AT-SPI C not found])]) [AC_MSG_ERROR([AT-SPI C not found])])
AC_DEFINE([HAVE_CSPI], [1], [Define if CSPI is found])
fi
AC_MSG_RESULT($enable_cspi)
AM_CONDITIONAL(ENABLE_CSPI, [test x$enable_cspi = xyes])
dnl Vala langauge binding dnl Vala langauge binding
AC_MSG_CHECKING([whether you enable Vala language support]) AC_MSG_CHECKING([whether you enable Vala language support])
@ -146,7 +172,7 @@ if test x$enable_clutter = xyes; then
AC_DEFINE_UNQUOTED([NEED_SWAP_EVENT_WORKAROUND], $need_swap_event_workaround, AC_DEFINE_UNQUOTED([NEED_SWAP_EVENT_WORKAROUND], $need_swap_event_workaround,
[Define if GLX_INTEL_swap_event work around is needed]) [Define if GLX_INTEL_swap_event work around is needed])
fi fi
AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes]) AM_CONDITIONAL(ENABLE_CLUTTER, [test x$enable_clutter = xyes])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
@ -162,7 +188,7 @@ AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR)
GOBJECT_INTROSPECTION_CHECK([0.6.7]) GOBJECT_INTROSPECTION_CHECK([0.6.7])
AC_CONFIG_HEADERS([eek/config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
eek/Makefile eek/Makefile
src/Makefile src/Makefile

View File

@ -104,7 +104,7 @@ GTKDOC_LIBS = $(top_srcdir)/eek/libeek.la \
$(GIO2_LIBS) \ $(GIO2_LIBS) \
$(XKB_LIBS) $(XKB_LIBS)
if HAVE_CLUTTER if ENABLE_CLUTTER
GTKDOC_LIBS += $(top_srcdir)/eek/libeek-clutter.la $(CLUTTER_LIBS) GTKDOC_LIBS += $(top_srcdir)/eek/libeek-clutter.la $(CLUTTER_LIBS)
endif endif

View File

@ -22,7 +22,7 @@ lib_LTLIBRARIES = \
libeek-xkb.la \ libeek-xkb.la \
libeek-xkl.la libeek-xkl.la
if HAVE_CLUTTER if ENABLE_CLUTTER
lib_LTLIBRARIES += libeek-clutter.la lib_LTLIBRARIES += libeek-clutter.la
endif endif
@ -86,7 +86,7 @@ libeek_la_SOURCES = \
libeek_la_CFLAGS = $(GIO2_CFLAGS) $(PANGOCAIRO_CFLAGS) libeek_la_CFLAGS = $(GIO2_CFLAGS) $(PANGOCAIRO_CFLAGS)
libeek_la_LIBADD = $(GIO2_LIBS) $(PANGOCAIRO_LIBS) -lm libeek_la_LIBADD = $(GIO2_LIBS) $(PANGOCAIRO_LIBS) -lm
if HAVE_CLUTTER if ENABLE_CLUTTER
libeek_clutter_public_headers = \ libeek_clutter_public_headers = \
$(srcdir)/eek-clutter-keyboard.h \ $(srcdir)/eek-clutter-keyboard.h \
$(srcdir)/eek-clutter.h $(srcdir)/eek-clutter.h
@ -178,7 +178,7 @@ pkgconfig_DATA = \
eek-xkb-$(EEK_API_VERSION).pc \ eek-xkb-$(EEK_API_VERSION).pc \
eek-xkl-$(EEK_API_VERSION).pc eek-xkl-$(EEK_API_VERSION).pc
if HAVE_CLUTTER if ENABLE_CLUTTER
pkgconfig_DATA += eek-clutter-$(EEK_API_VERSION).pc pkgconfig_DATA += eek-clutter-$(EEK_API_VERSION).pc
endif endif
@ -215,7 +215,7 @@ EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_gtk_la_CFLAGS)
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-gtk.la EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-gtk.la
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_gtk_sources) $(libeek_gtk_public_headers) EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_gtk_sources) $(libeek_gtk_public_headers)
if HAVE_CLUTTER if ENABLE_CLUTTER
EekClutter@EEK_LIBRARY_SUFFIX@.gir: libeek-clutter.la Eek@EEK_LIBRARY_SUFFIX@.gir EekClutter@EEK_LIBRARY_SUFFIX@.gir: libeek-clutter.la Eek@EEK_LIBRARY_SUFFIX@.gir
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek@EEK_LIBRARY_SUFFIX@ EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Clutter-1.0 Eek@EEK_LIBRARY_SUFFIX@
EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_clutter_la_CFLAGS) EekClutter@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_clutter_la_CFLAGS)
@ -241,7 +241,7 @@ INTROSPECTION_GIRS += \
EekXkb@EEK_LIBRARY_SUFFIX@.gir \ EekXkb@EEK_LIBRARY_SUFFIX@.gir \
EekXkl@EEK_LIBRARY_SUFFIX@.gir EekXkl@EEK_LIBRARY_SUFFIX@.gir
if HAVE_CLUTTER if ENABLE_CLUTTER
INTROSPECTION_GIRS += \ INTROSPECTION_GIRS += \
EekClutter@EEK_LIBRARY_SUFFIX@.gir EekClutter@EEK_LIBRARY_SUFFIX@.gir
endif endif

View File

@ -392,8 +392,10 @@ end_element_callback (GMarkupParseContext *pcontext,
if (g_strcmp0 (element_name, "keysym") == 0) { if (g_strcmp0 (element_name, "keysym") == 0) {
EekKeysym *keysym; EekKeysym *keysym;
if (data->keyval != EEK_INVALID_KEYSYM) if (data->keyval != EEK_INVALID_KEYSYM) {
keysym = eek_keysym_new (data->keyval); keysym = eek_keysym_new (data->keyval);
g_debug ("%u %s", data->keyval, eek_symbol_get_label (EEK_SYMBOL(keysym)));
}
else else
keysym = eek_keysym_new_from_name (text); keysym = eek_keysym_new_from_name (text);
data->symbols = g_slist_prepend (data->symbols, keysym); data->symbols = g_slist_prepend (data->symbols, keysym);

View File

@ -38,9 +38,7 @@ eekboard_system_client_CFLAGS = \
$(GTK_CFLAGS) \ $(GTK_CFLAGS) \
$(GCONF2_CFLAGS) \ $(GCONF2_CFLAGS) \
$(XKB_CFLAGS) \ $(XKB_CFLAGS) \
$(LIBXKLAVIER_CFLAGS) \ $(LIBXKLAVIER_CFLAGS)
$(LIBFAKEKEY_CFLAGS) \
$(CSPI_CFLAGS)
eekboard_system_client_LDADD = \ eekboard_system_client_LDADD = \
libeekboard.a \ libeekboard.a \
@ -50,9 +48,21 @@ eekboard_system_client_LDADD = \
$(GTK_LIBS) \ $(GTK_LIBS) \
$(GCONF2_LIBS) \ $(GCONF2_LIBS) \
$(XKB_LIBS) \ $(XKB_LIBS) \
$(LIBXKLAVIER_LIBS) \ $(LIBXKLAVIER_LIBS)
$(LIBFAKEKEY_LIBS) \
if ENABLE_FAKEKEY
eekboard_system_client_CFLAGS += \
$(FAKEKEY_CFLAGS)
eekboard_system_client_LDADD += \
$(FAKEKEY_LIBS)
endif
if ENABLE_CSPI
eekboard_system_client_CFLAGS += \
$(CSPI_CFLAGS)
eekboard_system_client_LDADD += \
$(CSPI_LIBS) $(CSPI_LIBS)
endif
eekboard_system_client_headers = system-client.h eekboard_system_client_headers = system-client.h
eekboard_system_client_SOURCES = system-client.c system-client-main.c eekboard_system_client_SOURCES = system-client.c system-client-main.c
@ -72,7 +82,7 @@ eekboard_server_LDADD = \
eekboard_server_headers = server.h eekboard_server_headers = server.h
eekboard_server_SOURCES = server.c server-main.c eekboard_server_SOURCES = server.c server-main.c
if HAVE_CLUTTER if ENABLE_CLUTTER
eekboard_server_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS) eekboard_server_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS)
eekboard_server_LDADD += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS) eekboard_server_LDADD += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
endif endif

View File

@ -5,19 +5,29 @@
#include "system-client.h" #include "system-client.h"
gboolean opt_keyboard = FALSE; gboolean opt_keyboard = FALSE;
#ifdef HAVE_CSPI
gboolean opt_focus = FALSE; gboolean opt_focus = FALSE;
gboolean opt_keystroke = FALSE; gboolean opt_keystroke = FALSE;
#endif /* HAVE_CSPI */
#ifdef HAVE_FAKEKEY
gboolean opt_fakekey = FALSE; gboolean opt_fakekey = FALSE;
#endif /* HAVE_FAKEKEY */
static const GOptionEntry options[] = { static const GOptionEntry options[] = {
{"listen-keyboard", 'k', 0, G_OPTION_ARG_NONE, &opt_keyboard, {"listen-keyboard", 'k', 0, G_OPTION_ARG_NONE, &opt_keyboard,
"Listen keyboard change events with libxklavier"}, "Listen keyboard change events with libxklavier"},
#ifdef HAVE_CSPI
{"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus, {"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
"Listen focus change events with AT-SPI"}, "Listen focus change events with AT-SPI"},
{"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke, {"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
"Listen keystroke events with AT-SPI"}, "Listen keystroke events with AT-SPI"},
#endif /* HAVE_CSPI */
#ifdef HAVE_FAKEKEY
{"generate-key-event", 'g', 0, G_OPTION_ARG_NONE, &opt_fakekey, {"generate-key-event", 'g', 0, G_OPTION_ARG_NONE, &opt_fakekey,
"Generate X key events with libfakekey"}, "Generate X key events with libfakekey"},
#endif /* HAVE_FAKEKEY */
{NULL} {NULL}
}; };
@ -49,6 +59,8 @@ main (int argc, char **argv)
client = eekboard_system_client_new (connection); client = eekboard_system_client_new (connection);
gconfc = gconf_client_get_default (); gconfc = gconf_client_get_default ();
#ifdef HAVE_CSPI
error = NULL; error = NULL;
if (opt_focus || opt_keystroke) { if (opt_focus || opt_keystroke) {
if (gconf_client_get_bool (gconfc, if (gconf_client_get_bool (gconfc,
@ -78,17 +90,21 @@ main (int argc, char **argv)
exit (1); exit (1);
} }
} }
#endif /* HAVE_CSPI */
if (opt_keyboard && if (opt_keyboard &&
!eekboard_system_client_enable_xkl (client)) { !eekboard_system_client_enable_xkl (client)) {
g_printerr ("Can't register xklavier event listeners\n"); g_printerr ("Can't register xklavier event listeners\n");
exit (1); exit (1);
} }
#ifdef HAVE_FAKEKEY
if (opt_fakekey && if (opt_fakekey &&
!eekboard_system_client_enable_fakekey (client)) { !eekboard_system_client_enable_fakekey (client)) {
g_printerr ("Can't init fakekey\n"); g_printerr ("Can't init fakekey\n");
exit (1); exit (1);
} }
#endif /* HAVE_FAKEKEY */
gtk_main (); gtk_main ();

View File

@ -15,15 +15,22 @@
* 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/>.
*/ */
#include <libxklavier/xklavier.h>
#include <cspi/spi.h>
#include <gdk/gdkx.h>
#include <fakekey/fakekey.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <libxklavier/xklavier.h>
#ifdef HAVE_CSPI
#include <cspi/spi.h>
#endif /* HAVE_CSPI */
#include <gdk/gdkx.h>
#ifdef HAVE_FAKEKEY
#include <fakekey/fakekey.h>
#endif /* HAVE_FAKEKEY */
#include "eek/eek.h" #include "eek/eek.h"
#include "eek/eek-xkl.h" #include "eek/eek-xkl.h"
#include "system-client.h" #include "system-client.h"
@ -49,7 +56,6 @@ struct _EekboardSystemClient {
GdkDisplay *display; GdkDisplay *display;
XklEngine *xkl_engine; XklEngine *xkl_engine;
XklConfigRegistry *xkl_config_registry; XklConfigRegistry *xkl_config_registry;
FakeKey *fakekey;
gulong xkl_config_changed_handler; gulong xkl_config_changed_handler;
gulong xkl_state_changed_handler; gulong xkl_state_changed_handler;
@ -57,8 +63,14 @@ struct _EekboardSystemClient {
gulong key_pressed_handler; gulong key_pressed_handler;
gulong key_released_handler; gulong key_released_handler;
#ifdef HAVE_CSPI
AccessibleEventListener *focus_listener; AccessibleEventListener *focus_listener;
AccessibleEventListener *keystroke_listener; AccessibleEventListener *keystroke_listener;
#endif /* HAVE_CSPI */
#ifdef HAVE_FAKEKEY
FakeKey *fakekey;
#endif /* HAVE_FAKEKEY */
}; };
struct _EekboardSystemClientClass { struct _EekboardSystemClientClass {
@ -81,12 +93,14 @@ static void on_xkl_state_changed
gboolean restore, gboolean restore,
gpointer user_data); gpointer user_data);
#ifdef HAVE_CSPI
static SPIBoolean focus_listener_cb (const AccessibleEvent *event, static SPIBoolean focus_listener_cb (const AccessibleEvent *event,
void *user_data); void *user_data);
static SPIBoolean keystroke_listener_cb static SPIBoolean keystroke_listener_cb
(const AccessibleKeystroke *stroke, (const AccessibleKeystroke *stroke,
void *user_data); void *user_data);
#endif /* HAVE_CSPI */
static void set_keyboard (EekboardSystemClient *client); static void set_keyboard (EekboardSystemClient *client);
static void static void
@ -122,18 +136,26 @@ eekboard_system_client_dispose (GObject *object)
EekboardSystemClient *client = EEKBOARD_SYSTEM_CLIENT(object); EekboardSystemClient *client = EEKBOARD_SYSTEM_CLIENT(object);
eekboard_system_client_disable_xkl (client); eekboard_system_client_disable_xkl (client);
#ifdef HAVE_CSPI
eekboard_system_client_disable_cspi_focus (client); eekboard_system_client_disable_cspi_focus (client);
eekboard_system_client_disable_cspi_keystroke (client); eekboard_system_client_disable_cspi_keystroke (client);
#endif /* HAVE_CSPI */
#ifdef HAVE_FAKEKEY
eekboard_system_client_disable_fakekey (client); eekboard_system_client_disable_fakekey (client);
#endif /* HAVE_FAKEKEY */
if (client->proxy) { if (client->proxy) {
g_object_unref (client->proxy); g_object_unref (client->proxy);
client->proxy = NULL; client->proxy = NULL;
} }
#ifdef HAVE_FAKEKEY
if (client->fakekey) { if (client->fakekey) {
client->fakekey = NULL; client->fakekey = NULL;
} }
#endif /* HAVE_FAKEKEY */
if (client->display) { if (client->display) {
gdk_display_close (client->display); gdk_display_close (client->display);
@ -169,14 +191,18 @@ eekboard_system_client_init (EekboardSystemClient *client)
client->display = NULL; client->display = NULL;
client->xkl_engine = NULL; client->xkl_engine = NULL;
client->xkl_config_registry = NULL; client->xkl_config_registry = NULL;
client->focus_listener = NULL;
client->keystroke_listener = NULL;
client->proxy = NULL; client->proxy = NULL;
client->fakekey = NULL;
client->key_pressed_handler = 0; client->key_pressed_handler = 0;
client->key_released_handler = 0; client->key_released_handler = 0;
client->xkl_config_changed_handler = 0; client->xkl_config_changed_handler = 0;
client->xkl_state_changed_handler = 0; client->xkl_state_changed_handler = 0;
#ifdef HAVE_CSPI
client->focus_listener = NULL;
client->keystroke_listener = NULL;
#endif /* HAVE_CSPI */
#ifdef HAVE_FAKEKEY
client->fakekey = NULL;
#endif /* HAVE_FAKEKEY */
} }
gboolean gboolean
@ -235,6 +261,7 @@ eekboard_system_client_disable_xkl (EekboardSystemClient *client)
client->xkl_state_changed_handler); client->xkl_state_changed_handler);
} }
#ifdef HAVE_CSPI
gboolean gboolean
eekboard_system_client_enable_cspi_focus (EekboardSystemClient *client) eekboard_system_client_enable_cspi_focus (EekboardSystemClient *client)
{ {
@ -292,14 +319,6 @@ eekboard_system_client_disable_cspi_keystroke (EekboardSystemClient *client)
} }
} }
EekboardSystemClient *
eekboard_system_client_new (GDBusConnection *connection)
{
return g_object_new (EEKBOARD_TYPE_SYSTEM_CLIENT,
"connection", connection,
NULL);
}
static SPIBoolean static SPIBoolean
focus_listener_cb (const AccessibleEvent *event, focus_listener_cb (const AccessibleEvent *event,
void *user_data) void *user_data)
@ -350,6 +369,15 @@ keystroke_listener_cb (const AccessibleKeystroke *stroke,
eekboard_proxy_release_key (client->proxy, stroke->keycode); eekboard_proxy_release_key (client->proxy, stroke->keycode);
return TRUE; return TRUE;
} }
#endif /* HAVE_CSPI */
EekboardSystemClient *
eekboard_system_client_new (GDBusConnection *connection)
{
return g_object_new (EEKBOARD_TYPE_SYSTEM_CLIENT,
"connection", connection,
NULL);
}
static GdkFilterReturn static GdkFilterReturn
filter_xkl_event (GdkXEvent *xev, filter_xkl_event (GdkXEvent *xev,
@ -371,8 +399,10 @@ on_xkl_config_changed (XklEngine *xklengine,
set_keyboard (client); set_keyboard (client);
#ifdef HAVE_FAKEKEY
if (client->fakekey) if (client->fakekey)
fakekey_reload_keysyms (client->fakekey); fakekey_reload_keysyms (client->fakekey);
#endif /* HAVE_FAKEKEY */
} }
static void static void
@ -413,6 +443,7 @@ on_xkl_state_changed (XklEngine *xklengine,
} }
} }
#ifdef HAVE_FAKEKEY
G_INLINE_FUNC FakeKeyModifier G_INLINE_FUNC FakeKeyModifier
get_fakekey_modifiers (EekModifierType modifiers) get_fakekey_modifiers (EekModifierType modifiers)
{ {
@ -519,3 +550,4 @@ eekboard_system_client_disable_fakekey (EekboardSystemClient *client)
g_signal_handler_disconnect (client->proxy, g_signal_handler_disconnect (client->proxy,
client->key_released_handler); client->key_released_handler);
} }
#endif /* HAVE_FAKEKEY */