dbus_error_init (&error);
dbus_bus_add_match (bus, match, &error);
g_free (match);
- return !dbus_error_is_set (&error);
+ if (dbus_error_is_set (&error))
+ {
+ dbus_error_free (&error);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
}
else return FALSE;
}
dbus_error_init (&error);
dbus_bus_remove_match (bus, match, &error);
g_free (match);
- return !dbus_error_is_set (&error);
+ if (dbus_error_is_set (&error))
+ {
+ dbus_error_free (&error);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
}
else return FALSE;
}
if (dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_STRUCT,
NULL, &iter_substruct))
{
- dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
- &listener->mode->synchronous);
- dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
- &listener->mode->preemptive);
- dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
- &listener->mode->global);
+ if (listener->mode)
+ {
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &listener->mode->synchronous);
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &listener->mode->preemptive);
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &listener->mode->global);
+ }
+ else
+ {
+ dbus_bool_t dummy_val = FALSE;
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &dummy_val);
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &dummy_val);
+ dbus_message_iter_append_basic (&iter_substruct, DBUS_TYPE_BOOLEAN,
+ &dummy_val);
+ }
dbus_message_iter_close_container (&iter_struct, &iter_substruct);
}
dbus_message_iter_close_container (iter, &iter_struct);
*replyptr = dbus_pending_call_steal_reply (pending);
}
+static GSList *hung_processes = NULL;
+
+static void
+reset_hung_process (DBusPendingCall *pending, void *data)
+{
+ DBusMessage *message = data;
+ const char *dest = dbus_message_get_destination (message);
+ GSList *l;
+
+ /* At this point we don't care about the result */
+ dbus_pending_call_unref (pending);
+
+ for (l = hung_processes; l; l = l->next)
+ {
+ if (!strcmp (l->data, dest))
+ {
+ g_free (l->data);
+ hung_processes = g_slist_remove (hung_processes, l->data);
+ break;
+ }
+ }
+}
+
+static gint
+time_elapsed (struct timeval *origin)
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ return (tv.tv_sec - origin->tv_sec) * 1000 + (tv.tv_usec - origin->tv_usec) / 1000;
+}
+
+static void
+reset_hung_process_from_ping (DBusPendingCall *pending, void *data)
+{
+ gchar *bus_name = data;
+ GSList *l;
+
+ for (l = hung_processes; l; l = l->next)
+ {
+ if (!strcmp (l->data, data))
+ {
+ g_free (l->data);
+ hung_processes = g_slist_remove (hung_processes, l->data);
+ break;
+ }
+ }
+ g_free (data);
+ dbus_pending_call_unref (pending);
+}
+
static DBusMessage *
send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, DBusError *error)
{
DBusPendingCall *pending;
DBusMessage *reply = NULL;
+ struct timeval tv;
if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
{
return NULL;
}
dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL);
+ gettimeofday (&tv, NULL);
while (!reply)
{
- if (!dbus_connection_read_write_dispatch (bus, timeout))
+ if (!dbus_connection_read_write_dispatch (bus, timeout) ||
+ time_elapsed (&tv) > timeout)
+ {
+ const char *dest = dbus_message_get_destination (message);
+ GSList *l;
+ gchar *bus_name_dup;
+ dbus_message_ref (message);
+ dbus_pending_call_set_notify (pending, reset_hung_process, message,
+ (DBusFreeFunction) dbus_message_unref);
+ message = dbus_message_new_method_call (dest, "/",
+ "org.freedesktop.DBus.Peer",
+ "Ping");
+ if (!message)
+ return NULL;
+ dbus_connection_send_with_reply (bus, message, &pending, -1);
+ dbus_message_unref (message);
+ if (!pending)
+ return NULL;
+ bus_name_dup = g_strdup (dest);
+ dbus_pending_call_set_notify (pending, reset_hung_process_from_ping,
+ bus_name_dup, NULL);
+ for (l = hung_processes; l; l = l->next)
+ if (!strcmp (l->data, dest))
+ return NULL;
+ hung_processes = g_slist_prepend (hung_processes, g_strdup (dest));
return NULL;
+ }
}
dbus_pending_call_unref (pending);
return reply;
listener->path,
SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER,
"NotifyEvent");
- DBusError error;
dbus_bool_t consumed = FALSE;
+ GSList *l;
+ gboolean hung = FALSE;
+
+ for (l = hung_processes; l; l = l->next)
+ {
+ if (!strcmp (l->data, listener->bus_name))
+ {
+ dbus_message_set_no_reply (message, TRUE);
+ hung = TRUE;
+ break;
+ }
+ }
- dbus_error_init(&error);
if (spi_dbus_marshal_deviceEvent(message, key_event))
{
- DBusMessage *reply = send_and_allow_reentry (controller->bus, message, 1000, &error);
+ DBusMessage *reply;
+
+ if (hung)
+ {
+ dbus_connection_send (controller->bus, message, NULL);
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ reply = send_and_allow_reentry (controller->bus, message, 3000, NULL);
if (reply)
{
- DBusError error;
- dbus_error_init(&error);
- dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &consumed, DBUS_TYPE_INVALID);
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_BOOLEAN, &consumed, DBUS_TYPE_INVALID);
dbus_message_unref(reply);
}
}
{
SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
DEControllerListener *dec_listener;
- DBusError error;
const char *path;
dbus_int32_t event_types;
dbus_bool_t ret;
DBusMessage *reply = NULL;
- dbus_error_init(&error);
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
+ if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
{
return invalid_arguments_error (message);
}
dbus_message_iter_init(message, &iter);
if (strcmp (dbus_message_get_signature (message), "oa(iisi)uu") != 0)
+ {
+ g_warning ("Received DeregisterKeystrokeListener with strange signature '%s'", dbus_message_get_signature (message));
+ return invalid_arguments_error (message);
+ }
+
dbus_message_iter_get_basic(&iter, &path);
dbus_message_iter_next(&iter);
dbus_message_iter_recurse(&iter, &iter_array);
{
SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
DEControllerListener *listener;
- DBusError error;
const char *path;
dbus_int32_t event_types;
DBusMessage *reply = NULL;
- dbus_error_init(&error);
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
+ if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_UINT32, &event_types, DBUS_TYPE_INVALID))
{
return invalid_arguments_error (message);
}
static DBusMessage * impl_generate_keyboard_event (DBusConnection *bus, DBusMessage *message, void *user_data)
{
SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER(user_data);
- DBusError error;
dbus_int32_t keycode;
char *keystring;
dbus_uint32_t synth_type;
DEControllerPrivateData *priv;
DBusMessage *reply = NULL;
- dbus_error_init(&error);
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &keycode, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_UINT32, &synth_type, DBUS_TYPE_INVALID))
+ if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &keycode, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_UINT32, &synth_type, DBUS_TYPE_INVALID))
{
return invalid_arguments_error (message);
}
/* Accessibility::DEController::GenerateMouseEvent */
static DBusMessage * impl_generate_mouse_event (DBusConnection *bus, DBusMessage *message, void *user_data)
{
- DBusError error;
dbus_int32_t x;
dbus_int32_t y;
char *eventName;
gboolean err = FALSE;
Display *display = spi_get_display ();
- dbus_error_init (&error);
- if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_STRING, &eventName, DBUS_TYPE_INVALID))
+ if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_STRING, &eventName, DBUS_TYPE_INVALID))
{
return invalid_arguments_error (message);
}