Use at-spi2 instead of at-spi1.

This commit is contained in:
Daiki Ueno
2011-04-19 14:57:42 +09:00
parent ac8764b9b7
commit 926d9346e1
5 changed files with 182 additions and 140 deletions

View File

@ -117,20 +117,20 @@ fi
AM_CONDITIONAL(ENABLE_FAKEKEY, [test x$enable_fakekey = xyes]) AM_CONDITIONAL(ENABLE_FAKEKEY, [test x$enable_fakekey = xyes])
AC_MSG_RESULT($enable_fakekey) AC_MSG_RESULT($enable_fakekey)
dnl use AT-SPI to capture focus/keystroke events dnl use AT-SPI 2 to capture focus/keystroke events
AC_MSG_CHECKING([whether you enable AT-SPI event handling]) AC_MSG_CHECKING([whether you enable AT-SPI 2 event handling])
AC_ARG_ENABLE(cspi, AC_ARG_ENABLE(atspi,
AS_HELP_STRING([--enable-cspi=no/yes], AS_HELP_STRING([--enable-atspi=no/yes],
[Enable AT-SPI event handling default=no]),, [Enable AT-SPI 2 event handling default=no]),,
enable_cspi=no) enable_atspi=no)
if test x$enable_cspi = xyes; then if test x$enable_atspi = xyes; then
PKG_CHECK_MODULES([CSPI], [cspi-1.0 gconf-2.0], , PKG_CHECK_MODULES([ATSPI2], [atspi-2 dbus-glib-1], ,
[AC_MSG_ERROR([AT-SPI C not found])]) [AC_MSG_ERROR([AT-SPI 2 not found])])
AC_DEFINE([HAVE_CSPI], [1], [Define if CSPI is found]) AC_DEFINE([HAVE_ATSPI], [1], [Define if AT-SPI 2 is found])
fi fi
AC_MSG_RESULT($enable_cspi) AC_MSG_RESULT($enable_atspi)
AM_CONDITIONAL(ENABLE_CSPI, [test x$enable_cspi = xyes]) AM_CONDITIONAL(ENABLE_ATSPI, [test x$enable_atspi = xyes])
dnl Python language binding dnl Python language binding
AC_MSG_CHECKING([whether you enable Python language support]) AC_MSG_CHECKING([whether you enable Python language support])

View File

@ -49,11 +49,11 @@ eekboard_LDADD += \
$(FAKEKEY_LIBS) $(FAKEKEY_LIBS)
endif endif
if ENABLE_CSPI if ENABLE_ATSPI
eekboard_CFLAGS += \ eekboard_CFLAGS += \
$(CSPI_CFLAGS) $(ATSPI2_CFLAGS)
eekboard_LDADD += \ eekboard_LDADD += \
$(CSPI_LIBS) $(ATSPI2_LIBS)
endif endif
eekboard_headers = client.h eekboard_headers = client.h

View File

@ -20,10 +20,10 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
#include <cspi/spi.h> #include <dbus/dbus.h>
#include <gconf/gconf-client.h> #include <atspi/atspi.h>
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include "eekboard/eekboard.h" #include "eekboard/eekboard.h"
@ -56,12 +56,12 @@ static const GOptionEntry options[] = {
N_("Connect to the given D-Bus address")}, N_("Connect to the given D-Bus address")},
{"use-system-layout", 'x', 0, G_OPTION_ARG_NONE, &opt_use_system_layout, {"use-system-layout", 'x', 0, G_OPTION_ARG_NONE, &opt_use_system_layout,
N_("Use system keyboard layout")}, N_("Use system keyboard layout")},
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
{"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus, {"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
N_("Listen focus change events with AT-SPI")}, N_("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,
N_("Listen keystroke events with AT-SPI")}, N_("Listen keystroke events with AT-SPI")},
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
{"keyboard", 'k', 0, G_OPTION_ARG_STRING, &opt_keyboard, {"keyboard", 'k', 0, G_OPTION_ARG_STRING, &opt_keyboard,
N_("Specify keyboard")}, N_("Specify keyboard")},
{"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model, {"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model,
@ -117,9 +117,6 @@ main (int argc, char **argv)
GBusType bus_type; GBusType bus_type;
GDBusConnection *connection; GDBusConnection *connection;
GError *error; GError *error;
#ifdef HAVE_CSPI
GConfClient *gconfc;
#endif /* HAVE_CSPI */
GOptionContext *option_context; GOptionContext *option_context;
GMainLoop *loop; GMainLoop *loop;
@ -175,30 +172,24 @@ main (int argc, char **argv)
exit (1); exit (1);
} }
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
gconfc = gconf_client_get_default ();
error = NULL;
if (opt_focus || opt_keystroke) { if (opt_focus || opt_keystroke) {
if (gconf_client_get_bool (gconfc, GSettings *settings = g_settings_new ("org.gnome.desktop.interface");
"/desktop/gnome/interface/accessibility",
&error) || if (g_settings_get_boolean (settings, "toolkit-accessibility")) {
gconf_client_get_bool (gconfc, if (atspi_init () != 0) {
"/desktop/gnome/interface/accessibility2", g_printerr ("Can't init AT-SPI 2\n");
&error)) {
if (SPI_init () != 0) {
g_printerr ("Can't init CSPI\n");
exit (1); exit (1);
} }
if (opt_focus && if (opt_focus &&
!eekboard_client_enable_cspi_focus (client)) { !eekboard_client_enable_atspi_focus (client)) {
g_printerr ("Can't register focus change event listeners\n"); g_printerr ("Can't register focus change event listeners\n");
exit (1); exit (1);
} }
if (opt_keystroke && if (opt_keystroke &&
!eekboard_client_enable_cspi_keystroke (client)) { !eekboard_client_enable_atspi_keystroke (client)) {
g_printerr ("Can't register keystroke event listeners\n"); g_printerr ("Can't register keystroke event listeners\n");
exit (1); exit (1);
} }
@ -207,7 +198,7 @@ main (int argc, char **argv)
exit (1); exit (1);
} }
} }
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
if (opt_use_system_layout && (opt_keyboard || opt_model || opt_layouts || opt_options)) { if (opt_use_system_layout && (opt_keyboard || opt_model || opt_layouts || opt_options)) {
g_printerr ("Can't use --use-system-layout option with keyboard options\n"); g_printerr ("Can't use --use-system-layout option with keyboard options\n");

View File

@ -21,9 +21,10 @@
#include <libxklavier/xklavier.h> #include <libxklavier/xklavier.h>
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
#include <cspi/spi.h> #include <dbus/dbus.h>
#endif /* HAVE_CSPI */ #include <atspi/atspi.h>
#endif /* HAVE_ATSPI */
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
@ -67,11 +68,11 @@ struct _EekboardClient {
gulong key_pressed_handler; gulong key_pressed_handler;
gulong key_released_handler; gulong key_released_handler;
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
Accessible *acc; AtspiAccessible *acc;
AccessibleEventListener *focus_listener; gboolean follows_focus;
AccessibleEventListener *keystroke_listener; AtspiDeviceListener *keystroke_listener;
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
#ifdef HAVE_FAKEKEY #ifdef HAVE_FAKEKEY
FakeKey *fakekey; FakeKey *fakekey;
@ -84,36 +85,33 @@ struct _EekboardClientClass {
G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_OBJECT); G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_OBJECT);
static GdkFilterReturn filter_xkl_event (GdkXEvent *xev, static GdkFilterReturn filter_xkl_event (GdkXEvent *xev,
GdkEvent *event, GdkEvent *event,
gpointer user_data); gpointer user_data);
static void on_xkl_config_changed static void on_xkl_config_changed (XklEngine *xklengine,
(XklEngine *xklengine, gpointer user_data);
gpointer user_data);
static void on_xkl_state_changed static void on_xkl_state_changed (XklEngine *xklengine,
(XklEngine *xklengine, XklEngineStateChange type,
XklEngineStateChange type, gint value,
gint value, gboolean restore,
gboolean restore, gpointer user_data);
gpointer user_data);
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
static SPIBoolean focus_listener_cb (const AccessibleEvent *event, static void focus_listener_cb (const AtspiEvent *event,
void *user_data); void *user_data);
static SPIBoolean keystroke_listener_cb static gboolean keystroke_listener_cb (const AtspiDeviceEvent *stroke,
(const AccessibleKeystroke *stroke, void *user_data);
void *user_data); #endif /* HAVE_ATSPI */
#endif /* HAVE_CSPI */ static gboolean set_keyboard (EekboardClient *client,
static gboolean set_keyboard (EekboardClient *client, gboolean show,
gboolean show, EekLayout *layout);
EekLayout *layout); static gboolean set_xkl_keyboard (EekboardClient *client,
static gboolean set_xkl_keyboard (EekboardClient *client, gboolean show,
gboolean show, const gchar *model,
const gchar *model, const gchar *layouts,
const gchar *layouts, const gchar *options);
const gchar *options);
static void static void
eekboard_client_set_property (GObject *object, eekboard_client_set_property (GObject *object,
@ -181,10 +179,10 @@ eekboard_client_dispose (GObject *object)
eekboard_client_disable_xkl (client); eekboard_client_disable_xkl (client);
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
eekboard_client_disable_cspi_focus (client); eekboard_client_disable_atspi_focus (client);
eekboard_client_disable_cspi_keystroke (client); eekboard_client_disable_atspi_keystroke (client);
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
#ifdef HAVE_FAKEKEY #ifdef HAVE_FAKEKEY
eekboard_client_disable_fakekey (client); eekboard_client_disable_fakekey (client);
@ -274,10 +272,10 @@ eekboard_client_init (EekboardClient *client)
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 #ifdef HAVE_ATSPI
client->focus_listener = NULL; client->follows_focus = FALSE;
client->keystroke_listener = NULL; client->keystroke_listener = NULL;
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
#ifdef HAVE_FAKEKEY #ifdef HAVE_FAKEKEY
client->fakekey = NULL; client->fakekey = NULL;
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_FAKEKEY */
@ -289,9 +287,9 @@ eekboard_client_set_xkl_config (EekboardClient *client,
const gchar *layouts, const gchar *layouts,
const gchar *options) const gchar *options)
{ {
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
return set_xkl_keyboard (client, return set_xkl_keyboard (client,
client->focus_listener ? FALSE : TRUE, !client->follows_focus,
model, model,
layouts, layouts,
options); options);
@ -340,9 +338,9 @@ eekboard_client_enable_xkl (EekboardClient *client)
xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
return set_xkl_keyboard (client, return set_xkl_keyboard (client,
client->focus_listener ? FALSE : TRUE, !client->follows_focus,
NULL, NULL,
NULL, NULL,
NULL); NULL);
@ -366,80 +364,135 @@ eekboard_client_disable_xkl (EekboardClient *client)
client->xkl_state_changed_handler); client->xkl_state_changed_handler);
} }
#ifdef HAVE_CSPI #ifdef HAVE_ATSPI
gboolean gboolean
eekboard_client_enable_cspi_focus (EekboardClient *client) eekboard_client_enable_atspi_focus (EekboardClient *client)
{ {
client->focus_listener = SPI_createAccessibleEventListener GError *error;
((AccessibleEventListenerCB)focus_listener_cb,
client);
if (!SPI_registerGlobalEventListener (client->focus_listener, error = NULL;
"object:state-changed:focused")) if (!atspi_event_listener_register_from_callback
((AtspiEventListenerCB)focus_listener_cb,
client,
NULL,
"object:state-changed:focused",
&error))
return FALSE; return FALSE;
if (!SPI_registerGlobalEventListener (client->focus_listener, error = NULL;
"focus:")) if (!atspi_event_listener_register_from_callback
((AtspiEventListenerCB)focus_listener_cb,
client,
NULL,
"focus:",
&error))
return FALSE; return FALSE;
client->follows_focus = TRUE;
return TRUE; return TRUE;
} }
void void
eekboard_client_disable_cspi_focus (EekboardClient *client) eekboard_client_disable_atspi_focus (EekboardClient *client)
{ {
if (client->focus_listener) { GError *error;
SPI_deregisterGlobalEventListenerAll (client->focus_listener);
AccessibleEventListener_unref (client->focus_listener); client->follows_focus = FALSE;
client->focus_listener = NULL;
} error = NULL;
atspi_event_listener_deregister_from_callback
((AtspiEventListenerCB)focus_listener_cb,
client,
"object:state-changed:focused",
&error);
error = NULL;
atspi_event_listener_deregister_from_callback
((AtspiEventListenerCB)focus_listener_cb,
client,
"focus:",
&error);
} }
gboolean gboolean
eekboard_client_enable_cspi_keystroke (EekboardClient *client) eekboard_client_enable_atspi_keystroke (EekboardClient *client)
{ {
GError *error;
client->keystroke_listener = client->keystroke_listener =
SPI_createAccessibleKeystrokeListener (keystroke_listener_cb, atspi_device_listener_new ((AtspiDeviceListenerCB)keystroke_listener_cb,
client); NULL,
client);
if (!SPI_registerAccessibleKeystrokeListener error = NULL;
if (!atspi_register_keystroke_listener
(client->keystroke_listener, (client->keystroke_listener,
SPI_KEYSET_ALL_KEYS, NULL,
0, 0,
SPI_KEY_PRESSED | ATSPI_KEY_PRESSED,
SPI_KEY_RELEASED, ATSPI_KEYLISTENER_NOSYNC,
SPI_KEYLISTENER_NOSYNC)) &error))
return FALSE;
error = NULL;
if (!atspi_register_keystroke_listener
(client->keystroke_listener,
NULL,
0,
ATSPI_KEY_RELEASED,
ATSPI_KEYLISTENER_NOSYNC,
&error))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
void void
eekboard_client_disable_cspi_keystroke (EekboardClient *client) eekboard_client_disable_atspi_keystroke (EekboardClient *client)
{ {
if (client->keystroke_listener) { if (client->keystroke_listener) {
SPI_deregisterAccessibleKeystrokeListener (client->keystroke_listener, GError *error;
0);
AccessibleKeystrokeListener_unref (client->keystroke_listener); error = NULL;
atspi_deregister_keystroke_listener (client->keystroke_listener,
NULL,
0,
ATSPI_KEY_PRESSED,
&error);
error = NULL;
atspi_deregister_keystroke_listener (client->keystroke_listener,
NULL,
0,
ATSPI_KEY_RELEASED,
&error);
g_object_unref (client->keystroke_listener);
client->keystroke_listener = NULL; client->keystroke_listener = NULL;
} }
} }
static SPIBoolean static void
focus_listener_cb (const AccessibleEvent *event, focus_listener_cb (const AtspiEvent *event,
void *user_data) void *user_data)
{ {
EekboardClient *client = user_data; EekboardClient *client = user_data;
Accessible *accessible = event->source; AtspiAccessible *accessible = event->source;
AccessibleStateSet *state_set = Accessible_getStateSet (accessible); AtspiStateSet *state_set = atspi_accessible_get_state_set (accessible);
AccessibleRole role = Accessible_getRole (accessible); AtspiRole role;
GError *error;
if (AccessibleStateSet_contains (state_set, SPI_STATE_EDITABLE) || error = NULL;
role == SPI_ROLE_TERMINAL) { role = atspi_accessible_get_role (accessible, &error);
if (error)
return;
if (atspi_state_set_contains (state_set, ATSPI_STATE_EDITABLE) ||
role == ATSPI_ROLE_TERMINAL) {
switch (role) { switch (role) {
case SPI_ROLE_TEXT: case ATSPI_ROLE_TEXT:
case SPI_ROLE_PARAGRAPH: case ATSPI_ROLE_PARAGRAPH:
case SPI_ROLE_PASSWORD_TEXT: case ATSPI_ROLE_PASSWORD_TEXT:
case SPI_ROLE_TERMINAL: case ATSPI_ROLE_TERMINAL:
if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) { if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
client->acc = accessible; client->acc = accessible;
eekboard_context_show_keyboard (client->context, NULL); eekboard_context_show_keyboard (client->context, NULL);
@ -448,7 +501,7 @@ focus_listener_cb (const AccessibleEvent *event,
eekboard_context_hide_keyboard (client->context, NULL); eekboard_context_hide_keyboard (client->context, NULL);
} }
break; break;
case SPI_ROLE_ENTRY: case ATSPI_ROLE_ENTRY:
if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) { if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
client->acc = accessible; client->acc = accessible;
eekboard_context_show_keyboard (client->context, NULL); eekboard_context_show_keyboard (client->context, NULL);
@ -464,13 +517,11 @@ focus_listener_cb (const AccessibleEvent *event,
} else { } else {
eekboard_context_hide_keyboard (client->context, NULL); eekboard_context_hide_keyboard (client->context, NULL);
} }
return FALSE;
} }
static SPIBoolean static gboolean
keystroke_listener_cb (const AccessibleKeystroke *stroke, keystroke_listener_cb (const AtspiDeviceEvent *stroke,
void *user_data) void *user_data)
{ {
EekboardClient *client = user_data; EekboardClient *client = user_data;
EekKey *key; EekKey *key;
@ -478,22 +529,22 @@ keystroke_listener_cb (const AccessibleKeystroke *stroke,
/* Ignore modifiers since the keystroke listener does not called /* Ignore modifiers since the keystroke listener does not called
when a modifier key is released. */ when a modifier key is released. */
key = eek_keyboard_find_key_by_keycode (client->keyboard, key = eek_keyboard_find_key_by_keycode (client->keyboard,
stroke->keycode); stroke->hw_code);
if (key) { if (key) {
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0); EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (symbol && eek_symbol_is_modifier (symbol)) if (symbol && eek_symbol_is_modifier (symbol))
return FALSE; return FALSE;
} }
if (stroke->type == SPI_KEY_PRESSED) { if (stroke->type == ATSPI_KEY_PRESSED) {
eekboard_context_press_key (client->context, stroke->keycode, NULL); eekboard_context_press_key (client->context, stroke->hw_code, NULL);
} else { } else {
eekboard_context_release_key (client->context, stroke->keycode, NULL); eekboard_context_release_key (client->context, stroke->hw_code, NULL);
} }
return TRUE; return TRUE;
} }
#endif /* HAVE_CSPI */ #endif /* HAVE_ATSPI */
EekboardClient * EekboardClient *
eekboard_client_new (GDBusConnection *connection) eekboard_client_new (GDBusConnection *connection)
@ -759,7 +810,7 @@ eekboard_client_load_keyboard_from_file (EekboardClient *client,
layout = eek_xml_layout_new (G_INPUT_STREAM(input)); layout = eek_xml_layout_new (G_INPUT_STREAM(input));
g_object_unref (input); g_object_unref (input);
retval = set_keyboard (client, TRUE, layout); retval = set_keyboard (client, !client->follows_focus, layout);
g_object_unref (layout); g_object_unref (layout);
return retval; return retval;
} }

View File

@ -44,14 +44,14 @@ gboolean eekboard_client_set_xkl_config (EekboardClient *client,
gboolean eekboard_client_enable_xkl (EekboardClient *client); gboolean eekboard_client_enable_xkl (EekboardClient *client);
void eekboard_client_disable_xkl (EekboardClient *client); void eekboard_client_disable_xkl (EekboardClient *client);
gboolean eekboard_client_enable_cspi_focus gboolean eekboard_client_enable_atspi_focus
(EekboardClient *client); (EekboardClient *client);
void eekboard_client_disable_cspi_focus void eekboard_client_disable_atspi_focus
(EekboardClient *client); (EekboardClient *client);
gboolean eekboard_client_enable_cspi_keystroke gboolean eekboard_client_enable_atspi_keystroke
(EekboardClient *client); (EekboardClient *client);
void eekboard_client_disable_cspi_keystroke void eekboard_client_disable_atspi_keystroke
(EekboardClient *client); (EekboardClient *client);
gboolean eekboard_client_enable_fakekey (EekboardClient *client); gboolean eekboard_client_enable_fakekey (EekboardClient *client);