mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-15 20:18:05 +02:00
gdbus-codegen: Add support for new org.gtk.GDBus.C.UnixFD annotation
Also add convenience _with_unix_fd_list variants to GDBusConnection, GDBusProxy and GDBusMethodInvocation types to easily support this. Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
7b22a8308f
commit
c404dbed11
@ -332,6 +332,18 @@ gdbus-codegen --c-namespace MyApp \
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>org.gtk.GDBus.C.UnixFD</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If set to a non-empty string, the generated code will
|
||||||
|
include parameters to exchange file descriptors using the
|
||||||
|
#GUnixFDList type. This annotation can be used on
|
||||||
|
<literal><method></literal> elements.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -744,8 +756,7 @@ on_handle_hello_world (MyAppFrobber *interface,
|
|||||||
<link linkend="G-VARIANT-TYPE-INT32:CAPS">'i'</link>,
|
<link linkend="G-VARIANT-TYPE-INT32:CAPS">'i'</link>,
|
||||||
<link linkend="G-VARIANT-TYPE-UINT32:CAPS">'u'</link>,
|
<link linkend="G-VARIANT-TYPE-UINT32:CAPS">'u'</link>,
|
||||||
<link linkend="G-VARIANT-TYPE-INT64:CAPS">'x'</link>,
|
<link linkend="G-VARIANT-TYPE-INT64:CAPS">'x'</link>,
|
||||||
<link linkend="G-VARIANT-TYPE-UINT64:CAPS">'t'</link>,
|
<link linkend="G-VARIANT-TYPE-UINT64:CAPS">'t'</link> and
|
||||||
<link linkend="G-VARIANT-TYPE-HANDLE:CAPS">'h'</link> and
|
|
||||||
<link linkend="G-VARIANT-TYPE-DOUBLE:CAPS">'d'</link>)
|
<link linkend="G-VARIANT-TYPE-DOUBLE:CAPS">'d'</link>)
|
||||||
),
|
),
|
||||||
strings (type-strings
|
strings (type-strings
|
||||||
@ -780,11 +791,7 @@ on_handle_hello_world (MyAppFrobber *interface,
|
|||||||
The generated C functions are guaranteed to not change their ABI
|
The generated C functions are guaranteed to not change their ABI
|
||||||
that is, if a method, signal or property does not change its
|
that is, if a method, signal or property does not change its
|
||||||
signature in the introspection XML, the generated C functions will
|
signature in the introspection XML, the generated C functions will
|
||||||
not change its C ABI either. One exception to this guarantee is if
|
not change its C ABI either.
|
||||||
you are using type <link
|
|
||||||
linkend="G-VARIANT-TYPE-HANDLE:CAPS">'h'</link> for passing file
|
|
||||||
descriptors on Unix. Future versions of gdbus-codegen will include
|
|
||||||
guarantees for this type as well.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The ABI of the generated #GType<!-- -->s will be preserved only if
|
The ABI of the generated #GType<!-- -->s will be preserved only if
|
||||||
|
@ -2468,6 +2468,9 @@ GDBusCallFlags
|
|||||||
g_dbus_connection_call
|
g_dbus_connection_call
|
||||||
g_dbus_connection_call_finish
|
g_dbus_connection_call_finish
|
||||||
g_dbus_connection_call_sync
|
g_dbus_connection_call_sync
|
||||||
|
g_dbus_connection_call_with_unix_fd_list
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_finish
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_sync
|
||||||
g_dbus_connection_emit_signal
|
g_dbus_connection_emit_signal
|
||||||
GDBusSignalFlags
|
GDBusSignalFlags
|
||||||
GDBusSignalCallback
|
GDBusSignalCallback
|
||||||
@ -2522,6 +2525,7 @@ g_dbus_method_invocation_return_error_literal
|
|||||||
g_dbus_method_invocation_return_gerror
|
g_dbus_method_invocation_return_gerror
|
||||||
g_dbus_method_invocation_return_dbus_error
|
g_dbus_method_invocation_return_dbus_error
|
||||||
g_dbus_method_invocation_take_error
|
g_dbus_method_invocation_take_error
|
||||||
|
g_dbus_method_invocation_return_value_with_unix_fd_list
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
G_DBUS_METHOD_INVOCATION
|
G_DBUS_METHOD_INVOCATION
|
||||||
G_IS_DBUS_METHOD_INVOCATION
|
G_IS_DBUS_METHOD_INVOCATION
|
||||||
@ -2602,6 +2606,9 @@ g_dbus_proxy_get_interface_info
|
|||||||
g_dbus_proxy_call
|
g_dbus_proxy_call
|
||||||
g_dbus_proxy_call_finish
|
g_dbus_proxy_call_finish
|
||||||
g_dbus_proxy_call_sync
|
g_dbus_proxy_call_sync
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_finish
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_sync
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
G_DBUS_PROXY
|
G_DBUS_PROXY
|
||||||
G_IS_DBUS_PROXY
|
G_IS_DBUS_PROXY
|
||||||
|
@ -63,6 +63,11 @@ class CodeGenerator:
|
|||||||
'#include "%s"\n'
|
'#include "%s"\n'
|
||||||
'\n'%(self.h.name))
|
'\n'%(self.h.name))
|
||||||
|
|
||||||
|
self.c.write('#ifdef G_OS_UNIX\n'
|
||||||
|
'# include <gio/gunixfdlist.h>\n'
|
||||||
|
'#endif\n'
|
||||||
|
'\n')
|
||||||
|
|
||||||
self.c.write('typedef struct\n'
|
self.c.write('typedef struct\n'
|
||||||
'{\n'
|
'{\n'
|
||||||
' GDBusArgInfo parent_struct;\n'
|
' GDBusArgInfo parent_struct;\n'
|
||||||
@ -74,6 +79,7 @@ class CodeGenerator:
|
|||||||
'{\n'
|
'{\n'
|
||||||
' GDBusMethodInfo parent_struct;\n'
|
' GDBusMethodInfo parent_struct;\n'
|
||||||
' const gchar *signal_name;\n'
|
' const gchar *signal_name;\n'
|
||||||
|
' gboolean pass_fdlist;\n'
|
||||||
'} _ExtendedGDBusMethodInfo;\n'
|
'} _ExtendedGDBusMethodInfo;\n'
|
||||||
'\n')
|
'\n')
|
||||||
|
|
||||||
@ -242,10 +248,15 @@ class CodeGenerator:
|
|||||||
if len(i.methods) > 0:
|
if len(i.methods) > 0:
|
||||||
self.h.write('\n')
|
self.h.write('\n')
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
key = (m.since, '_method_%s'%m.name_lower)
|
key = (m.since, '_method_%s'%m.name_lower)
|
||||||
value = ' gboolean (*handle_%s) (\n'%(m.name_lower)
|
value = ' gboolean (*handle_%s) (\n'%(m.name_lower)
|
||||||
value += ' %s *object,\n'%(i.camel_name)
|
value += ' %s *object,\n'%(i.camel_name)
|
||||||
value += ' GDBusMethodInvocation *invocation'%()
|
value += ' GDBusMethodInvocation *invocation'%()
|
||||||
|
if unix_fd:
|
||||||
|
value += ',\n GUnixFDList *fd_list'
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
value += ',\n %s%s'%(a.ctype_in, a.name)
|
value += ',\n %s%s'%(a.ctype_in, a.name)
|
||||||
value += ');\n\n'
|
value += ');\n\n'
|
||||||
@ -291,11 +302,16 @@ class CodeGenerator:
|
|||||||
self.h.write('\n')
|
self.h.write('\n')
|
||||||
self.h.write('/* D-Bus method call completion functions: */\n')
|
self.h.write('/* D-Bus method call completion functions: */\n')
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
if m.deprecated:
|
if m.deprecated:
|
||||||
self.h.write('G_GNUC_DEPRECATED ')
|
self.h.write('G_GNUC_DEPRECATED ')
|
||||||
self.h.write('void %s_complete_%s (\n'
|
self.h.write('void %s_complete_%s (\n'
|
||||||
' %s *object,\n'
|
' %s *object,\n'
|
||||||
' GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
|
' GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
|
if unix_fd:
|
||||||
|
self.h.write(',\n GUnixFDList *fd_list')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
self.h.write(');\n')
|
self.h.write(');\n')
|
||||||
@ -322,6 +338,9 @@ class CodeGenerator:
|
|||||||
self.h.write('\n')
|
self.h.write('\n')
|
||||||
self.h.write('/* D-Bus method calls: */\n')
|
self.h.write('/* D-Bus method calls: */\n')
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
# async begin
|
# async begin
|
||||||
if m.deprecated:
|
if m.deprecated:
|
||||||
self.h.write('G_GNUC_DEPRECATED ')
|
self.h.write('G_GNUC_DEPRECATED ')
|
||||||
@ -329,6 +348,8 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.h.write(',\n GUnixFDList *fd_list')
|
||||||
self.h.write(',\n'
|
self.h.write(',\n'
|
||||||
' GCancellable *cancellable,\n'
|
' GCancellable *cancellable,\n'
|
||||||
' GAsyncReadyCallback callback,\n'
|
' GAsyncReadyCallback callback,\n'
|
||||||
@ -341,6 +362,8 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.h.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
self.h.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.h.write(',\n GUnixFDList **out_fd_list')
|
||||||
self.h.write(',\n'
|
self.h.write(',\n'
|
||||||
' GAsyncResult *res,\n'
|
' GAsyncResult *res,\n'
|
||||||
' GError **error);\n')
|
' GError **error);\n')
|
||||||
@ -352,8 +375,12 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.h.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.h.write(',\n GUnixFDList *fd_list')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.h.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
self.h.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.h.write(',\n GUnixFDList **out_fd_list')
|
||||||
self.h.write(',\n'
|
self.h.write(',\n'
|
||||||
' GCancellable *cancellable,\n'
|
' GCancellable *cancellable,\n'
|
||||||
' GError **error);\n')
|
' GError **error);\n')
|
||||||
@ -749,6 +776,9 @@ class CodeGenerator:
|
|||||||
|
|
||||||
if len(i.methods) > 0:
|
if len(i.methods) > 0:
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
self.generate_args('_%s_method_info_%s_IN_ARG'%(i.name_lower, m.name_lower), m.in_args)
|
self.generate_args('_%s_method_info_%s_IN_ARG'%(i.name_lower, m.name_lower), m.in_args)
|
||||||
self.generate_args('_%s_method_info_%s_OUT_ARG'%(i.name_lower, m.name_lower), m.out_args)
|
self.generate_args('_%s_method_info_%s_OUT_ARG'%(i.name_lower, m.name_lower), m.out_args)
|
||||||
|
|
||||||
@ -772,8 +802,9 @@ class CodeGenerator:
|
|||||||
else:
|
else:
|
||||||
self.c.write(' (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n'%(i.name_lower, m.name_lower))
|
self.c.write(' (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n'%(i.name_lower, m.name_lower))
|
||||||
self.c.write(' },\n'
|
self.c.write(' },\n'
|
||||||
' "handle-%s"\n'
|
' "handle-%s",\n'
|
||||||
%(m.name_hyphen))
|
' %s\n'
|
||||||
|
%(m.name_hyphen, 'TRUE' if unix_fd else 'FALSE'))
|
||||||
self.c.write('};\n'
|
self.c.write('};\n'
|
||||||
'\n')
|
'\n')
|
||||||
|
|
||||||
@ -980,12 +1011,17 @@ class CodeGenerator:
|
|||||||
if len(i.methods) > 0:
|
if len(i.methods) > 0:
|
||||||
self.c.write(' /* GObject signals for incoming D-Bus method calls: */\n')
|
self.c.write(' /* GObject signals for incoming D-Bus method calls: */\n')
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
' /**\n'
|
' /**\n'
|
||||||
' * %s::handle-%s:\n'
|
' * %s::handle-%s:\n'
|
||||||
' * @object: A #%s.\n'
|
' * @object: A #%s.\n'
|
||||||
' * @invocation: A #GDBusMethodInvocation.\n'
|
' * @invocation: A #GDBusMethodInvocation.\n'
|
||||||
%(i.camel_name, m.name_hyphen, i.camel_name), False))
|
%(i.camel_name, m.name_hyphen, i.camel_name), False))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write (' * @fd_list: (allow-none): A #GUnixFDList or %NULL.\n')
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write (' * @%s: Argument passed by remote caller.\n'%(a.name))
|
self.c.write (' * @%s: Argument passed by remote caller.\n'%(a.name))
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
@ -997,6 +1033,10 @@ class CodeGenerator:
|
|||||||
' * Returns: %%TRUE if the invocation was handled, %%FALSE to let other signal handlers run.\n'
|
' * Returns: %%TRUE if the invocation was handled, %%FALSE to let other signal handlers run.\n'
|
||||||
%(i.name, m.name, i.name_lower, m.name_lower), False))
|
%(i.name, m.name, i.name_lower, m.name_lower), False))
|
||||||
self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 2)
|
self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 2)
|
||||||
|
if unix_fd:
|
||||||
|
extra_args = 2
|
||||||
|
else:
|
||||||
|
extra_args = 1
|
||||||
self.c.write(' g_signal_new ("handle-%s",\n'
|
self.c.write(' g_signal_new ("handle-%s",\n'
|
||||||
' G_TYPE_FROM_INTERFACE (iface),\n'
|
' G_TYPE_FROM_INTERFACE (iface),\n'
|
||||||
' G_SIGNAL_RUN_LAST,\n'
|
' G_SIGNAL_RUN_LAST,\n'
|
||||||
@ -1007,7 +1047,9 @@ class CodeGenerator:
|
|||||||
' G_TYPE_BOOLEAN,\n'
|
' G_TYPE_BOOLEAN,\n'
|
||||||
' %d,\n'
|
' %d,\n'
|
||||||
' G_TYPE_DBUS_METHOD_INVOCATION'
|
' G_TYPE_DBUS_METHOD_INVOCATION'
|
||||||
%(m.name_hyphen, i.camel_name, m.name_lower, len(m.in_args) + 1))
|
%(m.name_hyphen, i.camel_name, m.name_lower, len(m.in_args) + extra_args))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(', G_TYPE_UNIX_FD_LIST')
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write (', %s'%(a.gtype))
|
self.c.write (', %s'%(a.gtype))
|
||||||
self.c.write(');\n')
|
self.c.write(');\n')
|
||||||
@ -1212,6 +1254,9 @@ class CodeGenerator:
|
|||||||
|
|
||||||
def generate_method_calls(self, i):
|
def generate_method_calls(self, i):
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
# async begin
|
# async begin
|
||||||
self.c.write('/**\n'
|
self.c.write('/**\n'
|
||||||
' * %s_call_%s:\n'
|
' * %s_call_%s:\n'
|
||||||
@ -1219,6 +1264,8 @@ class CodeGenerator:
|
|||||||
%(i.name_lower, m.name_lower, i.camel_name))
|
%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
|
self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(' * @fd_list: (allow-none): A #GUnixFDList or %NULL.\n')
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
|
' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
|
||||||
' * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n'
|
' * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n'
|
||||||
@ -1236,13 +1283,18 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(',\n GUnixFDList *fd_list')
|
||||||
self.c.write(',\n'
|
self.c.write(',\n'
|
||||||
' GCancellable *cancellable,\n'
|
' GCancellable *cancellable,\n'
|
||||||
' GAsyncReadyCallback callback,\n'
|
' GAsyncReadyCallback callback,\n'
|
||||||
' gpointer user_data)\n'
|
' gpointer user_data)\n'
|
||||||
'{\n')
|
'{\n')
|
||||||
self.c.write(' g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n'
|
if unix_fd:
|
||||||
' "%s",\n'
|
self.c.write(' g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),\n')
|
||||||
|
else:
|
||||||
|
self.c.write(' g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n')
|
||||||
|
self.c.write(' "%s",\n'
|
||||||
' g_variant_new ("('%(m.name))
|
' g_variant_new ("('%(m.name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write('%s'%(a.format_in))
|
self.c.write('%s'%(a.format_in))
|
||||||
@ -1251,8 +1303,10 @@ class CodeGenerator:
|
|||||||
self.c.write(',\n %s'%(a.name))
|
self.c.write(',\n %s'%(a.name))
|
||||||
self.c.write('),\n'
|
self.c.write('),\n'
|
||||||
' G_DBUS_CALL_FLAGS_NONE,\n'
|
' G_DBUS_CALL_FLAGS_NONE,\n'
|
||||||
' -1,\n'
|
' -1,\n')
|
||||||
' cancellable,\n'
|
if unix_fd:
|
||||||
|
self.c.write(' fd_list,\n')
|
||||||
|
self.c.write(' cancellable,\n'
|
||||||
' callback,\n'
|
' callback,\n'
|
||||||
' user_data);\n')
|
' user_data);\n')
|
||||||
self.c.write('}\n'
|
self.c.write('}\n'
|
||||||
@ -1264,6 +1318,8 @@ class CodeGenerator:
|
|||||||
%(i.name_lower, m.name_lower, i.camel_name))
|
%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
|
self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(' * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n')
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n'
|
' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n'
|
||||||
' * @error: Return location for error or %%NULL.\n'
|
' * @error: Return location for error or %%NULL.\n'
|
||||||
@ -1278,13 +1334,18 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
self.c.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(',\n GUnixFDList **out_fd_list')
|
||||||
self.c.write(',\n'
|
self.c.write(',\n'
|
||||||
' GAsyncResult *res,\n'
|
' GAsyncResult *res,\n'
|
||||||
' GError **error)\n'
|
' GError **error)\n'
|
||||||
'{\n'
|
'{\n'
|
||||||
' GVariant *_ret;\n'
|
' GVariant *_ret;\n')
|
||||||
' _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n'
|
if unix_fd:
|
||||||
' if (_ret == NULL)\n'
|
self.c.write(' _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);\n')
|
||||||
|
else:
|
||||||
|
self.c.write(' _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n')
|
||||||
|
self.c.write(' if (_ret == NULL)\n'
|
||||||
' goto _out;\n')
|
' goto _out;\n')
|
||||||
self.c.write(' g_variant_get (_ret,\n'
|
self.c.write(' g_variant_get (_ret,\n'
|
||||||
' \"(')
|
' \"(')
|
||||||
@ -1308,8 +1369,12 @@ class CodeGenerator:
|
|||||||
%(i.name_lower, m.name_lower, i.camel_name))
|
%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
|
self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(' * @fd_list: (allow-none): A #GUnixFDList or %NULL.\n')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
|
self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(' * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n')
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
|
' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
|
||||||
' * @error: Return location for error or %%NULL.\n'
|
' * @error: Return location for error or %%NULL.\n'
|
||||||
@ -1326,15 +1391,22 @@ class CodeGenerator:
|
|||||||
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
' %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(',\n GUnixFDList *fd_list')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
self.c.write(',\n %sout_%s'%(a.ctype_out, a.name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(',\n GUnixFDList **out_fd_list')
|
||||||
self.c.write(',\n'
|
self.c.write(',\n'
|
||||||
' GCancellable *cancellable,\n'
|
' GCancellable *cancellable,\n'
|
||||||
' GError **error)\n'
|
' GError **error)\n'
|
||||||
'{\n'
|
'{\n'
|
||||||
' GVariant *_ret;\n')
|
' GVariant *_ret;\n')
|
||||||
self.c.write(' _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n'
|
if unix_fd:
|
||||||
' "%s",\n'
|
self.c.write(' _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),\n')
|
||||||
|
else:
|
||||||
|
self.c.write(' _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n')
|
||||||
|
self.c.write(' "%s",\n'
|
||||||
' g_variant_new ("('%(m.name))
|
' g_variant_new ("('%(m.name))
|
||||||
for a in m.in_args:
|
for a in m.in_args:
|
||||||
self.c.write('%s'%(a.format_in))
|
self.c.write('%s'%(a.format_in))
|
||||||
@ -1343,8 +1415,11 @@ class CodeGenerator:
|
|||||||
self.c.write(',\n %s'%(a.name))
|
self.c.write(',\n %s'%(a.name))
|
||||||
self.c.write('),\n'
|
self.c.write('),\n'
|
||||||
' G_DBUS_CALL_FLAGS_NONE,\n'
|
' G_DBUS_CALL_FLAGS_NONE,\n'
|
||||||
' -1,\n'
|
' -1,\n')
|
||||||
' cancellable,\n'
|
if unix_fd:
|
||||||
|
self.c.write(' fd_list,\n'
|
||||||
|
' out_fd_list,\n')
|
||||||
|
self.c.write(' cancellable,\n'
|
||||||
' error);\n'
|
' error);\n'
|
||||||
' if (_ret == NULL)\n'
|
' if (_ret == NULL)\n'
|
||||||
' goto _out;\n')
|
' goto _out;\n')
|
||||||
@ -1366,11 +1441,16 @@ class CodeGenerator:
|
|||||||
|
|
||||||
def generate_method_completers(self, i):
|
def generate_method_completers(self, i):
|
||||||
for m in i.methods:
|
for m in i.methods:
|
||||||
|
unix_fd = False
|
||||||
|
if utils.lookup_annotation(m.annotations, 'org.gtk.GDBus.C.UnixFD'):
|
||||||
|
unix_fd = True
|
||||||
self.c.write('/**\n'
|
self.c.write('/**\n'
|
||||||
' * %s_complete_%s:\n'
|
' * %s_complete_%s:\n'
|
||||||
' * @object: A #%s.\n'
|
' * @object: A #%s.\n'
|
||||||
' * @invocation: (transfer full): A #GDBusMethodInvocation.\n'
|
' * @invocation: (transfer full): A #GDBusMethodInvocation.\n'
|
||||||
%(i.name_lower, m.name_lower, i.camel_name))
|
%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write (' * @fd_list: (allow-none): A #GUnixFDList or %NULL.\n')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(' * @%s: Parameter to return.\n'%(a.name))
|
self.c.write(' * @%s: Parameter to return.\n'%(a.name))
|
||||||
self.c.write(self.docbook_gen.expand(
|
self.c.write(self.docbook_gen.expand(
|
||||||
@ -1384,20 +1464,29 @@ class CodeGenerator:
|
|||||||
'%s_complete_%s (\n'
|
'%s_complete_%s (\n'
|
||||||
' %s *object,\n'
|
' %s *object,\n'
|
||||||
' GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
|
' GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
|
||||||
|
if unix_fd:
|
||||||
|
self.c.write(',\n GUnixFDList *fd_list')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
self.c.write(',\n %s%s'%(a.ctype_in, a.name))
|
||||||
self.c.write(')\n'
|
self.c.write(')\n'
|
||||||
'{\n')
|
'{\n')
|
||||||
|
|
||||||
self.c.write(' g_dbus_method_invocation_return_value (invocation,\n'
|
if unix_fd:
|
||||||
' g_variant_new ("(')
|
self.c.write(' g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,\n'
|
||||||
|
' g_variant_new ("(')
|
||||||
|
else:
|
||||||
|
self.c.write(' g_dbus_method_invocation_return_value (invocation,\n'
|
||||||
|
' g_variant_new ("(')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write('%s'%(a.format_in))
|
self.c.write('%s'%(a.format_in))
|
||||||
self.c.write(')"')
|
self.c.write(')"')
|
||||||
for a in m.out_args:
|
for a in m.out_args:
|
||||||
self.c.write(',\n %s'%(a.name))
|
self.c.write(',\n %s'%(a.name))
|
||||||
self.c.write('));\n'
|
if unix_fd:
|
||||||
'}\n'
|
self.c.write('),\n fd_list);\n')
|
||||||
|
else:
|
||||||
|
self.c.write('));\n')
|
||||||
|
self.c.write('}\n'
|
||||||
'\n')
|
'\n')
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------------------
|
||||||
@ -1868,6 +1957,7 @@ class CodeGenerator:
|
|||||||
' GVariant *child;\n'
|
' GVariant *child;\n'
|
||||||
' GValue *paramv;\n'
|
' GValue *paramv;\n'
|
||||||
' guint num_params;\n'
|
' guint num_params;\n'
|
||||||
|
' guint num_extra;\n'
|
||||||
' guint n;\n'
|
' guint n;\n'
|
||||||
' guint signal_id;\n'
|
' guint signal_id;\n'
|
||||||
' GValue return_value = {0};\n'
|
' GValue return_value = {0};\n'
|
||||||
@ -1876,17 +1966,23 @@ class CodeGenerator:
|
|||||||
' g_assert (info != NULL);\n'
|
' g_assert (info != NULL);\n'
|
||||||
%())
|
%())
|
||||||
self.c.write (' num_params = g_variant_n_children (parameters);\n'
|
self.c.write (' num_params = g_variant_n_children (parameters);\n'
|
||||||
' paramv = g_new0 (GValue, num_params + 2);\n'
|
' num_extra = info->pass_fdlist ? 3 : 2;'
|
||||||
' g_value_init (¶mv[0], %sTYPE_%s);\n'
|
' paramv = g_new0 (GValue, num_params + num_extra);\n'
|
||||||
' g_value_set_object (¶mv[0], skeleton);\n'
|
' n = 0;\n'
|
||||||
' g_value_init (¶mv[1], G_TYPE_DBUS_METHOD_INVOCATION);\n'
|
' g_value_init (¶mv[n], %sTYPE_%s);\n'
|
||||||
' g_value_set_object (¶mv[1], invocation);\n'
|
' g_value_set_object (¶mv[n++], skeleton);\n'
|
||||||
|
' g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION);\n'
|
||||||
|
' g_value_set_object (¶mv[n++], invocation);\n'
|
||||||
|
' if (info->pass_fdlist)\n'
|
||||||
|
' {\n'
|
||||||
|
' g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST);\n'
|
||||||
|
' g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));\n'
|
||||||
|
' }\n'
|
||||||
%(i.ns_upper, i.name_upper))
|
%(i.ns_upper, i.name_upper))
|
||||||
self.c.write(' g_variant_iter_init (&iter, parameters);\n'
|
self.c.write(' g_variant_iter_init (&iter, parameters);\n'
|
||||||
' n = 2;\n'
|
|
||||||
' while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
|
' while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
|
||||||
' {\n'
|
' {\n'
|
||||||
' _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - 2];\n'
|
' _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];\n'
|
||||||
' if (arg_info->use_gvariant)\n'
|
' if (arg_info->use_gvariant)\n'
|
||||||
' {\n'
|
' {\n'
|
||||||
' g_value_init (¶mv[n], G_TYPE_VARIANT);\n'
|
' g_value_init (¶mv[n], G_TYPE_VARIANT);\n'
|
||||||
@ -1906,7 +2002,7 @@ class CodeGenerator:
|
|||||||
' g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n'
|
' g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n'
|
||||||
' g_value_unset (&return_value);\n'
|
' g_value_unset (&return_value);\n'
|
||||||
)
|
)
|
||||||
self.c.write(' for (n = 0; n < num_params + 2; n++)\n'
|
self.c.write(' for (n = 0; n < num_params + num_extra; n++)\n'
|
||||||
' g_value_unset (¶mv[n]);\n'
|
' g_value_unset (¶mv[n]);\n'
|
||||||
' g_free (paramv);\n')
|
' g_free (paramv);\n')
|
||||||
self.c.write('}\n'
|
self.c.write('}\n'
|
||||||
|
@ -4901,6 +4901,7 @@ static GVariant *
|
|||||||
decode_method_reply (GDBusMessage *reply,
|
decode_method_reply (GDBusMessage *reply,
|
||||||
const gchar *method_name,
|
const gchar *method_name,
|
||||||
const GVariantType *reply_type,
|
const GVariantType *reply_type,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GVariant *result;
|
GVariant *result;
|
||||||
@ -4934,6 +4935,18 @@ decode_method_reply (GDBusMessage *reply,
|
|||||||
g_free (type_string);
|
g_free (type_string);
|
||||||
result = NULL;
|
result = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (result != NULL)
|
||||||
|
{
|
||||||
|
if (out_fd_list != NULL)
|
||||||
|
{
|
||||||
|
*out_fd_list = g_dbus_message_get_unix_fd_list (reply);
|
||||||
|
if (*out_fd_list != NULL)
|
||||||
|
g_object_ref (*out_fd_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case G_DBUS_MESSAGE_TYPE_ERROR:
|
case G_DBUS_MESSAGE_TYPE_ERROR:
|
||||||
@ -4955,18 +4968,38 @@ typedef struct
|
|||||||
GVariantType *reply_type;
|
GVariantType *reply_type;
|
||||||
gchar *method_name; /* for error message */
|
gchar *method_name; /* for error message */
|
||||||
guint32 serial;
|
guint32 serial;
|
||||||
|
|
||||||
|
GVariant *value;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
#endif
|
||||||
} CallState;
|
} CallState;
|
||||||
|
|
||||||
|
static void
|
||||||
|
call_state_free (CallState *state)
|
||||||
|
{
|
||||||
|
g_variant_type_free (state->reply_type);
|
||||||
|
g_free (state->method_name);
|
||||||
|
|
||||||
|
if (state->value != NULL)
|
||||||
|
g_variant_unref (state->value);
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (state->fd_list != NULL)
|
||||||
|
g_object_unref (state->fd_list);
|
||||||
|
#endif
|
||||||
|
g_slice_free (CallState, state);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_dbus_connection_call_done (GObject *source,
|
g_dbus_connection_call_done (GObject *source,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GSimpleAsyncResult *simple;
|
||||||
GDBusConnection *connection = G_DBUS_CONNECTION (source);
|
GDBusConnection *connection = G_DBUS_CONNECTION (source);
|
||||||
CallState *state = user_data;
|
CallState *state = user_data;
|
||||||
GError *error;
|
GError *error;
|
||||||
GDBusMessage *reply;
|
GDBusMessage *reply;
|
||||||
GVariant *value;
|
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
reply = g_dbus_connection_send_message_with_reply_finish (connection,
|
reply = g_dbus_connection_send_message_with_reply_finish (connection,
|
||||||
@ -4994,30 +5027,247 @@ g_dbus_connection_call_done (GObject *source,
|
|||||||
_g_dbus_debug_print_unlock ();
|
_g_dbus_debug_print_unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (reply != NULL)
|
if (reply != NULL)
|
||||||
|
state->value = decode_method_reply (reply, state->method_name, state->reply_type, &state->fd_list, &error);
|
||||||
|
|
||||||
|
simple = state->simple; /* why? because state is freed before we unref simple.. */
|
||||||
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
value = decode_method_reply (reply, state->method_name,
|
g_simple_async_result_take_error (state->simple, error);
|
||||||
state->reply_type, &error);
|
g_simple_async_result_complete (state->simple);
|
||||||
g_object_unref (reply);
|
call_state_free (state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = NULL;
|
{
|
||||||
|
g_simple_async_result_set_op_res_gpointer (state->simple, state, (GDestroyNotify) call_state_free);
|
||||||
if (value == NULL)
|
g_simple_async_result_complete (state->simple);
|
||||||
g_simple_async_result_take_error (state->simple, error);
|
g_object_unref (reply);
|
||||||
else
|
}
|
||||||
g_simple_async_result_set_op_res_gpointer (state->simple, value,
|
g_object_unref (simple);
|
||||||
(GDestroyNotify) g_variant_unref);
|
|
||||||
|
|
||||||
g_simple_async_result_complete (state->simple);
|
|
||||||
g_variant_type_free (state->reply_type);
|
|
||||||
g_object_unref (state->simple);
|
|
||||||
g_free (state->method_name);
|
|
||||||
|
|
||||||
g_slice_free (CallState, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_dbus_connection_call_internal (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDBusMessage *message;
|
||||||
|
CallState *state;
|
||||||
|
|
||||||
|
g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
|
||||||
|
g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name));
|
||||||
|
g_return_if_fail (object_path != NULL && g_variant_is_object_path (object_path));
|
||||||
|
g_return_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name));
|
||||||
|
g_return_if_fail (method_name != NULL && g_dbus_is_member_name (method_name));
|
||||||
|
g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1);
|
||||||
|
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
||||||
|
g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
|
||||||
|
|
||||||
|
state = g_slice_new0 (CallState);
|
||||||
|
state->simple = g_simple_async_result_new (G_OBJECT (connection),
|
||||||
|
callback, user_data,
|
||||||
|
g_dbus_connection_call_internal);
|
||||||
|
state->method_name = g_strjoin (".", interface_name, method_name, NULL);
|
||||||
|
|
||||||
|
if (reply_type == NULL)
|
||||||
|
reply_type = G_VARIANT_TYPE_ANY;
|
||||||
|
|
||||||
|
state->reply_type = g_variant_type_copy (reply_type);
|
||||||
|
|
||||||
|
message = g_dbus_message_new_method_call (bus_name,
|
||||||
|
object_path,
|
||||||
|
interface_name,
|
||||||
|
method_name);
|
||||||
|
add_call_flags (message, flags);
|
||||||
|
if (parameters != NULL)
|
||||||
|
g_dbus_message_set_body (message, parameters);
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (fd_list != NULL)
|
||||||
|
g_dbus_message_set_unix_fd_list (message, fd_list);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_dbus_connection_send_message_with_reply (connection,
|
||||||
|
message,
|
||||||
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||||
|
timeout_msec,
|
||||||
|
&state->serial,
|
||||||
|
cancellable,
|
||||||
|
g_dbus_connection_call_done,
|
||||||
|
state);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
||||||
|
{
|
||||||
|
_g_dbus_debug_print_lock ();
|
||||||
|
g_print ("========================================================================\n"
|
||||||
|
"GDBus-debug:Call:\n"
|
||||||
|
" >>>> ASYNC %s.%s()\n"
|
||||||
|
" on object %s\n"
|
||||||
|
" owned by name %s (serial %d)\n",
|
||||||
|
interface_name,
|
||||||
|
method_name,
|
||||||
|
object_path,
|
||||||
|
bus_name != NULL ? bus_name : "(none)",
|
||||||
|
state->serial);
|
||||||
|
_g_dbus_debug_print_unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message != NULL)
|
||||||
|
g_object_unref (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
g_dbus_connection_call_finish_internal (GDBusConnection *connection,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *simple;
|
||||||
|
CallState *state;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
||||||
|
g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (connection),
|
||||||
|
g_dbus_connection_call_internal), NULL);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
|
simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||||
|
|
||||||
|
if (g_simple_async_result_propagate_error (simple, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
state = g_simple_async_result_get_op_res_gpointer (simple);
|
||||||
|
if (out_fd_list != NULL)
|
||||||
|
*out_fd_list = state->fd_list != NULL ? g_object_ref (state->fd_list) : NULL;
|
||||||
|
return g_variant_ref (state->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
g_dbus_connection_call_sync_internal (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GDBusMessage *message;
|
||||||
|
GDBusMessage *reply;
|
||||||
|
GVariant *result;
|
||||||
|
GError *local_error;
|
||||||
|
|
||||||
|
message = NULL;
|
||||||
|
reply = NULL;
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
||||||
|
g_return_val_if_fail (bus_name == NULL || g_dbus_is_name (bus_name), NULL);
|
||||||
|
g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), NULL);
|
||||||
|
g_return_val_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name), NULL);
|
||||||
|
g_return_val_if_fail (method_name != NULL && g_dbus_is_member_name (method_name), NULL);
|
||||||
|
g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
|
||||||
|
g_return_val_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
||||||
|
g_return_val_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list), NULL);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
|
if (reply_type == NULL)
|
||||||
|
reply_type = G_VARIANT_TYPE_ANY;
|
||||||
|
|
||||||
|
message = g_dbus_message_new_method_call (bus_name,
|
||||||
|
object_path,
|
||||||
|
interface_name,
|
||||||
|
method_name);
|
||||||
|
add_call_flags (message, flags);
|
||||||
|
if (parameters != NULL)
|
||||||
|
g_dbus_message_set_body (message, parameters);
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (fd_list != NULL)
|
||||||
|
g_dbus_message_set_unix_fd_list (message, fd_list);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
||||||
|
{
|
||||||
|
_g_dbus_debug_print_lock ();
|
||||||
|
g_print ("========================================================================\n"
|
||||||
|
"GDBus-debug:Call:\n"
|
||||||
|
" >>>> SYNC %s.%s()\n"
|
||||||
|
" on object %s\n"
|
||||||
|
" owned by name %s\n",
|
||||||
|
interface_name,
|
||||||
|
method_name,
|
||||||
|
object_path,
|
||||||
|
bus_name != NULL ? bus_name : "(none)");
|
||||||
|
_g_dbus_debug_print_unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
local_error = NULL;
|
||||||
|
reply = g_dbus_connection_send_message_with_reply_sync (connection,
|
||||||
|
message,
|
||||||
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||||
|
timeout_msec,
|
||||||
|
NULL, /* volatile guint32 *out_serial */
|
||||||
|
cancellable,
|
||||||
|
&local_error);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
||||||
|
{
|
||||||
|
_g_dbus_debug_print_lock ();
|
||||||
|
g_print ("========================================================================\n"
|
||||||
|
"GDBus-debug:Call:\n"
|
||||||
|
" <<<< SYNC COMPLETE %s.%s()\n"
|
||||||
|
" ",
|
||||||
|
interface_name,
|
||||||
|
method_name);
|
||||||
|
if (reply != NULL)
|
||||||
|
{
|
||||||
|
g_print ("SUCCESS\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_print ("FAILED: %s\n",
|
||||||
|
local_error->message);
|
||||||
|
}
|
||||||
|
_g_dbus_debug_print_unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply == NULL)
|
||||||
|
{
|
||||||
|
if (error != NULL)
|
||||||
|
*error = local_error;
|
||||||
|
else
|
||||||
|
g_error_free (local_error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = decode_method_reply (reply, method_name, reply_type, out_fd_list, error);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (message != NULL)
|
||||||
|
g_object_unref (message);
|
||||||
|
if (reply != NULL)
|
||||||
|
g_object_unref (reply);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_connection_call:
|
* g_dbus_connection_call:
|
||||||
* @connection: A #GDBusConnection.
|
* @connection: A #GDBusConnection.
|
||||||
@ -5094,63 +5344,7 @@ g_dbus_connection_call (GDBusConnection *connection,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GDBusMessage *message;
|
return g_dbus_connection_call_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, NULL, cancellable, callback, user_data);
|
||||||
CallState *state;
|
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
|
|
||||||
g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name));
|
|
||||||
g_return_if_fail (object_path != NULL && g_variant_is_object_path (object_path));
|
|
||||||
g_return_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name));
|
|
||||||
g_return_if_fail (method_name != NULL && g_dbus_is_member_name (method_name));
|
|
||||||
g_return_if_fail (timeout_msec >= 0 || timeout_msec == -1);
|
|
||||||
g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
|
||||||
|
|
||||||
state = g_slice_new (CallState);
|
|
||||||
state->simple = g_simple_async_result_new (G_OBJECT (connection),
|
|
||||||
callback, user_data,
|
|
||||||
g_dbus_connection_call);
|
|
||||||
state->method_name = g_strjoin (".", interface_name, method_name, NULL);
|
|
||||||
|
|
||||||
if (reply_type == NULL)
|
|
||||||
reply_type = G_VARIANT_TYPE_ANY;
|
|
||||||
|
|
||||||
state->reply_type = g_variant_type_copy (reply_type);
|
|
||||||
|
|
||||||
message = g_dbus_message_new_method_call (bus_name,
|
|
||||||
object_path,
|
|
||||||
interface_name,
|
|
||||||
method_name);
|
|
||||||
add_call_flags (message, flags);
|
|
||||||
if (parameters != NULL)
|
|
||||||
g_dbus_message_set_body (message, parameters);
|
|
||||||
|
|
||||||
g_dbus_connection_send_message_with_reply (connection,
|
|
||||||
message,
|
|
||||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
|
||||||
timeout_msec,
|
|
||||||
&state->serial,
|
|
||||||
cancellable,
|
|
||||||
g_dbus_connection_call_done,
|
|
||||||
state);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
|
||||||
{
|
|
||||||
_g_dbus_debug_print_lock ();
|
|
||||||
g_print ("========================================================================\n"
|
|
||||||
"GDBus-debug:Call:\n"
|
|
||||||
" >>>> ASYNC %s.%s()\n"
|
|
||||||
" on object %s\n"
|
|
||||||
" owned by name %s (serial %d)\n",
|
|
||||||
interface_name,
|
|
||||||
method_name,
|
|
||||||
object_path,
|
|
||||||
bus_name != NULL ? bus_name : "(none)",
|
|
||||||
state->serial);
|
|
||||||
_g_dbus_debug_print_unlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message != NULL)
|
|
||||||
g_object_unref (message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5171,23 +5365,9 @@ g_dbus_connection_call_finish (GDBusConnection *connection,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *simple;
|
return g_dbus_connection_call_finish_internal (connection, NULL, res, error);
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
|
||||||
g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (connection),
|
|
||||||
g_dbus_connection_call), NULL);
|
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
||||||
|
|
||||||
simple = G_SIMPLE_ASYNC_RESULT (res);
|
|
||||||
|
|
||||||
if (g_simple_async_result_propagate_error (simple, error))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_connection_call_sync:
|
* g_dbus_connection_call_sync:
|
||||||
* @connection: A #GDBusConnection.
|
* @connection: A #GDBusConnection.
|
||||||
@ -5259,101 +5439,130 @@ g_dbus_connection_call_sync (GDBusConnection *connection,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GDBusMessage *message;
|
return g_dbus_connection_call_sync_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, NULL, NULL, cancellable, error);
|
||||||
GDBusMessage *reply;
|
|
||||||
GVariant *result;
|
|
||||||
GError *local_error;
|
|
||||||
|
|
||||||
message = NULL;
|
|
||||||
reply = NULL;
|
|
||||||
result = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
|
|
||||||
g_return_val_if_fail (bus_name == NULL || g_dbus_is_name (bus_name), NULL);
|
|
||||||
g_return_val_if_fail (object_path != NULL && g_variant_is_object_path (object_path), NULL);
|
|
||||||
g_return_val_if_fail (interface_name != NULL && g_dbus_is_interface_name (interface_name), NULL);
|
|
||||||
g_return_val_if_fail (method_name != NULL && g_dbus_is_member_name (method_name), NULL);
|
|
||||||
g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
|
|
||||||
g_return_val_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
|
||||||
|
|
||||||
if (reply_type == NULL)
|
|
||||||
reply_type = G_VARIANT_TYPE_ANY;
|
|
||||||
|
|
||||||
message = g_dbus_message_new_method_call (bus_name,
|
|
||||||
object_path,
|
|
||||||
interface_name,
|
|
||||||
method_name);
|
|
||||||
add_call_flags (message, flags);
|
|
||||||
if (parameters != NULL)
|
|
||||||
g_dbus_message_set_body (message, parameters);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
|
||||||
{
|
|
||||||
_g_dbus_debug_print_lock ();
|
|
||||||
g_print ("========================================================================\n"
|
|
||||||
"GDBus-debug:Call:\n"
|
|
||||||
" >>>> SYNC %s.%s()\n"
|
|
||||||
" on object %s\n"
|
|
||||||
" owned by name %s\n",
|
|
||||||
interface_name,
|
|
||||||
method_name,
|
|
||||||
object_path,
|
|
||||||
bus_name != NULL ? bus_name : "(none)");
|
|
||||||
_g_dbus_debug_print_unlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
local_error = NULL;
|
|
||||||
reply = g_dbus_connection_send_message_with_reply_sync (connection,
|
|
||||||
message,
|
|
||||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
|
||||||
timeout_msec,
|
|
||||||
NULL, /* volatile guint32 *out_serial */
|
|
||||||
cancellable,
|
|
||||||
&local_error);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (_g_dbus_debug_call ()))
|
|
||||||
{
|
|
||||||
_g_dbus_debug_print_lock ();
|
|
||||||
g_print ("========================================================================\n"
|
|
||||||
"GDBus-debug:Call:\n"
|
|
||||||
" <<<< SYNC COMPLETE %s.%s()\n"
|
|
||||||
" ",
|
|
||||||
interface_name,
|
|
||||||
method_name);
|
|
||||||
if (reply != NULL)
|
|
||||||
{
|
|
||||||
g_print ("SUCCESS\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_print ("FAILED: %s\n",
|
|
||||||
local_error->message);
|
|
||||||
}
|
|
||||||
_g_dbus_debug_print_unlock ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reply == NULL)
|
|
||||||
{
|
|
||||||
if (error != NULL)
|
|
||||||
*error = local_error;
|
|
||||||
else
|
|
||||||
g_error_free (local_error);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = decode_method_reply (reply, method_name, reply_type, error);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (message != NULL)
|
|
||||||
g_object_unref (message);
|
|
||||||
if (reply != NULL)
|
|
||||||
g_object_unref (reply);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_connection_call_with_unix_fd_list:
|
||||||
|
* @connection: A #GDBusConnection.
|
||||||
|
* @bus_name: (allow-none): A unique or well-known bus name or %NULL if
|
||||||
|
* @connection is not a message bus connection.
|
||||||
|
* @object_path: Path of remote object.
|
||||||
|
* @interface_name: D-Bus interface to invoke method on.
|
||||||
|
* @method_name: The name of the method to invoke.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with parameters for the method
|
||||||
|
* or %NULL if not passing parameters.
|
||||||
|
* @reply_type: (allow-none): The expected type of the reply, or %NULL.
|
||||||
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
|
* @timeout_msec: The timeout in milliseconds, -1 to use the default
|
||||||
|
* timeout or %G_MAXINT for no timeout.
|
||||||
|
* @fd_list: (allow-none): A #GUnixFDList or %NULL.
|
||||||
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
|
* @callback: (allow-none): A #GAsyncReadyCallback to call when the request is
|
||||||
|
* satisfied or %NULL if you don't * care about the result of the
|
||||||
|
* method invocation.
|
||||||
|
* @user_data: The data to pass to @callback.
|
||||||
|
*
|
||||||
|
* Like g_dbus_connection_call() but also takes a #GUnixFDList object.
|
||||||
|
*
|
||||||
|
* This method is only available on UNIX.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_dbus_connection_call_with_unix_fd_list (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
return g_dbus_connection_call_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, fd_list, cancellable, callback, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_connection_call_with_unix_fd_list_finish:
|
||||||
|
* @connection: A #GDBusConnection.
|
||||||
|
* @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
|
||||||
|
* @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_connection_call_with_unix_fd_list().
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Finishes an operation started with g_dbus_connection_call_with_unix_fd_list().
|
||||||
|
*
|
||||||
|
* Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
|
||||||
|
* return values. Free with g_variant_unref().
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
GVariant *
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_finish (GDBusConnection *connection,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_dbus_connection_call_finish_internal (connection, out_fd_list, res, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_connection_call_with_unix_fd_list_sync:
|
||||||
|
* @connection: A #GDBusConnection.
|
||||||
|
* @bus_name: A unique or well-known bus name.
|
||||||
|
* @object_path: Path of remote object.
|
||||||
|
* @interface_name: D-Bus interface to invoke method on.
|
||||||
|
* @method_name: The name of the method to invoke.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with parameters for the method
|
||||||
|
* or %NULL if not passing parameters.
|
||||||
|
* @reply_type: (allow-none): The expected type of the reply, or %NULL.
|
||||||
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
|
* @timeout_msec: The timeout in milliseconds, -1 to use the default
|
||||||
|
* timeout or %G_MAXINT for no timeout.
|
||||||
|
* @fd_list: (allow-none): A #GUnixFDList or %NULL.
|
||||||
|
* @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
|
||||||
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects.
|
||||||
|
*
|
||||||
|
* This method is only available on UNIX.
|
||||||
|
*
|
||||||
|
* Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
|
||||||
|
* return values. Free with g_variant_unref().
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
GVariant *
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_dbus_connection_call_sync_internal (connection, bus_name, object_path, interface_name, method_name, parameters, reply_type, flags, timeout_msec, fd_list, out_fd_list, cancellable, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* G_OS_UNIX */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
struct ExportedSubtree
|
struct ExportedSubtree
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
|
@ -181,6 +181,36 @@ GVariant *g_dbus_connection_call_sync (GDBusConnection
|
|||||||
gint timeout_msec,
|
gint timeout_msec,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
void g_dbus_connection_call_with_unix_fd_list (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
GVariant *g_dbus_connection_call_with_unix_fd_list_finish (GDBusConnection *connection,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
|
GVariant *g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection,
|
||||||
|
const gchar *bus_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
const GVariantType *reply_type,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
#include "gdbuserror.h"
|
#include "gdbuserror.h"
|
||||||
#include "gdbusprivate.h"
|
#include "gdbusprivate.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#include "gunixfdlist.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -335,23 +339,10 @@ _g_dbus_method_invocation_new (const gchar *sender,
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* g_dbus_method_invocation_return_value:
|
g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation,
|
||||||
* @invocation: (transfer full): A #GDBusMethodInvocation.
|
GVariant *parameters,
|
||||||
* @parameters: (allow-none): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
|
GUnixFDList *fd_list)
|
||||||
*
|
|
||||||
* Finishes handling a D-Bus method call by returning @parameters.
|
|
||||||
* If the @parameters GVariant is floating, it is consumed.
|
|
||||||
*
|
|
||||||
* It is an error if @parameters is not of the right format.
|
|
||||||
*
|
|
||||||
* This method will free @invocation, you cannot use it afterwards.
|
|
||||||
*
|
|
||||||
* Since: 2.26
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
|
||||||
GVariant *parameters)
|
|
||||||
{
|
{
|
||||||
GDBusMessage *reply;
|
GDBusMessage *reply;
|
||||||
GError *error;
|
GError *error;
|
||||||
@ -401,6 +392,12 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
|||||||
|
|
||||||
reply = g_dbus_message_new_method_reply (invocation->message);
|
reply = g_dbus_message_new_method_reply (invocation->message);
|
||||||
g_dbus_message_set_body (reply, parameters);
|
g_dbus_message_set_body (reply, parameters);
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (fd_list != NULL)
|
||||||
|
g_dbus_message_set_unix_fd_list (reply, fd_list);
|
||||||
|
#endif
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
|
if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error))
|
||||||
{
|
{
|
||||||
@ -413,6 +410,51 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
|||||||
g_object_unref (invocation);
|
g_object_unref (invocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_method_invocation_return_value:
|
||||||
|
* @invocation: (transfer full): A #GDBusMethodInvocation.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
|
||||||
|
*
|
||||||
|
* Finishes handling a D-Bus method call by returning @parameters.
|
||||||
|
* If the @parameters GVariant is floating, it is consumed.
|
||||||
|
*
|
||||||
|
* It is an error if @parameters is not of the right format.
|
||||||
|
*
|
||||||
|
* This method will free @invocation, you cannot use it afterwards.
|
||||||
|
*
|
||||||
|
* Since: 2.26
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
||||||
|
GVariant *parameters)
|
||||||
|
{
|
||||||
|
return g_dbus_method_invocation_return_value_internal (invocation, parameters, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
/**
|
||||||
|
* g_dbus_method_invocation_return_value_with_unix_fd_list:
|
||||||
|
* @invocation: (transfer full): A #GDBusMethodInvocation.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
|
||||||
|
* @fd_list: (allow-none): A #GUnixFDList or %NULL.
|
||||||
|
*
|
||||||
|
* Like g_dbus_method_invocation_return_value() but also takes a #GUnixFDList.
|
||||||
|
*
|
||||||
|
* This method is only available on UNIX.
|
||||||
|
*
|
||||||
|
* This method will free @invocation, you cannot use it afterwards.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation,
|
||||||
|
GVariant *parameters,
|
||||||
|
GUnixFDList *fd_list)
|
||||||
|
{
|
||||||
|
return g_dbus_method_invocation_return_value_internal (invocation, parameters, fd_list);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,6 +48,9 @@ gpointer g_dbus_method_invocation_get_user_data (GDBusMetho
|
|||||||
|
|
||||||
void g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
void g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
|
||||||
GVariant *parameters);
|
GVariant *parameters);
|
||||||
|
void g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation,
|
||||||
|
GVariant *parameters,
|
||||||
|
GUnixFDList *fd_list);
|
||||||
void g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
|
void g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
|
||||||
GQuark domain,
|
GQuark domain,
|
||||||
gint code,
|
gint code,
|
||||||
|
521
gio/gdbusproxy.c
521
gio/gdbusproxy.c
@ -39,6 +39,10 @@
|
|||||||
#include "gcancellable.h"
|
#include "gcancellable.h"
|
||||||
#include "gdbusinterface.h"
|
#include "gdbusinterface.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#include "gunixfdlist.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2325,6 +2329,24 @@ maybe_split_method_name (const gchar *method_name,
|
|||||||
return was_split;
|
return was_split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GVariant *value;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
#endif
|
||||||
|
} ReplyData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
reply_data_free (ReplyData *data)
|
||||||
|
{
|
||||||
|
g_variant_unref (data->value);
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (data->fd_list != NULL)
|
||||||
|
g_object_unref (data->fd_list);
|
||||||
|
#endif
|
||||||
|
g_slice_free (ReplyData, data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reply_cb (GDBusConnection *connection,
|
reply_cb (GDBusConnection *connection,
|
||||||
@ -2334,20 +2356,34 @@ reply_cb (GDBusConnection *connection,
|
|||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
|
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
value = g_dbus_connection_call_with_unix_fd_list_finish (connection,
|
||||||
|
&fd_list,
|
||||||
|
res,
|
||||||
|
&error);
|
||||||
|
#else
|
||||||
value = g_dbus_connection_call_finish (connection,
|
value = g_dbus_connection_call_finish (connection,
|
||||||
res,
|
res,
|
||||||
&error);
|
&error);
|
||||||
|
#endif
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
g_simple_async_result_take_error (simple, error);
|
g_simple_async_result_take_error (simple, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_simple_async_result_set_op_res_gpointer (simple,
|
ReplyData *data;
|
||||||
value,
|
data = g_slice_new0 (ReplyData);
|
||||||
(GDestroyNotify) g_variant_unref);
|
data->value = value;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
data->fd_list = fd_list;
|
||||||
|
#endif
|
||||||
|
g_simple_async_result_set_op_res_gpointer (simple, data, (GDestroyNotify) reply_data_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no need to complete in idle since the method GDBusConnection already does */
|
/* no need to complete in idle since the method GDBusConnection already does */
|
||||||
@ -2399,6 +2435,233 @@ get_destination_for_call (GDBusProxy *proxy)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_dbus_proxy_call_internal (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *simple;
|
||||||
|
gboolean was_split;
|
||||||
|
gchar *split_interface_name;
|
||||||
|
const gchar *split_method_name;
|
||||||
|
const gchar *target_method_name;
|
||||||
|
const gchar *target_interface_name;
|
||||||
|
const gchar *destination;
|
||||||
|
GVariantType *reply_type;
|
||||||
|
|
||||||
|
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
||||||
|
g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name));
|
||||||
|
g_return_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
||||||
|
g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0);
|
||||||
|
g_return_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list));
|
||||||
|
|
||||||
|
reply_type = NULL;
|
||||||
|
split_interface_name = NULL;
|
||||||
|
|
||||||
|
simple = g_simple_async_result_new (G_OBJECT (proxy),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
g_dbus_proxy_call_internal);
|
||||||
|
|
||||||
|
was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name);
|
||||||
|
target_method_name = was_split ? split_method_name : method_name;
|
||||||
|
target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name;
|
||||||
|
|
||||||
|
/* Warn if method is unexpected (cf. :g-interface-info) */
|
||||||
|
if (!was_split)
|
||||||
|
{
|
||||||
|
const GDBusMethodInfo *expected_method_info;
|
||||||
|
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
||||||
|
if (expected_method_info != NULL)
|
||||||
|
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
destination = NULL;
|
||||||
|
if (proxy->priv->name != NULL)
|
||||||
|
{
|
||||||
|
destination = get_destination_for_call (proxy);
|
||||||
|
if (destination == NULL)
|
||||||
|
{
|
||||||
|
g_simple_async_result_set_error (simple,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
_("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
g_dbus_connection_call_with_unix_fd_list (proxy->priv->connection,
|
||||||
|
destination,
|
||||||
|
proxy->priv->object_path,
|
||||||
|
target_interface_name,
|
||||||
|
target_method_name,
|
||||||
|
parameters,
|
||||||
|
reply_type,
|
||||||
|
flags,
|
||||||
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
|
fd_list,
|
||||||
|
cancellable,
|
||||||
|
(GAsyncReadyCallback) reply_cb,
|
||||||
|
simple);
|
||||||
|
#else
|
||||||
|
g_dbus_connection_call (proxy->priv->connection,
|
||||||
|
destination,
|
||||||
|
proxy->priv->object_path,
|
||||||
|
target_interface_name,
|
||||||
|
target_method_name,
|
||||||
|
parameters,
|
||||||
|
reply_type,
|
||||||
|
flags,
|
||||||
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
|
cancellable,
|
||||||
|
(GAsyncReadyCallback) reply_cb,
|
||||||
|
simple);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (reply_type != NULL)
|
||||||
|
g_variant_type_free (reply_type);
|
||||||
|
|
||||||
|
g_free (split_interface_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
g_dbus_proxy_call_finish_internal (GDBusProxy *proxy,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
||||||
|
GVariant *value;
|
||||||
|
ReplyData *data;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
||||||
|
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
|
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_proxy_call_internal);
|
||||||
|
|
||||||
|
value = NULL;
|
||||||
|
|
||||||
|
if (g_simple_async_result_propagate_error (simple, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
data = g_simple_async_result_get_op_res_gpointer (simple);
|
||||||
|
value = g_variant_ref (data->value);
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
if (out_fd_list != NULL)
|
||||||
|
*out_fd_list = data->fd_list != NULL ? g_object_ref (data->fd_list) : NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
g_dbus_proxy_call_sync_internal (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GVariant *ret;
|
||||||
|
gboolean was_split;
|
||||||
|
gchar *split_interface_name;
|
||||||
|
const gchar *split_method_name;
|
||||||
|
const gchar *target_method_name;
|
||||||
|
const gchar *target_interface_name;
|
||||||
|
const gchar *destination;
|
||||||
|
GVariantType *reply_type;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
||||||
|
g_return_val_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name), NULL);
|
||||||
|
g_return_val_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
||||||
|
g_return_val_if_fail (timeout_msec == -1 || timeout_msec >= 0, NULL);
|
||||||
|
g_return_val_if_fail (fd_list == NULL || G_IS_UNIX_FD_LIST (fd_list), NULL);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
|
reply_type = NULL;
|
||||||
|
|
||||||
|
was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name);
|
||||||
|
target_method_name = was_split ? split_method_name : method_name;
|
||||||
|
target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name;
|
||||||
|
|
||||||
|
/* Warn if method is unexpected (cf. :g-interface-info) */
|
||||||
|
if (!was_split)
|
||||||
|
{
|
||||||
|
const GDBusMethodInfo *expected_method_info;
|
||||||
|
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
||||||
|
if (expected_method_info != NULL)
|
||||||
|
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
destination = NULL;
|
||||||
|
if (proxy->priv->name != NULL)
|
||||||
|
{
|
||||||
|
destination = get_destination_for_call (proxy);
|
||||||
|
if (destination == NULL)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
_("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
|
||||||
|
ret = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
ret = g_dbus_connection_call_with_unix_fd_list_sync (proxy->priv->connection,
|
||||||
|
destination,
|
||||||
|
proxy->priv->object_path,
|
||||||
|
target_interface_name,
|
||||||
|
target_method_name,
|
||||||
|
parameters,
|
||||||
|
reply_type,
|
||||||
|
flags,
|
||||||
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
|
fd_list,
|
||||||
|
out_fd_list,
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
#else
|
||||||
|
ret = g_dbus_connection_call_sync (proxy->priv->connection,
|
||||||
|
destination,
|
||||||
|
proxy->priv->object_path,
|
||||||
|
target_interface_name,
|
||||||
|
target_method_name,
|
||||||
|
parameters,
|
||||||
|
reply_type,
|
||||||
|
flags,
|
||||||
|
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (reply_type != NULL)
|
||||||
|
g_variant_type_free (reply_type);
|
||||||
|
|
||||||
|
g_free (split_interface_name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_proxy_call:
|
* g_dbus_proxy_call:
|
||||||
* @proxy: A #GDBusProxy.
|
* @proxy: A #GDBusProxy.
|
||||||
@ -2460,73 +2723,7 @@ g_dbus_proxy_call (GDBusProxy *proxy,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *simple;
|
return g_dbus_proxy_call_internal (proxy, method_name, parameters, flags, timeout_msec, NULL, cancellable, callback, user_data);
|
||||||
gboolean was_split;
|
|
||||||
gchar *split_interface_name;
|
|
||||||
const gchar *split_method_name;
|
|
||||||
const gchar *target_method_name;
|
|
||||||
const gchar *target_interface_name;
|
|
||||||
const gchar *destination;
|
|
||||||
GVariantType *reply_type;
|
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_PROXY (proxy));
|
|
||||||
g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name));
|
|
||||||
g_return_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
|
|
||||||
g_return_if_fail (timeout_msec == -1 || timeout_msec >= 0);
|
|
||||||
|
|
||||||
reply_type = NULL;
|
|
||||||
split_interface_name = NULL;
|
|
||||||
|
|
||||||
simple = g_simple_async_result_new (G_OBJECT (proxy),
|
|
||||||
callback,
|
|
||||||
user_data,
|
|
||||||
g_dbus_proxy_call);
|
|
||||||
|
|
||||||
was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name);
|
|
||||||
target_method_name = was_split ? split_method_name : method_name;
|
|
||||||
target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name;
|
|
||||||
|
|
||||||
/* Warn if method is unexpected (cf. :g-interface-info) */
|
|
||||||
if (!was_split)
|
|
||||||
{
|
|
||||||
const GDBusMethodInfo *expected_method_info;
|
|
||||||
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
|
||||||
if (expected_method_info != NULL)
|
|
||||||
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
destination = NULL;
|
|
||||||
if (proxy->priv->name != NULL)
|
|
||||||
{
|
|
||||||
destination = get_destination_for_call (proxy);
|
|
||||||
if (destination == NULL)
|
|
||||||
{
|
|
||||||
g_simple_async_result_set_error (simple,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_FAILED,
|
|
||||||
_("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dbus_connection_call (proxy->priv->connection,
|
|
||||||
destination,
|
|
||||||
proxy->priv->object_path,
|
|
||||||
target_interface_name,
|
|
||||||
target_method_name,
|
|
||||||
parameters,
|
|
||||||
reply_type,
|
|
||||||
flags,
|
|
||||||
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
|
||||||
cancellable,
|
|
||||||
(GAsyncReadyCallback) reply_cb,
|
|
||||||
simple);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (reply_type != NULL)
|
|
||||||
g_variant_type_free (reply_type);
|
|
||||||
|
|
||||||
g_free (split_interface_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2547,24 +2744,7 @@ g_dbus_proxy_call_finish (GDBusProxy *proxy,
|
|||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
|
return g_dbus_proxy_call_finish_internal (proxy, NULL, res, error);
|
||||||
GVariant *value;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
|
||||||
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
|
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
||||||
|
|
||||||
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_dbus_proxy_call);
|
|
||||||
|
|
||||||
value = NULL;
|
|
||||||
|
|
||||||
if (g_simple_async_result_propagate_error (simple, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
value = g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
|
||||||
|
|
||||||
out:
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2624,74 +2804,111 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GVariant *ret;
|
return g_dbus_proxy_call_sync_internal (proxy, method_name, parameters, flags, timeout_msec, NULL, NULL, cancellable, error);
|
||||||
gboolean was_split;
|
|
||||||
gchar *split_interface_name;
|
|
||||||
const gchar *split_method_name;
|
|
||||||
const gchar *target_method_name;
|
|
||||||
const gchar *target_interface_name;
|
|
||||||
const gchar *destination;
|
|
||||||
GVariantType *reply_type;
|
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), NULL);
|
|
||||||
g_return_val_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name), NULL);
|
|
||||||
g_return_val_if_fail (parameters == NULL || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
|
|
||||||
g_return_val_if_fail (timeout_msec == -1 || timeout_msec >= 0, NULL);
|
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
||||||
|
|
||||||
reply_type = NULL;
|
|
||||||
|
|
||||||
was_split = maybe_split_method_name (method_name, &split_interface_name, &split_method_name);
|
|
||||||
target_method_name = was_split ? split_method_name : method_name;
|
|
||||||
target_interface_name = was_split ? split_interface_name : proxy->priv->interface_name;
|
|
||||||
|
|
||||||
/* Warn if method is unexpected (cf. :g-interface-info) */
|
|
||||||
if (!was_split)
|
|
||||||
{
|
|
||||||
const GDBusMethodInfo *expected_method_info;
|
|
||||||
expected_method_info = lookup_method_info_or_warn (proxy, target_method_name);
|
|
||||||
if (expected_method_info != NULL)
|
|
||||||
reply_type = _g_dbus_compute_complete_signature (expected_method_info->out_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
destination = NULL;
|
|
||||||
if (proxy->priv->name != NULL)
|
|
||||||
{
|
|
||||||
destination = get_destination_for_call (proxy);
|
|
||||||
if (destination == NULL)
|
|
||||||
{
|
|
||||||
g_set_error_literal (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_FAILED,
|
|
||||||
_("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
|
|
||||||
ret = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = g_dbus_connection_call_sync (proxy->priv->connection,
|
|
||||||
destination,
|
|
||||||
proxy->priv->object_path,
|
|
||||||
target_interface_name,
|
|
||||||
target_method_name,
|
|
||||||
parameters,
|
|
||||||
reply_type,
|
|
||||||
flags,
|
|
||||||
timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
|
|
||||||
cancellable,
|
|
||||||
error);
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (reply_type != NULL)
|
|
||||||
g_variant_type_free (reply_type);
|
|
||||||
|
|
||||||
g_free (split_interface_name);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_proxy_call_with_unix_fd_list:
|
||||||
|
* @proxy: A #GDBusProxy.
|
||||||
|
* @method_name: Name of method to invoke.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with parameters for the signal or %NULL if not passing parameters.
|
||||||
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
|
* @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning
|
||||||
|
* "infinite") or -1 to use the proxy default timeout.
|
||||||
|
* @fd_list: (allow-none): A #GUnixFDList or %NULL.
|
||||||
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
|
* @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL if you don't
|
||||||
|
* care about the result of the method invocation.
|
||||||
|
* @user_data: The data to pass to @callback.
|
||||||
|
*
|
||||||
|
* Like g_dbus_proxy_call() but also takes a #GUnixFDList object.
|
||||||
|
*
|
||||||
|
* This method is only available on UNIX.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
return g_dbus_proxy_call_internal (proxy, method_name, parameters, flags, timeout_msec, fd_list, cancellable, callback, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_proxy_call_with_unix_fd_list_finish:
|
||||||
|
* @proxy: A #GDBusProxy.
|
||||||
|
* @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
|
||||||
|
* @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_proxy_call_with_unix_fd_list().
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Finishes an operation started with g_dbus_proxy_call_with_unix_fd_list().
|
||||||
|
*
|
||||||
|
* Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
|
||||||
|
* return values. Free with g_variant_unref().
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
GVariant *
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_finish (GDBusProxy *proxy,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_dbus_proxy_call_finish_internal (proxy, out_fd_list, res, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_proxy_call_with_unix_fd_list_sync:
|
||||||
|
* @proxy: A #GDBusProxy.
|
||||||
|
* @method_name: Name of method to invoke.
|
||||||
|
* @parameters: (allow-none): A #GVariant tuple with parameters for the signal
|
||||||
|
* or %NULL if not passing parameters.
|
||||||
|
* @flags: Flags from the #GDBusCallFlags enumeration.
|
||||||
|
* @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning
|
||||||
|
* "infinite") or -1 to use the proxy default timeout.
|
||||||
|
* @fd_list: (allow-none): A #GUnixFDList or %NULL.
|
||||||
|
* @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
|
||||||
|
* @cancellable: A #GCancellable or %NULL.
|
||||||
|
* @error: Return location for error or %NULL.
|
||||||
|
*
|
||||||
|
* Like g_dbus_proxy_call_sync() but also takes and returns #GUnixFDList objects.
|
||||||
|
*
|
||||||
|
* This method is only available on UNIX.
|
||||||
|
*
|
||||||
|
* Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
|
||||||
|
* return values. Free with g_variant_unref().
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
GVariant *
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_sync (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_dbus_proxy_call_sync_internal (proxy, method_name, parameters, flags, timeout_msec, fd_list, out_fd_list, cancellable, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* G_OS_UNIX */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static GDBusInterfaceInfo *
|
static GDBusInterfaceInfo *
|
||||||
_g_dbus_proxy_get_info (GDBusInterface *interface)
|
_g_dbus_proxy_get_info (GDBusInterface *interface)
|
||||||
{
|
{
|
||||||
|
@ -162,6 +162,29 @@ GVariant *g_dbus_proxy_call_sync (GDBusProxy *pr
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
void g_dbus_proxy_call_with_unix_fd_list (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
GVariant *g_dbus_proxy_call_with_unix_fd_list_finish (GDBusProxy *proxy,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
|
GVariant *g_dbus_proxy_call_with_unix_fd_list_sync (GDBusProxy *proxy,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusCallFlags flags,
|
||||||
|
gint timeout_msec,
|
||||||
|
GUnixFDList *fd_list,
|
||||||
|
GUnixFDList **out_fd_list,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_DBUS_PROXY_H__ */
|
#endif /* __G_DBUS_PROXY_H__ */
|
||||||
|
@ -1036,6 +1036,13 @@ g_unix_fd_message_new
|
|||||||
g_unix_fd_message_steal_fds
|
g_unix_fd_message_steal_fds
|
||||||
g_unix_fd_message_get_fd_list
|
g_unix_fd_message_get_fd_list
|
||||||
g_unix_fd_message_new_with_fd_list
|
g_unix_fd_message_new_with_fd_list
|
||||||
|
g_dbus_connection_call_with_unix_fd_list
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_finish
|
||||||
|
g_dbus_connection_call_with_unix_fd_list_sync
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_finish
|
||||||
|
g_dbus_proxy_call_with_unix_fd_list_sync
|
||||||
|
g_dbus_method_invocation_return_value_with_unix_fd_list
|
||||||
#endif
|
#endif
|
||||||
#ifndef G_OS_WIN32
|
#ifndef G_OS_WIN32
|
||||||
g_unix_fd_list_append
|
g_unix_fd_list_append
|
||||||
|
@ -467,4 +467,12 @@
|
|||||||
</interface>
|
</interface>
|
||||||
<unknownTag/>
|
<unknownTag/>
|
||||||
|
|
||||||
|
<interface name="FDPassing">
|
||||||
|
<method name="HelloFD">
|
||||||
|
<annotation name="org.gtk.GDBus.C.UnixFD" value="1"/>
|
||||||
|
<arg name="greeting" direction="in" type="s"/>
|
||||||
|
<arg name="response" direction="out" type="s"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
|
||||||
</node>
|
</node>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user