[gtk/a11y/atspi: 7/28] a11y: Add AT-SPI cache object




commit d7ebf18723a499533d9bac815ebbf8083004c61b
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Fri Oct 9 14:20:43 2020 +0100

    a11y: Add AT-SPI cache object
    
    Right now, the cache is unused, and we still need to implement the
    serialisation method and emit the signals.

 gtk/a11y/gtkatspicache.c        | 218 ++++++++++++++++++++++++++++++++++++++++
 gtk/a11y/gtkatspicacheprivate.h |  44 ++++++++
 gtk/a11y/gtkatspicontext.c      |   4 +
 gtk/a11y/gtkatspiroot.c         |  25 ++++-
 gtk/a11y/gtkatspirootprivate.h  |   5 +
 gtk/a11y/meson.build            |   1 +
 6 files changed, 293 insertions(+), 4 deletions(-)
---
diff --git a/gtk/a11y/gtkatspicache.c b/gtk/a11y/gtkatspicache.c
new file mode 100644
index 0000000000..9681fd613e
--- /dev/null
+++ b/gtk/a11y/gtkatspicache.c
@@ -0,0 +1,218 @@
+/* gtkatspicache.c: AT-SPI object cache
+ *
+ * Copyright 2020  holder
+ *
+ * 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 "gtkatspicacheprivate.h"
+
+#include "gtkdebug.h"
+
+#include "a11y/atspi/atspi-cache.h"
+
+struct _GtkAtSpiCache
+{
+  GObject parent_instance;
+
+  char *cache_path;
+  GDBusConnection *connection;
+
+  GHashTable *contexts;
+};
+
+enum
+{
+  PROP_CACHE_PATH = 1,
+  PROP_CONNECTION,
+
+  N_PROPS
+};
+
+static GParamSpec *obj_props[N_PROPS];
+
+G_DEFINE_TYPE (GtkAtSpiCache, gtk_at_spi_cache, G_TYPE_OBJECT)
+
+static void
+gtk_at_spi_cache_finalize (GObject *gobject)
+{
+  GtkAtSpiCache *self = GTK_AT_SPI_CACHE (gobject);
+
+  g_clear_pointer (&self->contexts, g_hash_table_unref);
+  g_clear_object (&self->connection);
+  g_free (self->cache_path);
+
+  G_OBJECT_CLASS (gtk_at_spi_cache_parent_class)->finalize (gobject);
+}
+
+static void
+gtk_at_spi_cache_set_property (GObject      *gobject,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GtkAtSpiCache *self = GTK_AT_SPI_CACHE (gobject);
+
+  switch (prop_id)
+    {
+    case PROP_CACHE_PATH:
+      g_free (self->cache_path);
+      self->cache_path = g_value_dup_string (value);
+      break;
+
+    case PROP_CONNECTION:
+      g_clear_object (&self->connection);
+      self->connection = g_value_dup_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+    }
+}
+
+static void
+handle_cache_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)
+{
+  g_printerr ("[Cache] Method '%s' on interface '%s' for object '%s' from '%s'\n",
+              method_name, interface_name, object_path, sender);
+
+}
+
+static GVariant *
+handle_cache_get_property (GDBusConnection       *connection,
+                           const gchar           *sender,
+                           const gchar           *object_path,
+                           const gchar           *interface_name,
+                           const gchar           *property_name,
+                           GError               **error,
+                           gpointer               user_data)
+{
+  GVariant *res = NULL;
+
+  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+               "Unknown property '%s'", property_name);
+
+  return res;
+}
+
+
+static const GDBusInterfaceVTable cache_vtable = {
+  handle_cache_method,
+  handle_cache_get_property,
+  NULL,
+};
+
+static void
+gtk_at_spi_cache_constructed (GObject *gobject)
+{
+  GtkAtSpiCache *self = GTK_AT_SPI_CACHE (gobject);
+
+  g_assert (self->connection);
+  g_assert (self->cache_path);
+
+  g_dbus_connection_register_object (self->connection,
+                                     self->cache_path,
+                                     (GDBusInterfaceInfo *) &atspi_cache_interface,
+                                     &cache_vtable,
+                                     self,
+                                     NULL,
+                                     NULL);
+
+  GTK_NOTE (A11Y, g_message ("Cache registered at %s", self->cache_path));
+
+  G_OBJECT_CLASS (gtk_at_spi_cache_parent_class)->constructed (gobject);
+}
+
+static void
+gtk_at_spi_cache_class_init (GtkAtSpiCacheClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->constructed = gtk_at_spi_cache_constructed;
+  gobject_class->set_property = gtk_at_spi_cache_set_property;
+  gobject_class->finalize = gtk_at_spi_cache_finalize;
+
+  obj_props[PROP_CACHE_PATH] =
+    g_param_spec_string ("cache-path", NULL, NULL,
+                         NULL,
+                         G_PARAM_WRITABLE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+
+  obj_props[PROP_CONNECTION] =
+    g_param_spec_object ("connection", NULL, NULL,
+                         G_TYPE_DBUS_CONNECTION,
+                         G_PARAM_WRITABLE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, obj_props);
+}
+
+static void
+gtk_at_spi_cache_init (GtkAtSpiCache *self)
+{
+  self->contexts = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                          g_free,
+                                          NULL);
+}
+
+GtkAtSpiCache *
+gtk_at_spi_cache_new (GDBusConnection *connection,
+                      const char *cache_path)
+{
+  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+  g_return_val_if_fail (cache_path != NULL, NULL);
+
+  return g_object_new (GTK_TYPE_AT_SPI_CACHE,
+                       "connection", connection,
+                       "cache-path", cache_path,
+                       NULL);
+}
+
+void
+gtk_at_spi_cache_add_context (GtkAtSpiCache *self,
+                              const char *path,
+                              GtkATContext *context)
+{
+  g_return_if_fail (GTK_IS_AT_SPI_CACHE (self));
+  g_return_if_fail (path != NULL);
+  g_return_if_fail (GTK_IS_AT_CONTEXT (context));
+
+  if (g_hash_table_contains (self->contexts, path))
+    return;
+
+  g_hash_table_insert (self->contexts, g_strdup (path), context);
+}
+
+GtkATContext *
+gtk_at_spi_cache_get_context (GtkAtSpiCache *self,
+                              const char *path)
+{
+  g_return_val_if_fail (GTK_IS_AT_SPI_CACHE (self), NULL);
+  g_return_val_if_fail (path != NULL, NULL);
+
+  return g_hash_table_lookup (self->contexts, path);
+}
diff --git a/gtk/a11y/gtkatspicacheprivate.h b/gtk/a11y/gtkatspicacheprivate.h
new file mode 100644
index 0000000000..12952a3c87
--- /dev/null
+++ b/gtk/a11y/gtkatspicacheprivate.h
@@ -0,0 +1,44 @@
+/* gtkatspicacheprivate.h: AT-SPI object cache
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "gtkatcontextprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_AT_SPI_CACHE (gtk_at_spi_cache_get_type())
+
+G_DECLARE_FINAL_TYPE (GtkAtSpiCache, gtk_at_spi_cache, GTK, AT_SPI_CACHE, GObject)
+
+GtkAtSpiCache *
+gtk_at_spi_cache_new (GDBusConnection *connection,
+                      const char *cache_path);
+
+void
+gtk_at_spi_cache_add_context (GtkAtSpiCache *self,
+                              const char *path,
+                              GtkATContext *context);
+
+GtkATContext *
+gtk_at_spi_cache_get_context (GtkAtSpiCache *self,
+                              const char *path);
+
+G_END_DECLS
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c
index d2c582d018..31ef9a8842 100644
--- a/gtk/a11y/gtkatspicontext.c
+++ b/gtk/a11y/gtkatspicontext.c
@@ -22,6 +22,7 @@
 
 #include "gtkatspicontextprivate.h"
 
+#include "gtkatspicacheprivate.h"
 #include "gtkatspirootprivate.h"
 #include "gtkdebug.h"
 #include "gtkwindow.h"
@@ -43,6 +44,9 @@ struct _GtkAtSpiContext
   /* The root object, used as a entry point */
   GtkAtSpiRoot *root;
 
+  /* The cache object, used to retrieve ATContexts */
+  GtkAtSpiCache *cache;
+
   /* The address for the ATSPI accessibility bus */
   char *bus_address;
 
diff --git a/gtk/a11y/gtkatspiroot.c b/gtk/a11y/gtkatspiroot.c
index 5d7e5feef7..4cca4e526a 100644
--- a/gtk/a11y/gtkatspiroot.c
+++ b/gtk/a11y/gtkatspiroot.c
@@ -32,8 +32,11 @@
 
 #include <gio/gio.h>
 
-#define ATSPI_VERSION   "2.1"
-#define ATSPI_ROOT_PATH "/org/a11y/atspi/accessible/root"
+#define ATSPI_VERSION           "2.1"
+
+#define ATSPI_PATH_PREFIX       "/org/a11y/atspi"
+#define ATSPI_ROOT_PATH         ATSPI_PATH_PREFIX "/accessible/root"
+#define ATSPI_CACHE_PATH        ATSPI_PATH_PREFIX "/cache"
 
 struct _GtkAtSpiRoot
 {
@@ -52,6 +55,8 @@ struct _GtkAtSpiRoot
   char *desktop_path;
 
   gint32 application_id;
+
+  GtkAtSpiCache *cache;
 };
 
 enum
@@ -82,6 +87,7 @@ gtk_at_spi_root_dispose (GObject *gobject)
 {
   GtkAtSpiRoot *self = GTK_AT_SPI_ROOT (gobject);
 
+  g_clear_object (&self->cache);
   g_clear_object (&self->connection);
 
   G_OBJECT_CLASS (gtk_at_spi_root_parent_class)->dispose (gobject);
@@ -295,6 +301,9 @@ on_registration_reply (GObject      *gobject,
                                  self->desktop_name,
                                  self->desktop_path));
     }
+
+  /* Register the cache object */
+  self->cache = gtk_at_spi_cache_new (self->connection, ATSPI_CACHE_PATH);
 }
 
 static void
@@ -324,14 +333,14 @@ gtk_at_spi_root_register (GtkAtSpiRoot *self)
 
   g_dbus_connection_register_object (self->connection,
                                      self->root_path,
-                                     atspi_application_interface_info (),
+                                     (GDBusInterfaceInfo *) &atspi_application_interface,
                                      &root_application_vtable,
                                      self,
                                      NULL,
                                      NULL);
   g_dbus_connection_register_object (self->connection,
                                      self->root_path,
-                                     atspi_accessible_interface_info (),
+                                     (GDBusInterfaceInfo *) &atspi_accessible_interface,
                                      &root_accessible_vtable,
                                      self,
                                      NULL,
@@ -430,3 +439,11 @@ gtk_at_spi_root_get_connection (GtkAtSpiRoot *self)
 
   return self->connection;
 }
+
+GtkAtSpiCache *
+gtk_at_spi_root_get_cache (GtkAtSpiRoot *self)
+{
+  g_return_val_if_fail (GTK_IS_AT_SPI_ROOT (self), NULL);
+
+  return self->cache;
+}
diff --git a/gtk/a11y/gtkatspirootprivate.h b/gtk/a11y/gtkatspirootprivate.h
index ff30b24670..4e951bbcea 100644
--- a/gtk/a11y/gtkatspirootprivate.h
+++ b/gtk/a11y/gtkatspirootprivate.h
@@ -22,6 +22,8 @@
 
 #include <gio/gio.h>
 
+#include "gtkatspicacheprivate.h"
+
 G_BEGIN_DECLS
 
 #define GTK_TYPE_AT_SPI_ROOT (gtk_at_spi_root_get_type())
@@ -34,4 +36,7 @@ gtk_at_spi_root_new (const char *bus_address);
 GDBusConnection *
 gtk_at_spi_root_get_connection (GtkAtSpiRoot *self);
 
+GtkAtSpiCache *
+gtk_at_spi_root_get_cache (GtkAtSpiRoot *self);
+
 G_END_DECLS
diff --git a/gtk/a11y/meson.build b/gtk/a11y/meson.build
index d9c6cdc97c..d18682637a 100644
--- a/gtk/a11y/meson.build
+++ b/gtk/a11y/meson.build
@@ -9,6 +9,7 @@ if gtk_a11y_backends.contains('atspi')
   subdir('atspi')
 
   gtk_a11y_src += files([
+    'gtkatspicache.c',
     'gtkatspicontext.c',
     'gtkatspiroot.c',
   ])


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