*
*/
-#define SPI_ATK_PATH_PREFIX_LENGTH 22
-#define SPI_ATK_OBJECT_PATH_PREFIX "/org/at_spi/accessible"
-#define SPI_ATK_OBJECT_PATH_DESKTOP SPI_ATK_OBJECT_PATH_PREFIX "/desktop"
+#define SPI_ATK_PATH_PREFIX_LENGTH 27
+#define SPI_ATK_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/"
+#define SPI_ATK_OBJECT_PATH_ROOT "root"
-#define SPI_ATK_OBJECT_REFERENCE_TEMPLATE SPI_ATK_OBJECT_PATH_PREFIX "/%d"
+#define SPI_ATK_OBJECT_REFERENCE_TEMPLATE SPI_ATK_OBJECT_PATH_PREFIX "%d"
#define SPI_DBUS_ID "spi-dbus-id"
SpiRegister *spi_global_register = NULL;
+static const gchar * spi_register_root_path = SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_ROOT;
+
enum
{
OBJECT_REGISTERED,
}
static void
+deregister_object (gpointer data, GObject * gobj)
+{
+ SpiRegister *reg = SPI_REGISTER (data);
+
+ spi_register_deregister_object (reg, gobj, FALSE);
+}
+
+static void
+spi_register_remove_weak_ref (gpointer key, gpointer val, gpointer reg)
+{
+ g_object_weak_unref (val, deregister_object, reg);
+}
+
+static void
spi_register_finalize (GObject * object)
{
SpiRegister *reg = SPI_REGISTER (object);
- g_free (reg->ref2ptr);
+ g_hash_table_foreach (reg->ref2ptr, spi_register_remove_weak_ref, reg);
+ g_hash_table_unref (reg->ref2ptr);
G_OBJECT_CLASS (spi_register_parent_class)->finalize (object);
}
* Removes the AtkObject from the reference lookup tables, meaning
* it is no longer exposed over D-Bus.
*/
-static void
-deregister_object (gpointer data, GObject * gobj)
+void
+spi_register_deregister_object (SpiRegister *reg, GObject *gobj, gboolean unref)
{
- SpiRegister *reg = SPI_REGISTER (data);
guint ref;
ref = object_to_ref (gobj);
register_signals [OBJECT_DEREGISTERED],
0,
gobj);
+ if (unref)
+ g_object_weak_unref (gobj, deregister_object, reg);
g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref));
+
+#ifdef SPI_ATK_DEBUG
+ g_debug ("DEREG - %d", ref);
+#endif
}
}
g_object_set_data (G_OBJECT (gobj), SPI_DBUS_ID, GINT_TO_POINTER (ref));
g_object_weak_ref (G_OBJECT (gobj), deregister_object, reg);
+#ifdef SPI_ATK_DEBUG
+ g_debug ("REG - %d", ref);
+#endif
+
g_signal_emit (reg, register_signals [OBJECT_REGISTERED], 0, gobj);
}
!= 0)
return NULL;
- path += SPI_ATK_PATH_PREFIX_LENGTH; /* Skip over the prefix */
+ path += SPI_ATK_PATH_PREFIX_LENGTH; /* Skip over the prefix */
- if (!g_strcmp0 (SPI_ATK_OBJECT_PATH_DESKTOP, path))
- return G_OBJECT (atk_get_root ());
- if (path[0] != '/')
- return NULL;
+ /* Map the root path to the root object. */
+ if (!g_strcmp0 (SPI_ATK_OBJECT_PATH_ROOT, path))
+ return G_OBJECT (spi_global_app_data->root);
- path++;
index = atoi (path);
data = g_hash_table_lookup (reg->ref2ptr, GINT_TO_POINTER (index));
if (data)
{
guint ref;
+ if (gobj == NULL)
+ return NULL;
+
+ /* Map the root object to the root path. */
+ if ((void *)gobj == (void *)spi_global_app_data->root)
+ return g_strdup (spi_register_root_path);
+
ref = object_to_ref (gobj);
if (!ref)
{
* within any particular application.
*/
gchar *
-spi_register_desktop_object_path ()
+spi_register_root_object_path ()
{
- return g_strdup (SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_DESKTOP);
+ return g_strdup (SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_ROOT);
}
/*END------------------------------------------------------------------------*/