summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--telepathy-glib/channel.c42
-rw-r--r--tools/glib-client-gen.py106
-rw-r--r--tools/libglibcodegen.py28
3 files changed, 155 insertions, 21 deletions
diff --git a/telepathy-glib/channel.c b/telepathy-glib/channel.c
index a943e588e..63943ec5b 100644
--- a/telepathy-glib/channel.c
+++ b/telepathy-glib/channel.c
@@ -1889,21 +1889,20 @@ tp_channel_join_finish (TpChannel *self,
_tp_implement_finish_void (self, tp_channel_join_async);
}
-/* tp_cli callbacks can potentially be called in a re-entrant way,
- * so we can't necessarily complete @result without using an idle. */
static void
-channel_close_cb (TpChannel *channel,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
+channel_close_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
GSimpleAsyncResult *result = user_data;
+ TpChannel *self = TP_CHANNEL (g_async_result_get_source_object (user_data));
+ GError *error = NULL;
- if (error != NULL)
+ if (!tp_cli_channel_close_finish (self, res, &error))
{
DEBUG ("Close() failed: %s", error->message);
- if (tp_proxy_get_invalidated (channel) == NULL)
+ if (tp_proxy_get_invalidated (self) == NULL)
{
g_simple_async_result_set_from_error (result, error);
}
@@ -1911,9 +1910,11 @@ channel_close_cb (TpChannel *channel,
{
DEBUG ("... but channel was already invalidated, so never mind");
}
+
+ g_error_free (error);
}
- g_simple_async_result_complete_in_idle (result);
+ g_simple_async_result_complete (result);
g_object_unref (result);
}
@@ -1934,8 +1935,8 @@ channel_remove_self_cb (TpChannel *channel,
DEBUG ("RemoveMembersWithDetails() with self handle failed; call Close()"
" %s", error->message);
- tp_cli_channel_call_close (channel, -1, channel_close_cb, result,
- NULL, NULL);
+ tp_cli_channel_close_async (channel, NULL, NULL, channel_close_cb,
+ result);
return;
}
@@ -2015,8 +2016,8 @@ group_prepared_cb (GObject *source,
return;
call_close:
- tp_cli_channel_call_close (self, -1, channel_close_cb,
- g_object_ref (ctx->result), NULL, NULL);
+ tp_cli_channel_close_async (self, NULL, NULL, channel_close_cb,
+ g_object_ref (ctx->result));
leave_ctx_free (ctx);
}
@@ -2065,8 +2066,8 @@ tp_channel_leave_async (TpChannel *self,
{
DEBUG ("Channel doesn't implement Group; fallback to Close()");
- tp_cli_channel_call_close (self, -1, channel_close_cb, result,
- NULL, NULL);
+ tp_cli_channel_close_async (self, NULL, NULL, channel_close_cb,
+ result);
return;
}
@@ -2130,8 +2131,7 @@ tp_channel_close_async (TpChannel *self,
result = g_simple_async_result_new (G_OBJECT (self), callback,
user_data, tp_channel_close_async);
- tp_cli_channel_call_close (self, -1, channel_close_cb, result,
- NULL, NULL);
+ tp_cli_channel_close_async (self, NULL, NULL, channel_close_cb, result);
}
/**
@@ -2167,8 +2167,8 @@ channel_destroy_cb (TpChannel *channel,
{
DEBUG ("Destroy() failed; call Close(): %s", error->message);
- tp_cli_channel_call_close (channel, -1, channel_close_cb, result,
- NULL, NULL);
+ tp_cli_channel_close_async (channel, NULL, NULL, channel_close_cb,
+ result);
return;
}
@@ -2210,8 +2210,8 @@ tp_channel_destroy_async (TpChannel *self,
{
DEBUG ("Channel doesn't implement Destroy; fallback to Close()");
- tp_cli_channel_call_close (self, -1, channel_close_cb, result,
- NULL, NULL);
+ tp_cli_channel_close_async (self, NULL, NULL, channel_close_cb,
+ result);
return;
}
diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py
index e2ea3fc7b..94886cbca 100644
--- a/tools/glib-client-gen.py
+++ b/tools/glib-client-gen.py
@@ -414,6 +414,8 @@ class Generator(object):
ret_count = 0
in_args = []
out_args = []
+ in_signature = ''
+ out_signature = ''
for arg in method.getElementsByTagName('arg'):
name = arg.getAttribute('name')
@@ -437,8 +439,10 @@ class Generator(object):
info = type_to_gtype(type)
if direction != 'out':
in_args.append((name, info, tp_type, arg))
+ in_signature = in_signature + type
else:
out_args.append((name, info, tp_type, arg))
+ out_signature = out_signature + type
# Async reply callback type
@@ -871,6 +875,108 @@ class Generator(object):
self.do_method_reentrant(method, iface_lc, member, member_lc,
in_args, out_args, collect_callback)
+ # Async stub (GVariant-style)
+
+ # Example:
+ # void tp_cli_dbus_properties_get_properties_async
+ # (gpointer proxy,
+ # GVariant *parameters,
+ # GCancellable *cancellable,
+ # GAsyncReadyCallback callback,
+ # gpointer user_data);
+ # GVariant *tp_cli_dbus_properties_get_properties_finish
+ # (gpointer proxy,
+
+ async_name = '%s_%s_%s_async' % (self.prefix_lc, iface_lc, member_lc)
+ finish_name = '%s_%s_%s_finish' % (self.prefix_lc, iface_lc, member_lc)
+
+ self.d('/**')
+ self.d(' * %s:' % async_name)
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @parameters: a #GVariant of type "(%s)"' % in_signature)
+ self.d(' * @cancellable: %NULL or a cancellation object')
+ self.d(' * @callback: a #GAsyncReadyCallback to call when the method')
+ self.d(' * returns, times out or is cancelled, or %NULL')
+ self.d(' * @user_data: user data for @callback')
+ self.d(' *')
+ self.d(' * Call the D-Bus method "%s.%s".' % (self.iface_dbus, member))
+ self.d(' *')
+ self.d(' * If @parameters is a floating #GVariant reference, it is')
+ self.d(' * consumed, allowing for convenient "inline" use of')
+ self.d(' * g_variant_new() (as for g_dbus_connection_call()).')
+ self.d(' */')
+
+ self.d('/**')
+ self.d(' * %s:' % finish_name)
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @result: a result from the #GAsyncReadyCallback')
+ self.d(' * @error: return location for error or %NULL')
+ self.d(' *')
+ self.d(' * Examine the result of the D-Bus method "%s.%s".'
+ % (self.iface_dbus, member))
+ self.d(' *')
+ self.d(' * If a faulty implementation of the method returns an')
+ self.d(' * unexpected signature, it is turned into a #GError')
+ self.d(' * and %NULL is returned instead.')
+ self.d(' *')
+ self.d(' * Returns: (transfer full): a #GVariant of type "(%s)"'
+ % out_signature)
+ self.d(' * or %NULL on error')
+ self.d(' */')
+
+ self.h('#ifndef __GTK_DOC_IGNORE__')
+ self.h('static inline')
+ self.h('#endif /* __GTK_DOC_IGNORE__ */')
+ self.h('void %s (%s proxy,' % (async_name, self.proxy_arg))
+ self.h(' GVariant *parameters,')
+ self.h(' GCancellable *cancellable,')
+ self.h(' GAsyncReadyCallback callback,')
+ self.h(' gpointer user_data);')
+
+ self.h('#ifndef __GTK_DOC_IGNORE__')
+ self.h('static inline')
+ self.h('#endif /* __GTK_DOC_IGNORE__ */')
+ self.h('GVariant *%s (%s proxy,' % (finish_name, self.proxy_arg))
+ self.h(' GAsyncResult *result,')
+ self.h(' GError **error);')
+
+ self.h('#ifndef __GTK_DOC_IGNORE__')
+ self.h('static inline void')
+ self.h('%s (%s proxy,' % (async_name, self.proxy_arg))
+ self.h(' GVariant *parameters,')
+ self.h(' GCancellable *cancellable,')
+ self.h(' GAsyncReadyCallback callback,')
+ self.h(' gpointer user_data)')
+ self.h('{')
+ self.h(' TpProxy *cast_to_proxy = (TpProxy *) proxy;')
+ self.h('')
+ self.h(' g_return_if_fail (%s (proxy));' % self.proxy_assert)
+ self.h(' g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));')
+ self.h(' g_return_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(%s)")));' % in_signature)
+ self.h(' dbus_g_connection_call_async (cast_to_proxy->dbus_connection,')
+ self.h(' cast_to_proxy->bus_name,')
+ self.h(' cast_to_proxy->object_path,')
+ self.h(' "%s",' % self.iface_dbus)
+ self.h(' "%s",' % member)
+ self.h(' parameters,')
+ self.h(' G_VARIANT_TYPE ("(%s)"),' % out_signature)
+ self.h(' G_DBUS_CALL_FLAGS_NONE,')
+ self.h(' -1,')
+ self.h(' cancellable,')
+ self.h(' callback,')
+ self.h(' user_data);')
+ self.h(' g_variant_ref_sink (parameters);')
+ self.h(' g_variant_unref (parameters);')
+ self.h('}')
+ self.h('static inline GVariant *')
+ self.h('%s (%s proxy,' % (finish_name, self.proxy_arg))
+ self.h(' GAsyncResult *result,')
+ self.h(' GError **error)')
+ self.h('{')
+ self.h(' return dbus_g_connection_call_finish (result, error);')
+ self.h('}')
+ self.h('#endif /* __GTK_DOC_IGNORE__ */')
+
# leave a gap for the end of the method
self.d('')
self.b('')
diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py
index 6a9d21485..3bd9ee3db 100644
--- a/tools/libglibcodegen.py
+++ b/tools/libglibcodegen.py
@@ -170,3 +170,31 @@ def type_to_gtype(s):
# we just don't know ..
raise Exception, "don't know the GType for " + s
+
+def type_to_gdbus_info(s):
+ if s == 'y': #byte
+ return dict(ctype='guchar ')
+ elif s == 'b': #boolean
+ return dict(ctype='gboolean ')
+ elif s == 'n': #int16
+ return dict(ctype='gint16 ')
+ elif s == 'q': #uint16
+ return dict(ctype='guint16 ')
+ elif s == 'i': #int32
+ return dict(ctype='gint32 ')
+ elif s == 'u': #uint32
+ return dict(ctype='guint32 ')
+ elif s == 'x': #int64
+ return dict(ctype='gint64 ')
+ elif s == 't': #uint64
+ return dict(ctype='guint64 ')
+ elif s == 'd': #double
+ return dict(ctype='gdouble ')
+ elif s == 's': #string
+ return dict(ctype='gchar *', pointer=True)
+ elif s == 'g': #signature - FIXME
+ return dict(ctype='gchar *', pointer=True)
+ elif s == 'o': #object path
+ return dict(ctype='gchar *', pointer=True)
+ else:
+ return dict(ctype='GVariant *', pointer=True, variant=True)