atspi-image.h \
atspi-matchrule.c \
atspi-matchrule.h \
+ atspi-matchrule-private.h \
atspi-misc.c \
atspi-misc.h \
atspi-misc-private.h \
g_return_val_if_fail (obj != NULL, NULL);
if (!(obj->cached_properties & ATSPI_CACHE_NAME))
{
- if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", NULL, "s", &obj->name))
+ if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error,
+ "s", &obj->name))
return NULL;
obj->cached_properties |= ATSPI_CACHE_NAME;
}
AtspiStateSet *
atspi_accessible_get_state_set (AtspiAccessible *obj)
{
- return obj->states;
+ return g_object_ref (obj->states);
}
/**
message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
ret = _atspi_dbus_attribute_array_from_message (message);
- dbus_message_unref (message);
+ if (message)
+ dbus_message_unref (message);
return ret;
}
/**
- * atspi_accessible_get_host_application:
+ * atspi_accessible_get_application:
* @obj: The #AtspiAccessible being queried.
*
* Get the containing #AtspiApplication for an object.
* this object.
*/
AtspiAccessible *
-atspi_accessible_get_host_application (AtspiAccessible *obj, GError **error)
+atspi_accessible_get_application (AtspiAccessible *obj, GError **error)
{
AtspiAccessible *parent;
parent = atspi_accessible_get_parent (obj, NULL);
if (!parent || parent == obj ||
atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
- return obj;
+ return g_object_ref (obj);
obj = parent;
}
}
+/* Applicatio-specific methods */
+
+/**
+ * atspi_accessible_get_toolkit_name:
+ * @obj: a pointer to the #AtspiAccessible object on which to operate.
+ *
+ * Get the toolkit for a #AtspiAccessible object.
+ * Only works on application root objects.
+ *
+ * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object.
+ * or NULL on exception
+ **/
+gchar *
+atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error)
+{
+ gchar *ret = NULL;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+
+ if (!_atspi_dbus_get_property (obj, atspi_interface_application, "ToolkitName", error, "s", &ret))
+ return NULL;
+ return g_strdup (ret);
+}
+
+/**
+ * atspi_accessible_get_toolkit_version:
+ * @obj: a pointer to the #AtspiAccessible object on which to operate.
+ *
+ * Get the toolkit version for a #AtspiAccessible object.
+ * Only works on application root objects.
+ *
+ * Returns: a UTF-8 string indicating the toolkit ersion for the #AtspiAccessible object.
+ * or NULL on exception
+ **/
+gchar *
+atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error)
+{
+ gchar *ret = NULL;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+
+ if (!_atspi_dbus_get_property (obj, atspi_interface_application, "ToolkitVersion", error, "s", &ret))
+ return NULL;
+ return g_strdup (ret);
+}
/* Interface query methods */
/**
}
/**
- * atspi_accessible_get_application:
- * @obj: a pointer to the #AtspiAccessible instance to query.
- *
- * Get the #AtspiApplication interface for an #AtspiAccessible.
- *
- * Returns: a pointer to an #AtspiApplication interface instance, or
- * NULL if @obj does not implement #AtspiApplication.
- **/
-AtspiApplication *
-atspi_accessible_get_application (AtspiAccessible *accessible)
-{
- return (_atspi_accessible_is_a (accessible, atspi_interface_application) ?
- g_object_ref (ATSPI_ACTION (accessible)) : NULL);
-}
-
-/**
* atspi_accessible_get_action:
* @obj: a pointer to the #AtspiAccessible instance to query.
*
GArray * atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error);
-AtspiAccessible * atspi_accessible_get_host_application (AtspiAccessible *obj, GError **error);
+gchar * atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error);
+
+gchar * atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error);
+
+AtspiAccessible * atspi_accessible_get_application (AtspiAccessible *obj, GError **error);
AtspiAction * atspi_accessible_get_action (AtspiAccessible *obj);
ATSPI_MODIFIER_META2,
ATSPI_MODIFIER_META3,
ATSPI_MODIFIER_NUMLOCK,
-} AtspimodifierType;
+} AtspiModifierType;
/**
* ATSPI_MODIFIERTYPE_COUNT:
{
AtspiDeviceListenerCB callback;
gpointer user_data;
+ GDestroyNotify callback_destroyed;
} DeviceEventHandler;
GObjectClass *device_parent_class;
*/
static DeviceEventHandler *
-device_event_handler_new (AtspiDeviceListenerCB callback, gpointer user_data)
+device_event_handler_new (AtspiDeviceListenerCB callback,
+ GDestroyNotify callback_destroyed,
+ gpointer user_data)
{
DeviceEventHandler *eh = g_new0 (DeviceEventHandler, 1);
eh->callback = callback;
+ eh->callback_destroyed = callback_destroyed;
eh->user_data = user_data;
return eh;
}
+static gboolean
+device_remove_datum (const AtspiDeviceEvent *event, void *user_data)
+{
+ AtspiDeviceListenerSimpleCB cb = user_data;
+ return cb (event);
+}
+
+static void
+device_event_handler_free (DeviceEventHandler *eh)
+{
+#if 0
+ /* TODO; Test this; it will probably crash with pyatspi for unknown reasons */
+ if (eh->callback_destroyed)
+ {
+ gpointer rea_callback = (eh->callback == device_remove_datum ?
+ eh->user_data : eh->callback);
+ (*eh->callback_destroyed) (real_callback);
+ }
+#endif
+ g_free (eh);
+}
+
static GList *
event_list_remove_by_cb (GList *list, AtspiDeviceListenerCB callback)
{
if (eh->callback == callback)
{
list = g_list_delete_link (list, l);
- g_free (eh);
+ device_event_handler_free (eh);
}
}
device_listeners = g_list_remove (device_listeners, obj);
}
+static AtspiDeviceEvent *
+atspi_device_event_copy (AtspiDeviceEvent *src)
+{
+ AtspiDeviceEvent *dst = g_new0 (AtspiDeviceEvent, 1);
+ if (!dst)
+ return NULL;
+ dst->type = src->type;
+ dst->id = src->id;
+ dst->hw_code = src->hw_code;
+ dst->modifiers = src->modifiers;
+ dst->timestamp = src->timestamp;
+ if (src->event_string)
+ dst->event_string = g_strdup (src->event_string);
+ dst->is_text = src->is_text;
+ return dst;
+}
+
+void
+atspi_device_event_free (AtspiDeviceEvent *event)
+{
+ if (event->event_string)
+ g_free (event->event_string);
+ g_free (event);
+}
+
/*
* Device event handler
*/
const AtspiDeviceEvent *event)
{
GList *l;
- AtspiDeviceEvent anevent;
gboolean handled = FALSE;
/* FIXME: re-enterancy hazard on this list */
{
DeviceEventHandler *eh = l->data;
- if ((handled = eh->callback (&anevent, eh->user_data)))
+ if ((handled = eh->callback (atspi_device_event_copy (event), eh->user_data)))
{
break;
}
for (l = listener->callbacks; l; l = l->next)
{
- g_free (l->data);
+ device_event_handler_free (l->data);
}
g_list_free (listener->callbacks);
/**
* atspi_device_listener_new:
- * @callback: (scope call): an #AtspiDeviceListenerCB callback function,
+ * @callback: (scope notify): an #AtspiDeviceListenerCB callback function,
* or NULL.
+ * @callback_destroyed: A #GDestroyNotify called when the listener is freed
+ * and data associated with the callback should be freed. Can be NULL.
* @user_data: (closure): a pointer to data which will be passed to the
* callback when invoked.
*
*
**/
AtspiDeviceListener *
-atspi_device_listener_new (AtspiDeviceListenerCB callback)
+atspi_device_listener_new (AtspiDeviceListenerCB callback,
+ GDestroyNotify callback_destroyed,
+ void *user_data)
{
AtspiDeviceListener *listener = g_object_new (atspi_device_listener_get_type (), NULL);
+ if (callback)
+ atspi_device_listener_add_callback (listener, callback, callback_destroyed,
+ user_data);
return listener;
}
/**
+ * atspi_device_listener_new_simple:
+ * @callback: (scope notify): an #AtspiDeviceListenerCB callback function,
+ * or NULL.
+ * @callback_destroyed: A #GDestroyNotify called when the listener is freed
+ * and data associated with the callback should be freed. Can be NULL.
+ *
+ * Create a new #AtspiDeviceListener with a specified callback function.
+ * Like atspi_device_listener_new, but callback takes no user data.
+ *
+ * Returns: a pointer to a newly-created #AtspiDeviceListener.
+ *
+ **/
+AtspiDeviceListener *
+atspi_device_listener_new_simple (AtspiDeviceListenerSimpleCB callback,
+ GDestroyNotify callback_destroyed)
+{
+ return atspi_device_listener_new (device_remove_datum, callback_destroyed, callback);
+}
+
+/**
* atspi_device_listener_add_callback:
* @listener: the #AtspiDeviceListener instance to modify.
- * @callback: (scope call): an #AtspiDeviceListenerCB function pointer.
+ * @callback: (scope notify): an #AtspiDeviceListenerCB function pointer.
* @user_data: (closure): a pointer to data which will be passed to the
* callback when invoked.
+ * @callback_destroyed: A #GDestroyNotify called when the listener is freed
+ * and data associated with the callback should be freed. Can be NULL.
*
* Add an in-process callback function to an existing #AtspiDeviceListener.
*
void
atspi_device_listener_add_callback (AtspiDeviceListener *listener,
AtspiDeviceListenerCB callback,
+ GDestroyNotify callback_destroyed,
void *user_data)
{
g_return_if_fail (ATSPI_IS_DEVICE_LISTENER (listener));
+ DeviceEventHandler *new_handler;
- listener->callbacks = g_list_prepend (listener->callbacks,
- device_event_handler_new ((void *)callback, user_data));
+ new_handler = device_event_handler_new (callback,
+ callback_destroyed, user_data);
+
+ if (new_handler)
+ {
+ GList *new_list;
+ new_list = g_list_prepend (listener->callbacks, new_handler);
+ if (new_list)
+ listener->callbacks = new_list;
+ }
}
/**
{
return g_strdup_printf ("/org/a11y/atspi/listeners/%d", listener->id);
}
+
+G_DEFINE_BOXED_TYPE (AtspiDeviceEvent,
+ atspi_device_event,
+ atspi_device_event_copy,
+ atspi_device_event_free)
/**
* AtspiDeviceListenerCB:
- * @stroke: The #AtspiDeviceEvent for which notification is being received.
+ * @stroke: (transfer full): The #AtspiDeviceEvent for which notification is
+ * being received.
* @user_data: Data which is passed to the client each time this callback is notified.
*
* A callback function prototype via which clients receive device event notifications.
typedef gboolean (*AtspiDeviceListenerCB) (const AtspiDeviceEvent *stroke,
void *user_data);
+/**
+ * AtspiDeviceListenerSimpleCB:
+ * @stroke: (transfer full): The #AtspiDeviceEvent for which notification is
+ * being received.
+ *
+ * Like #AtspiDeviceListenerCB but with no user data.
+ *
+ * Returns: %TRUE if the client wishes to consume/preempt the event, preventing it from being
+ * relayed to the currently focussed application, %FALSE if the event delivery should proceed as normal.
+ **/
+typedef gboolean (*AtspiDeviceListenerSimpleCB) (const AtspiDeviceEvent *stroke);
+
#define ATSPI_TYPE_DEVICE_LISTENER (atspi_device_listener_get_type ())
#define ATSPI_DEVICE_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ATSPI_TYPE_DEVICE_LISTENER, AtspiDeviceListener))
#define ATSPI_DEVICE_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ATSPI_TYPE_DEVICE_LISTENER, AtspiDeviceListenerClass))
GType atspi_device_listener_get_type (void);
-AtspiDeviceListener *atspi_device_listener_new (AtspiDeviceListenerCB callback);
+AtspiDeviceListener *atspi_device_listener_new (AtspiDeviceListenerCB callback, GDestroyNotify callback_destroyed, void *user_data);
+
+AtspiDeviceListener *atspi_device_listener_new_simple (AtspiDeviceListenerSimpleCB callback, GDestroyNotify callback_destroyed);
-void atspi_device_listener_add_callback (AtspiDeviceListener *listener, AtspiDeviceListenerCB callback, void *user_data);
+void atspi_device_listener_add_callback (AtspiDeviceListener *listener, AtspiDeviceListenerCB callback, GDestroyNotify callback_destroyed, void *user_data);
void atspi_device_listener_remove_callback (AtspiDeviceListener *listener, AtspiDeviceListenerCB callback);
#endif /* _ATSPI_DEVICE_LISTENER_H_ */
callback_ref (remove_datum, callback_destroyed);
listener->user_data = callback;
listener->cb_destroyed = callback_destroyed;
+ return listener;
}
static GList *event_listeners = NULL;
{
gchar *d = g_strdup (s);
gchar *p;
+ int parts = 0;
if (!d)
return NULL;
}
else if (*p == ':')
{
+ parts++;
+ if (parts == 2)
+ break;
p [1] = toupper (p [1]);
}
}
event_type);
}
+static AtspiEvent *
+atspi_event_copy (AtspiEvent *src)
+{
+ AtspiEvent *dst = g_new0 (AtspiEvent, 1);
+ dst->type = g_strdup (src->type);
+ dst->source = g_object_ref (src->source);
+ dst->detail1 = src->detail1;
+ dst->detail2 = src->detail2;
+ dst->any_data.g_type = src->any_data.g_type;
+ g_value_copy (&dst->any_data, &src->any_data);
+ return dst;
+}
+
+static void
+atspi_event_free (AtspiEvent *event)
+{
+ g_object_unref (event->source);
+ g_free (event->type);
+ g_value_unset (&event->any_data);
+ g_free (event);
+}
+
void
_atspi_send_event (AtspiEvent *e)
{
/* Ensure that the value is set to avoid a Python exception */
/* TODO: Figure out how to do this without using a private field */
if (e->any_data.g_type == 0)
+ {
+ g_value_init (&e->any_data, G_TYPE_INT);
g_value_set_int (&e->any_data, 0);
+ }
if (!convert_event_type_to_dbus (e->type, &category, &name, &detail, NULL))
{
(entry->name == NULL || !strcmp (name, entry->name)) &&
(entry->detail == NULL || !strcmp (detail, entry->detail)))
{
- entry->callback (e, entry->user_data);
+ entry->callback (atspi_event_copy (e), entry->user_data);
}
}
if (detail) g_free (detail);
case DBUS_TYPE_STRING:
{
dbus_message_iter_get_basic (&iter_variant, &p);
+ g_value_init (&e.any_data, G_TYPE_STRING);
g_value_set_string (&e.any_data, p);
break;
}
return DBUS_HANDLER_RESULT_HANDLED;
}
-static AtspiEvent *
-atspi_event_copy (AtspiEvent *src)
-{
- AtspiEvent *dst = g_new0 (AtspiEvent, 1);
- dst->type = g_strdup (src->type);
- dst->detail1 = src->detail1;
- dst->detail2 = src->detail2;
- g_value_copy (&dst->any_data, &src->any_data);
-}
-
-static void
-atspi_event_free (AtspiEvent *event)
-{
- g_object_unref (event->source);
- g_free (event->type);
- g_value_unset (&event->any_data);
- g_free (event);
-}
-
G_DEFINE_BOXED_TYPE (AtspiEvent, atspi_event, atspi_event_copy, atspi_event_free)
#include "atspi-types.h"
+GType atspi_event_get_type (void);
+
/**
* AtspiEventListenerCB:
- * @event: The event for which notification is sent.
+ * @event: (transfer full): The event for which notification is sent.
* @user_data: User data which is passed to the callback each time a notification takes place.
*
* A function prototype for callbacks via which clients are notified of AT-SPI events.
/**
* AtspiEventListenerSimpleCB:
- * @event: The event for which notification is sent.
+ * @event: (transfer full): The event for which notification is sent.
*
* Like #AtspiEventlistenerCB, but with no user_data.
*
--- /dev/null
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2002 Ximian, Inc.
+ * 2002 Sun Microsystems Inc.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATSPI_MATCH_RULE_PRIVATE_H_
+#define _ATSPI_MATCH_RULE_PRIVATE_H_
+
+#include "glib-object.h"
+
+#include "atspi-matchrule.h"
+#include "dbus/dbus.h"
+
+gboolean
+_atspi_match_rule_marshal (AtspiMatchRule *rule, DBusMessageIter *iter);
+
+#endif /* _ATSPI_MATCH_RULE_PRIVATE_H_ */
AtspiCollectionMatchType interfacematchtype,
gboolean invert);
-gboolean
-_atspi_match_rule_marshal (AtspiMatchRule *rule, DBusMessageIter *iter);
-
#endif /* _ATSPI_MATCH_RULE_H_ */
{
return atspi_dbus_handle_event (bus, message, data);
}
- if (dbus_message_is_method_call (message, atspi_interface_device_event_listener, "notifyEvent"))
+ if (dbus_message_is_method_call (message, atspi_interface_device_event_listener, "NotifyEvent"))
{
- g_warning ("atspi: TODO: DeviceEvent");
- //return handle_device_event (bus, message, data);
+ return atspi_dbus_handle_DeviceEvent (bus, message, data);
}
if (dbus_message_is_signal (message, atspi_interface_cache, "AddAccessible"))
{
#include "atspi-device-listener-private.h"
#include "atspi-event-listener-private.h"
+#include "atspi-matchrule-private.h"
#include "atspi-misc-private.h"
#include "atspi.h"
/**
* ATSPI_KEYSET_ALL_KEYS:
- * @ATSPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
+ * @ATSPI_KEYSET_ALL_KEYS: A special value for an AtspiKeySet type, which tacitly
* includes all keycodes and keyvals for the specified modifier set.
**/
/**
- * atspi_register_accessible_keystroke_listener:
- * @listener: a pointer to the #AccessibleKeystrokeListener for which
+ * atspi_register_keystroke_listener:
+ * @listener: a pointer to the #AtspiDeviceListener for which
* keystroke events are requested.
- * @key_set: (type: AtspiKeyDefinition): a pointer to the
- * #AccessibleKeyDefinition array indicating which keystroke events are requested, or #ATSPI_KEYSET_ALL_KEYS
+ * @key_set: (element-type AtspiKeyDefinition): a pointer to the
+ * #AtspiKeyDefinition array indicating which keystroke events are requested, or #ATSPI_KEYSET_ALL_KEYS
* to indicate that all keycodes and keyvals for the specified
* modifier set are to be included.
* @modmask: an #AtspiKeyMaskType mask indicating which
* events will only be reported for key events for which all
* modifiers in @modmask are set. If you wish to listen for
* events with multiple modifier combinations you must call
- * register_accessible_keystroke_listener() once for each
+ * register_keystroke_listener() once for each
* combination.
* @eventmask: an #AtspiKeyMaskType mask indicating which
* types of key events are requested (#ATSPI_KEY_PRESSED, etc.).
* Returns: #TRUE if successful, otherwise #FALSE.
**/
gboolean
-atspi_register_accessible_keystroke_listener (AtspiDeviceListener *listener,
+atspi_register_keystroke_listener (AtspiDeviceListener *listener,
GArray *key_set,
AtspiKeyMaskType modmask,
AtspiKeyEventMask event_types,
dbus_error_init (&d_error);
dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "RegisterKeystrokeListener", &d_error, "oa(iisi)uu(bbb)=>b", path, d_key_set, d_modmask, d_event_types, &listener_mode, &retval);
- g_array_free (key_set, TRUE);
+ g_array_free (d_key_set, TRUE);
g_free (path);
return retval;
}
/**
- * atspi_deregister_accessible_keystroke_listener:
- * @listener: a pointer to the #AccessibleKeystrokeListener for which
+ * atspi_deregister_keystroke_listener:
+ * @listener: a pointer to the #AtspiDeviceListener for which
* keystroke events are requested.
* @modmask: the key modifier mask for which this listener is to be
* 'deregistered' (of type #AtspiKeyMaskType).
* Returns: #TRUE if successful, otherwise #FALSE.
**/
gboolean
-atspi_deregister_accessible_keystroke_listener (AtspiDeviceListener *listener,
+atspi_deregister_keystroke_listener (AtspiDeviceListener *listener,
AtspiKeyMaskType modmask, AtspiKeyEventMask event_types, GError **error)
{
gchar *path = _atspi_device_listener_get_path (listener);
* being synthesized; this type of keyboard event synthesis does
* not emulate hardware keypresses but injects the string
* as though a composing input method (such as XIM) were used.
- * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
+ * @synth_type: a #AtspiKeySynthType flag indicating whether @keyval
* is to be interpreted as a keysym rather than a keycode
* (ATSPI_KEYSYM), or whether to synthesize
* ATSPI_KEY_PRESS, ATSPI_KEY_RELEASE, or both (ATSPI_KEY_PRESSRELEASE).
dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "GenerateMouseEvent", &d_error, "iis", x, y, name);
return TRUE;
}
+
+AtspiKeyDefinition *
+atspi_key_definition_copy (AtspiKeyDefinition *src)
+{
+ AtspiKeyDefinition *dst;
+
+ dst = g_new0 (AtspiKeyDefinition, 1);
+ if (!dst)
+ return NULL;
+ dst->keycode = src->keycode;
+ dst->keysym = src->keysym;
+ if (src->keystring)
+ dst->keystring = g_strdup (src->keystring);
+ dst->unused = src->unused;
+ return dst;
+}
+
+void
+atspi_key_definition_free (AtspiKeyDefinition *kd)
+{
+ if (kd->keystring)
+ g_free (kd->keystring);
+ g_free (kd);
+}
+
+G_DEFINE_BOXED_TYPE (AtspiKeyDefinition, atspi_key_definition, atspi_key_definition_copy, atspi_key_definition_free)
#include "atspi-types.h"
#include "atspi-device-listener.h"
+GType atspi_key_definition_get_type ();
+
gint atspi_get_desktop_count ();
AtspiAccessible* atspi_get_desktop (gint i);
GArray *atspi_get_desktop_list ();
gboolean
-atspi_register_accessible_keystroke_listener (AtspiDeviceListener *listener,
+atspi_register_keystroke_listener (AtspiDeviceListener *listener,
GArray *key_set,
AtspiKeyMaskType modmask,
AtspiKeyEventMask event_types,
AtspiKeyListenerSyncType sync_type, GError **error);
gboolean
-atspi_deregister_accessible_keystroke_listener (AtspiDeviceListener *listener,
+atspi_deregister_keystroke_listener (AtspiDeviceListener *listener,
AtspiKeyMaskType modmask,
AtspiKeyEventMask event_types,
GError **error);
dbus_message_iter_next (iter);
}
+static const char *
+pass_complex_arg (const char *p, char begin, char end)
+{
+ int level = 1;
+
+ p++;
+ while (*p && level > 0)
+ {
+ if (*p == begin)
+ level++;
+ else if (*p == end)
+ level--;
+ p++;
+ }
+ if (*p == end)
+ p++;
+ return p;
+}
+
+static const char *
+pass_arg (const char *p)
+{
+ switch (*p)
+ {
+ case '(':
+ return pass_complex_arg (p, '(', ')');
+ case '{':
+ return pass_complex_arg (p, '{', '}');
+ case 'a':
+ return pass_arg (p+1);
+ default:
+ return p + 1;
+ }
+}
+
/*---------------------------------------------------------------------------*/
void
fprintf (stderr, "Unknown / invalid arg type %c\n", *p);
break;
}
- p++;
+ p = pass_arg (p);
}
if (p [0] == '=' && p[1] == '>')
{
GMainLoop *loop;
DBusMessage *reply;
+ guint timeout;
} SpiReentrantCallClosure;
static void
g_main_loop_quit (closure->loop);
}
+gboolean
+main_loop_timeout (SpiReentrantCallClosure *closure)
+{
+ g_main_loop_quit (closure->loop);
+ /* Returning TRUE because caller will remove the timer */
+ return TRUE;
+}
+
DBusMessage *
dbind_send_and_allow_reentry (DBusConnection * bus, DBusMessage * message, DBusError *error)
{
dbus_bus_get_unique_name (bus)) != 0)
return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error);
+ /* TODO: Figure out why this isn't working */
+ return NULL;
if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout))
return NULL;
dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL);
closure.loop = g_main_loop_new (NULL, FALSE);
+ closure.reply = NULL;
dbus_connection_setup_with_g_main(bus, NULL);
if (1)
{
+ closure.timeout = g_timeout_add_seconds (2, main_loop_timeout, &closure);
g_main_loop_run (closure.loop);
+ g_source_remove (closure.timeout);
}
else
{