}
/**
++<<<<<<< HEAD
+ * atspi_component_scroll_to:
+ * @obj: a pointer to the #AtspiComponent object on which to operate.
+ * @type: a #AtspiScrollType indicating where the object should be placed on the
+ * screen.
+ *
+ * Scrolls whatever container of the #AtspiComponent object so it becomes
+ * visible on the screen.
+ *
+ * Returns: #TRUE if successful, #FALSE otherwise.
+ **/
+gboolean
+atspi_component_scroll_to (AtspiComponent *obj,
+ AtspiScrollType type,
+ GError **error)
+{
+ dbus_bool_t retval = FALSE;
+
+ g_return_val_if_fail (obj != NULL, FALSE);
+
+ _atspi_dbus_call (obj, atspi_interface_component,
+ "ScrollTo", error, "u=>b", type, &retval);
+
+ return retval;
+}
+
+/**
+ * atspi_component_scroll_to_point:
+ * @obj: a pointer to the #AtspiComponent object on which to operate.
+ * @coords: a #AtspiCoordType indicating whether the coordinates are relative to
+ * the screen, to the window, or to the parent object.
+ * @x: the x coordinate of the point to reach
+ * @y: the y coordinate of the point to reach
+ * @error: return location for a #GError
+ *
+ * Scrolls whatever container of the #AtspiComponent object so it becomes
+ * visible on the screen at a given position.
+ *
+ * Returns: #TRUE if successful, #FALSE otherwise.
+ **/
+gboolean
+atspi_component_scroll_to_point (AtspiComponent *obj,
+ AtspiCoordType coords,
+ gint x,
+ gint y,
+ GError **error)
+{
+ dbus_bool_t retval = FALSE;
+
+ g_return_val_if_fail (obj != NULL, FALSE);
+
+ _atspi_dbus_call (obj, atspi_interface_component,
+ "ScrollToPoint", error, "uii=>b", coords, x, y, &retval);
+
+ return retval;
+}
+
++/**
+ * atspi_component_get_highlight_index
+ * @obj: a pointer to the #AtspiComponent to query.
+ *
+ * Returns: highlight index of object if (>0), 0 if highlight index is not set
+ * or -1 if an error occured.
+ **/
+ int
+ atspi_component_get_highlight_index (AtspiComponent *obj, GError **error)
+ {
+ gint ret = -1;
+ g_return_val_if_fail (obj != NULL, -1);
+ _atspi_dbus_get_property (obj, atspi_interface_component,
+ "HighlightIndex", error, "i", &ret);
+ return ret;
+ }
+
static void
atspi_component_base_init (AtspiComponent *klass)
{
gboolean atspi_component_set_size (AtspiComponent *obj, gint width, gint height, GError **error);
+gboolean atspi_component_scroll_to (AtspiComponent *obj, AtspiScrollType type, GError **error);
+
+gboolean atspi_component_scroll_to_point (AtspiComponent *obj, AtspiCoordType coords, gint x, gint y, GError **error);
+
+ gboolean atspi_component_grab_highlight (AtspiComponent *obj, GError **error);
+
+ gboolean atspi_component_clear_highlight (AtspiComponent *obj, GError **error);
+
+ int atspi_component_get_highlight_index(AtspiComponent *obj, GError **error);
+
G_END_DECLS
#endif /* _ATSPI_COMPONENT_H_ */
typedef enum {
ATSPI_COORD_TYPE_SCREEN,
ATSPI_COORD_TYPE_WINDOW,
+ ATSPI_COORD_TYPE_PARENT,
} AtspiCoordType;
+ typedef enum {
+ ATSPI_NEIGHBOR_SEARCH_FORWARD = 1,
+ ATSPI_NEIGHBOR_SEARCH_BACKWARD = 2,
+ } AtspiNeighborSearchDirection;
+
/**
* ATSPI_COORD_TYPE_COUNT:
*
GDBusConnection *session_bus;
GSettings *a11y_schema;
GSettings *interface_schema;
+ int name_owner_id;
+ A11yBusClient screen_reader;
+ A11yBusClient universal_switch;
+
GDBusProxy *client_proxy;
A11yBusState state;
app->a11y_launch_error_message = g_strdup_printf ("Bus stopped by signal %d", WSTOPSIG (status));
}
g_main_loop_quit (app->loop);
- }
+ }
+#ifdef DBUS_DAEMON
+static void
+setup_bus_child_daemon (gpointer data)
+{
+ A11yBusLauncher *app = data;
+ (void) app;
+
+ close (app->pipefd[0]);
+ dup2 (app->pipefd[1], 3);
+ close (app->pipefd[1]);
+
+ /* On Linux, tell the bus process to exit if this process goes away */
+#ifdef __linux__
+ prctl (PR_SET_PDEATHSIG, 15);
+#endif
+}
+
static gboolean
-ensure_a11y_bus (A11yBusLauncher *app)
+ensure_a11y_bus_daemon (A11yBusLauncher *app, char *config_path)
{
+ char *argv[] = { DBUS_DAEMON, config_path, "--nofork", "--print-address", "3", NULL };
GPid pid;
- char *argv[] = { DBUS_DAEMON, NULL, "--nofork", "--print-address", "3", NULL };
char addr_buf[2048];
GError *error = NULL;
- const char *config_path = NULL;
- if (g_file_test (SYSCONFDIR"/at-spi2/accessibility.conf", G_FILE_TEST_EXISTS))
- config_path = "--config-file="SYSCONFDIR"/at-spi2/accessibility.conf";
- else
- config_path = "--config-file="DATADIR"/defaults/at-spi2/accessibility.conf";
-
+ if (app->a11y_bus_pid != 0)
+ return FALSE;
+
+ argv[1] = (char*)config_path;
+
if (pipe (app->pipefd) < 0)
g_error ("Failed to create pipe: %s", strerror (errno));
/* Trim the trailing newline */
app->a11y_bus_address = g_strchomp (g_strdup (addr_buf));
- g_debug ("a11y bus address: %s", app->a11y_bus_address);
+ LOGD("a11y bus address: %s", app->a11y_bus_address);
+ return TRUE;
+
+error:
+ close (app->pipefd[0]);
+ close (app->pipefd[1]);
+ app->state = A11Y_BUS_STATE_ERROR;
+
+ return FALSE;
+}
+#else
+static gboolean
+ensure_a11y_bus_daemon (A11yBusLauncher *app, char *config_path)
+{
+ return FALSE;
+}
+#endif
+
+#ifdef DBUS_BROKER
+static void
+setup_bus_child_broker (gpointer data)
+{
+ A11yBusLauncher *app = data;
+ gchar *pid_str;
+ (void) app;
+
+ dup2 (app->listenfd, 3);
+ close (app->listenfd);
+ g_setenv("LISTEN_FDS", "1", TRUE);
+
+ pid_str = g_strdup_printf("%u", getpid());
+ g_setenv("LISTEN_PID", pid_str, TRUE);
+ g_free(pid_str);
+
+ /* Tell the bus process to exit if this process goes away */
+ prctl (PR_SET_PDEATHSIG, SIGTERM);
+}
+
+static gboolean
+ensure_a11y_bus_broker (A11yBusLauncher *app, char *config_path)
+{
+ char *argv[] = { DBUS_BROKER, config_path, "--scope", "user", NULL };
+ struct sockaddr_un addr = { .sun_family = AF_UNIX };
+ socklen_t addr_len = sizeof(addr);
+ GPid pid;
+ GError *error = NULL;
+
+ if ((app->listenfd = socket (PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0)
+ g_error ("Failed to create listening socket: %s", strerror (errno));
+
+ if (bind (app->listenfd, (struct sockaddr *)&addr, sizeof(sa_family_t)) < 0)
+ g_error ("Failed to bind listening socket: %s", strerror (errno));
+
+ if (getsockname (app->listenfd, (struct sockaddr *)&addr, &addr_len) < 0)
+ g_error ("Failed to get socket name for listening socket: %s", strerror(errno));
+
+ if (listen (app->listenfd, 1024) < 0)
+ g_error ("Failed to listen on socket: %s", strerror(errno));
+
+ g_clear_pointer (&app->a11y_launch_error_message, g_free);
+
+ if (!g_spawn_async (NULL,
+ argv,
+ NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+ setup_bus_child_broker,
+ app,
+ &pid,
+ &error))
+ {
+ app->a11y_bus_pid = -1;
+ app->a11y_launch_error_message = g_strdup (error->message);
+ g_clear_error (&error);
+ goto error;
+ }
+
+ close (app->listenfd);
+ app->listenfd = -1;
+
+ g_child_watch_add (pid, on_bus_exited, app);
+ app->a11y_bus_pid = pid;
+ g_debug ("Launched a11y bus, child is %ld", (long) pid);
+ app->state = A11Y_BUS_STATE_RUNNING;
+
+ app->a11y_bus_address = g_strconcat("unix:abstract=", addr.sun_path + 1, NULL);
+ g_debug ("a11y bus address: %s", app->a11y_bus_address);
+
+ return TRUE;
+
+error:
+ close (app->listenfd);
+ app->state = A11Y_BUS_STATE_ERROR;
+
+ return FALSE;
+}
+#else
+static gboolean
+ensure_a11y_bus_broker (A11yBusLauncher *app, char *config_path)
+{
+ return FALSE;
+}
+#endif
+
+static gboolean
+ensure_a11y_bus (A11yBusLauncher *app)
+{
+ char *config_path = NULL;
+ gboolean success = FALSE;
+
+ if (app->a11y_bus_pid != 0)
+ return FALSE;
+
+ if (g_file_test (SYSCONFDIR"/at-spi2/accessibility.conf", G_FILE_TEST_EXISTS))
+ config_path = "--config-file="SYSCONFDIR"/at-spi2/accessibility.conf";
+ else
+ config_path = "--config-file="DATADIR"/defaults/at-spi2/accessibility.conf";
+
+#ifdef WANT_DBUS_BROKER
+ success = ensure_a11y_bus_broker (app, config_path);
+ if (!success)
+ {
+ if (!ensure_a11y_bus_daemon (app, config_path))
+ return FALSE;
+ }
+#else
+ success = ensure_a11y_bus_daemon (app, config_path);
+ if (!success)
+ {
+ if (!ensure_a11y_bus_broker (app, config_path))
+ return FALSE;
+ }
+#endif
+
#ifdef HAVE_X11
{
Display *display = XOpenDisplay (NULL);
main (int argc,
char **argv)
{
+ #ifdef ATSPI_BUS_LAUNCHER_LOG_TO_FILE
+ log_file = fopen("/tmp/at-spi-bus-launcher.log", "a");
+ #endif
+
+ LOGD("Starting atspi bus launcher");
++
gboolean a11y_set = FALSE;
gboolean screen_reader_set = FALSE;
gint i;
executable('at-spi-bus-launcher', 'at-spi-bus-launcher.c',
include_directories: [ root_inc, include_directories('.') ],
-- dependencies: [ gio_dep, x11_deps ],
- c_args: [
- '-DSYSCONFDIR="@0@"'.format(atspi_sysconfdir),
- '-DDATADIR="@0@"'.format(atspi_datadir),
- '-DDBUS_DAEMON="@0@"'.format(dbus_daemon),
- ],
++ dependencies: [ gio_dep, x11_deps, app_svc_dep ],
+ c_args: launcher_args,
install: true,
install_dir: atspi_libexecdir)
glib_req_version = '>= 2.32.0'
gobject_req_version = '>= 2.0.0'
gio_req_version = '>= 2.28.0'
++app_svc_req_version = '>= 0.0.0'
libdbus_dep = dependency('dbus-1', version: libdbus_req_version)
glib_dep = dependency('glib-2.0', version: glib_req_version)
gobject_dep = dependency('gobject-2.0', version: gobject_req_version)
gio_dep = dependency('gio-2.0', version: gio_req_version)
++app_svc_dep = dependency('appsvc', version: app_svc_req_version)
dl_dep = cc.find_library('dl', required: false)
x11_deps = []
--- /dev/null
-Version: 2.26.1
+ %bcond_with x
+
+ Name: at-spi2-core
-Source: http://ftp.gnome.org/pub/GNOME/sources/at-spi2-core/2.26/%{name}-%{version}.tar.xz
++Version: 2.31.1
+ Release: 0
+ Summary: Assistive Technology Service Provider Interface - D-Bus based implementation
+ License: LGPL-2.0+
+ Group: System/Libraries
+ Url: http://www.gnome.org/
-%autogen --libexecdir=%{_libexecdir}/at-spi2 \
- --with-dbus-daemondir=%{_bindir} \
++Source: http://ftp.gnome.org/pub/GNOME/sources/at-spi2-core/2.31/%{name}-%{version}.tar.xz
+ Source1001: %{name}.manifest
+ Requires: dbus
+ BuildRequires: python-devel
+ BuildRequires: python-xml
+ BuildRequires: intltool
+ BuildRequires: dbus-devel
+ BuildRequires: glib2-devel
+ BuildRequires: gettext
+ BuildRequires: gtk-doc
+ %if %{with x}
+ BuildRequires: libX11-devel
+ BuildRequires: libXtst-devel
+ BuildRequires: libXi-devel
+ %endif
+ BuildRequires: pkgconfig(vconf)
+ BuildRequires: pkgconfig(appsvc)
+ BuildRequires: pkgconfig(dlog)
+ BuildRequires: pkgconfig(aul)
+ BuildRequires: gobject-introspection
++BuildRequires: meson
++BuildRequires: app-svc-devel
+
+ %description
+ AT-SPI is a general interface for applications to make use of the
+ accessibility toolkit. This version is based on dbus.
+
+ This package contains the AT-SPI registry daemon. It provides a
+ mechanism for all assistive technologies to discover and interact
+ with applications running on the desktop.
+
+ %package -n libatspi0
+ Summary: An Accessibility ToolKit -- Library
+ Group: System/Libraries
+
+ %description -n libatspi0
+ AT-SPI is a general interface for applications to make use of the
+ accessibility toolkit. This version is based on dbus.
+
+ %package -n typelib-1_0-Atspi-2_0
+ Summary: An Accessibility ToolKit -- Introspection bindings
+ Group: System/Libraries
+
+ %description -n typelib-1_0-Atspi-2_0
+ AT-SPI is a general interface for applications to make use of the
+ accessibility toolkit. This version is based on dbus.
+
+ This package provides the GObject Introspection bindings for the
+ libatspi library.
+
+ %package devel
+ Summary: Include Files and Libraries mandatory for Development
+ Group: Development/Libraries
+ Requires: %{name} = %{version}
+ Requires: libatspi0 = %{version}
+ Requires: typelib-1_0-Atspi-2_0 = %{version}
+
+ %description devel
+ This package contains all necessary include files and libraries needed
+ to develop applications that require these.
+
+ %prep
+ %setup -q
+ cp %{SOURCE1001} .
+
+ %build
- --disable-x11 \
++meson build -Dwith-dbus-daemondir=%{_bindir} \
+ %if !%{with x}
- --disable-static
-%__make %{?_smp_flags}
++ -Denable-x11=no \
++%else
++ -Denable-x11=yes \
+ %endif
-rm -rf %{buildroot}
++ -Denable-static=no
++
++(cd build && ninja)
+
+ %install
-%make_install
+ find %{buildroot} -name '*.la' -or -name '*.a' | xargs rm -f
+
-%{_bindir}/at_spi2_tool
++(cd build && DESTDIR=%{buildroot} ninja install)
+ %find_lang %{name}
+
+ %clean
+ rm -fr %{buildroot}
+
+ %post -n libatspi0 -p /sbin/ldconfig
+
+ %postun -n libatspi0 -p /sbin/ldconfig
+
+ %files -f %{name}.lang
+ %manifest %{name}.manifest
+ %defattr(-,root,root)
-%{_libexecdir}/at-spi2/at-spi-bus-launcher
-%{_libexecdir}/at-spi2/at-spi2-registryd
-%{_datadir}/defaults/at-spi2/accessibility.conf
-%{_sysconfdir}/xdg/autostart/at-spi-dbus-bus.desktop
-%{_datadir}/dbus-1/accessibility-services/org.a11y.atspi.Registry.service
-%{_datadir}/dbus-1/services/org.a11y.Bus.service
-%{_prefix}/lib/systemd/user/at-spi-dbus-bus.service
++/usr/local/libexec/at_spi2_tool
+
+ %doc AUTHORS README
+ %license COPYING
-%{_libdir}/libatspi.so.0*
++/usr/local/libexec/at-spi-bus-launcher
++/usr/local/libexec/at-spi2-registryd
++/usr/local/share/defaults/at-spi2/accessibility.conf
++/usr/local/etc/xdg/autostart/at-spi-dbus-bus.desktop
++/usr/local/share/dbus-1/accessibility-services/org.a11y.atspi.Registry.service
++/usr/local/share/dbus-1/services/org.a11y.Bus.service
++/usr/local/lib/systemd/user/at-spi-dbus-bus.service
+ %files -n libatspi0
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
-%{_includedir}/at-spi-2.0
-%{_libdir}/libatspi.so
-%{_libdir}/pkgconfig/atspi-2.pc
++/usr/local/lib/libatspi.so.0*
+
+ %files -n typelib-1_0-Atspi-2_0
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
+
+ %files devel
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
++/usr/local/include/at-spi-2.0
++/usr/local/lib/libatspi.so
++/usr/local/lib/pkgconfig/atspi-2.pc
executable('memory', 'memory.c',
include_directories: root_inc,
dependencies: [ atspi_dep ]))
++
++at_spi2_tool_sources = [
++ 'at_spi2_tool.c'
++]
++
++executable('at_spi2_tool', at_spi2_tool_sources,
++ dependencies: [ atspi_dep, gio_dep ],
++ install: true,
++ install_dir: atspi_libexecdir)
++