[gtk/a11y/component: 180/183] atspi: Implement Component




commit 30115e0f9a13dc5f5286a6f342dda00d6660a9b4
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Oct 13 21:23:22 2020 -0400

    atspi: Implement Component
    
    Implement the non-questionable parts of the Component interface
    for accessibles which are widgets.
    
    This does not include:
     - global coordinates
     - setters
     - scrolling
     - alpha, layers, zorder, and the like

 gtk/a11y/gtkatspicomponent.c        | 242 ++++++++++++++++++++++++++++++++++++
 gtk/a11y/gtkatspicomponentprivate.h |  30 +++++
 gtk/a11y/gtkatspicontext.c          |  17 +++
 gtk/a11y/gtkatspiprivate.h          |   6 +
 gtk/a11y/meson.build                |   1 +
 5 files changed, 296 insertions(+)
---
diff --git a/gtk/a11y/gtkatspicomponent.c b/gtk/a11y/gtkatspicomponent.c
new file mode 100644
index 0000000000..d9c92a8d5c
--- /dev/null
+++ b/gtk/a11y/gtkatspicomponent.c
@@ -0,0 +1,242 @@
+/* gtkatspicomponent.c: AT-SPI Component implementation
+ *
+ * Copyright 2020 Red Hat, Inc.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkatspicomponentprivate.h"
+
+#include "gtkatspicontextprivate.h"
+#include "gtkatspiprivate.h"
+#include "gtkatspiutilsprivate.h"
+#include "gtkaccessibleprivate.h"
+#include "gtkwidget.h"
+
+#include "a11y/atspi/atspi-component.h"
+
+#include "gtkdebug.h"
+
+#include <gio/gio.h>
+
+static void
+translate_coordinates_to_widget (GtkWidget      *widget,
+                                 AtspiCoordType  coordtype,
+                                 int             xi,
+                                 int             yi,
+                                 int            *xo,
+                                 int            *yo)
+{
+  double x = xi;
+  double y = yi;
+
+  switch (coordtype)
+    {
+    case ATSPI_COORD_TYPE_SCREEN:
+      g_warning ("Screen coordinates not supported, reported positions will be wrong");
+      G_GNUC_FALLTHROUGH;
+
+    case ATSPI_COORD_TYPE_WINDOW:
+      gtk_widget_translate_coordinates (GTK_WIDGET (gtk_widget_get_root (widget)),
+                                        widget,
+                                        x, y,
+                                        &x, &y);
+      break;
+
+    case ATSPI_COORD_TYPE_PARENT:
+      gtk_widget_translate_coordinates (gtk_widget_get_parent (widget),
+                                        widget,
+                                        x, y,
+                                        &x, &y);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  *xo = (int)x;
+  *yo = (int)y;
+}
+
+static void
+translate_coordinates_from_widget (GtkWidget      *widget,
+                                   AtspiCoordType  coordtype,
+                                   int             xi,
+                                   int             yi,
+                                   int            *xo,
+                                   int            *yo)
+{
+  double x = xi;
+  double y = yi;
+
+  switch (coordtype)
+    {
+    case ATSPI_COORD_TYPE_SCREEN:
+      g_warning ("Screen coordinates not supported, reported positions will be wrong");
+      G_GNUC_FALLTHROUGH;
+
+    case ATSPI_COORD_TYPE_WINDOW:
+      gtk_widget_translate_coordinates (widget,
+                                        GTK_WIDGET (gtk_widget_get_root (widget)),
+                                        x, y,
+                                        &x, &y);
+      break;
+
+    case ATSPI_COORD_TYPE_PARENT:
+      gtk_widget_translate_coordinates (widget,
+                                        gtk_widget_get_parent (widget),
+                                        x, y,
+                                        &x, &y);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+
+  *xo = (int)x;
+  *yo = (int)y;
+}
+
+static void
+component_handle_method (GDBusConnection       *connection,
+                         const gchar           *sender,
+                         const gchar           *object_path,
+                         const gchar           *interface_name,
+                         const gchar           *method_name,
+                         GVariant              *parameters,
+                         GDBusMethodInvocation *invocation,
+                         gpointer               user_data)
+{
+  GtkATContext *self = user_data;
+  GtkAccessible *accessible = gtk_at_context_get_accessible (self);
+  GtkWidget *widget = GTK_WIDGET (accessible);
+
+  if (g_strcmp0 (method_name, "Contains") == 0)
+    {
+      int x, y;
+      AtspiCoordType coordtype;
+      gboolean ret;
+
+      g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
+
+      translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
+
+      ret = gtk_widget_contains (widget, x, y);
+      g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+    }
+  else if (g_strcmp0 (method_name, "GetAccessibleAtPoint") == 0)
+    {
+      int x, y;
+      AtspiCoordType coordtype;
+      GtkWidget *child;
+
+      g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
+
+      translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
+
+      child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
+      if (!child)
+        {
+          g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_null_ref 
()));
+        }
+      else
+        {
+          GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)));
+
+          g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", 
gtk_at_spi_context_to_ref (ctx)));
+        }
+    }
+  else if (g_strcmp0 (method_name, "GetExtents") == 0)
+    {
+      AtspiCoordType coordtype;
+      int x, y;
+      int width = gtk_widget_get_width (widget);
+      int height = gtk_widget_get_height (widget);
+
+      g_variant_get (parameters, "(u)", &coordtype);
+
+      translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
+
+      g_dbus_method_invocation_return_value (invocation, g_variant_new ("((iiii))", x, y, width, height));
+    }
+  else if (g_strcmp0 (method_name, "GetPosition") == 0)
+    {
+      AtspiCoordType coordtype;
+      int x, y;
+
+      g_variant_get (parameters, "(u)", &coordtype);
+
+      translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
+
+      g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", x, y));
+    }
+  else if (g_strcmp0 (method_name, "GetSize") == 0)
+    {
+      int width = gtk_widget_get_width (widget);
+      int height = gtk_widget_get_height (widget);
+
+      g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", width, height));
+    }
+  else if (g_strcmp0 (method_name, "GetLayer") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "GetMDIZOrder") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "GrabFocus") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "GetAlpha") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "SetExtents") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "SetPosition") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "SetSize") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "ScrollTo") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+  else if (g_strcmp0 (method_name, "ScrollToPoint") == 0)
+    {
+      g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, 
"");
+    }
+}
+
+static const GDBusInterfaceVTable component_vtable = {
+  component_handle_method,
+};
+
+const GDBusInterfaceVTable *
+gtk_atspi_get_component_vtable (GtkAccessible *accessible)
+{
+  if (GTK_IS_WIDGET (accessible))
+    return &component_vtable;
+}
diff --git a/gtk/a11y/gtkatspicomponentprivate.h b/gtk/a11y/gtkatspicomponentprivate.h
new file mode 100644
index 0000000000..157a6e9eca
--- /dev/null
+++ b/gtk/a11y/gtkatspicomponentprivate.h
@@ -0,0 +1,30 @@
+/* gtkatspicomponentprivate.h: AT-SPI Component implementation
+ *
+ * Copyright 2020 Red Hat, Inc.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+#include "gtkaccessible.h"
+
+G_BEGIN_DECLS
+
+const GDBusInterfaceVTable *gtk_atspi_get_component_vtable (GtkAccessible *accessible);
+
+G_END_DECLS
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c
index bed789f048..53589b9466 100644
--- a/gtk/a11y/gtkatspicontext.c
+++ b/gtk/a11y/gtkatspicontext.c
@@ -33,6 +33,7 @@
 #include "gtkatspitextprivate.h"
 #include "gtkatspiutilsprivate.h"
 #include "gtkatspivalueprivate.h"
+#include "gtkatspicomponentprivate.h"
 
 #include "a11y/atspi/atspi-accessible.h"
 #include "a11y/atspi/atspi-action.h"
@@ -40,6 +41,7 @@
 #include "a11y/atspi/atspi-text.h"
 #include "a11y/atspi/atspi-value.h"
 #include "a11y/atspi/atspi-selection.h"
+#include "a11y/atspi/atspi-component.h"
 
 #include "gtkdebug.h"
 #include "gtkeditable.h"
@@ -989,6 +991,21 @@ gtk_at_spi_context_register_object (GtkAtSpiContext *self)
                                          NULL);
   self->n_registered_objects++;
 
+  vtable = gtk_atspi_get_component_vtable (accessible);
+  if (vtable)
+    {
+      g_variant_builder_add (&interfaces, "s", atspi_component_interface.name);
+      self->registration_ids[self->n_registered_objects] =
+          g_dbus_connection_register_object (self->connection,
+                                             self->context_path,
+                                             (GDBusInterfaceInfo *) &atspi_component_interface,
+                                             vtable,
+                                             self,
+                                             NULL,
+                                             NULL);
+      self->n_registered_objects++;
+    }
+
   vtable = gtk_atspi_get_text_vtable (accessible);
   if (vtable)
     {
diff --git a/gtk/a11y/gtkatspiprivate.h b/gtk/a11y/gtkatspiprivate.h
index 6b35e0df6c..9d3d316354 100644
--- a/gtk/a11y/gtkatspiprivate.h
+++ b/gtk/a11y/gtkatspiprivate.h
@@ -246,4 +246,10 @@ typedef enum {
   ATSPI_TEXT_GRANULARITY_PARAGRAPH
 } AtspiTextGranularity;
 
+typedef enum {
+  ATSPI_COORD_TYPE_SCREEN,
+  ATSPI_COORD_TYPE_WINDOW,
+  ATSPI_COORD_TYPE_PARENT,
+} AtspiCoordType;
+
 G_END_DECLS
diff --git a/gtk/a11y/meson.build b/gtk/a11y/meson.build
index 5cb0cc88f2..7fff19549a 100644
--- a/gtk/a11y/meson.build
+++ b/gtk/a11y/meson.build
@@ -11,6 +11,7 @@ if gtk_a11y_backends.contains('atspi')
   gtk_a11y_src += files([
     'gtkatspiaction.c',
     'gtkatspicache.c',
+    'gtkatspicomponent.c',
     'gtkatspicontext.c',
     'gtkatspieditabletext.c',
     'gtkatspipango.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]