diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c new file mode 100644 index 0000000000..95fc342917 --- /dev/null +++ b/gtk/a11y/gtkatspicontext.c @@ -0,0 +1,85 @@ +/* gtkatspicontext.c: AT-SPI GtkATContext implementation + * + * Copyright 2020 GNOME Foundation + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * 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.1 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, see . + */ + +#include "config.h" + +#include "gtkatspicontextprivate.h" + +struct _GtkAtSpiContext +{ + GtkATContext parent_instance; +}; + +G_DEFINE_TYPE (GtkAtSpiContext, gtk_at_spi_context, GTK_TYPE_AT_CONTEXT) + +static void +gtk_at_spi_context_state_change (GtkATContext *self, + GtkAccessibleStateChange changed_states, + GtkAccessiblePropertyChange changed_properties, + GtkAccessibleRelationChange changed_relations, + GtkAccessibleAttributeSet *states, + GtkAccessibleAttributeSet *properties, + GtkAccessibleAttributeSet *relations) +{ +} + +static void +gtk_at_spi_context_constructed (GObject *gobject) +{ + G_OBJECT_CLASS (gtk_at_spi_context_parent_class)->constructed (gobject); +} + +static void +gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkATContextClass *context_class = GTK_AT_CONTEXT_CLASS (klass); + + gobject_class->constructed = gtk_at_spi_context_constructed; + + context_class->state_change = gtk_at_spi_context_state_change; +} + +static void +gtk_at_spi_context_init (GtkAtSpiContext *self) +{ +} + +/*< private > + * gtk_at_spi_context_new: + * @accessible_role: the accessible role for the AT context + * @accessible: the #GtkAccessible instance which owns the context + * + * Creates a new #GtkAtSpiContext instance for @accessible, using the + * given @accessible_role. + * + * Returns: (transfer full): the newly created #GtkAtSpiContext + */ +GtkATContext * +gtk_at_spi_context_new (GtkAccessibleRole accessible_role, + GtkAccessible * accessible) +{ + g_return_val_if_fail (GTK_IS_ACCESSIBLE (accessible), NULL); + + return g_object_new (GTK_TYPE_AT_SPI_CONTEXT, + "accessible-role", accessible_role, + "accessible", accessible, + NULL); +} diff --git a/gtk/a11y/gtkatspicontextprivate.h b/gtk/a11y/gtkatspicontextprivate.h new file mode 100644 index 0000000000..28205f1fbc --- /dev/null +++ b/gtk/a11y/gtkatspicontextprivate.h @@ -0,0 +1,35 @@ +/* gtkatspicontextprivate.h: AT-SPI GtkATContext implementation + * + * Copyright 2020 GNOME Foundation + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * 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.1 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, see . + */ + +#pragma once + +#include "gtkatcontextprivate.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_AT_SPI_CONTEXT (gtk_at_spi_context_get_type()) + +G_DECLARE_FINAL_TYPE (GtkAtSpiContext, gtk_at_spi_context, GTK, AT_SPI_CONTEXT, GtkATContext) + +GtkATContext * +gtk_at_spi_context_new (GtkAccessibleRole accessible_role, + GtkAccessible *accessible); + +G_END_DECLS diff --git a/gtk/a11y/meson.build b/gtk/a11y/meson.build index b3555eff27..22d1956027 100644 --- a/gtk/a11y/meson.build +++ b/gtk/a11y/meson.build @@ -7,4 +7,8 @@ endif if gtk_a11y_backends.contains('atspi') subdir('atspi') + + gtk_a11y_src += files([ + 'gtkatspicontext.c', + ]) endif diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index 6686e3f9a9..4d86a2346d 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -36,9 +36,14 @@ #include "gtkatcontextprivate.h" #include "gtkaccessiblevalueprivate.h" +#include "gtkdebug.h" #include "gtktestatcontextprivate.h" #include "gtktypebuiltins.h" +#if defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND) +#include "a11y/gtkatspicontextprivate.h" +#endif + G_DEFINE_ABSTRACT_TYPE (GtkATContext, gtk_at_context, G_TYPE_OBJECT) enum @@ -354,6 +359,20 @@ gtk_at_context_get_accessible_role (GtkATContext *self) return self->accessible_role; } +static const struct { + const char *name; + GtkATContext * (* create_context) (GtkAccessibleRole accessible_role, + GtkAccessible *accessible); +} a11y_backends[] = { +#if defined(GDK_WINDOWING_WAYLAND) + { "AT-SPI", _gtk_at_spi_context_new }, +#endif +#if defined(GDK_WINDOWING_X11) + { "AT-SPI", gtk_at_spi_context_new }, +#endif + { NULL, NULL }, +}; + /** * gtk_at_context_create: (constructor) * @accessible_role: the accessible role used by the #GtkATContext @@ -401,8 +420,23 @@ gtk_at_context_create (GtkAccessibleRole accessible_role, if (gtk_no_a11y[0] == '1') return NULL; + GtkATContext *res = NULL; + + for (guint i = 0; i < G_N_ELEMENTS (a11y_backends); i++) + { + GTK_NOTE (A11Y, g_message ("Trying %s a11y backend", a11y_backends[i].name)); + if (a11y_backends[i].create_context != NULL) + { + res = a11y_backends[i].create_context (accessible_role, accessible); + break; + } + } + + if (res == NULL) + res = gtk_test_at_context_new (accessible_role, accessible); + /* FIXME: Add GIOExtension for AT contexts */ - return gtk_test_at_context_new (accessible_role, accessible); + return res; } /*< private >