mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-25 11:40:10 +01:00
2005-07-06 Colin Walters <walters@verbum.org>
* dbus/dbus-glib.h (DBusGPendingCall, DBusGPendingCallNotify) (DBUS_TYPE_G_PENDING_CALL, dbus_g_pending_call_get_g_type) (dbus_g_pending_call_ref, dbus_g_pending_call_unref): Delete. (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete in favor of dbus_g_proxy_begin_call and dbus_g_proxy_cancel_call. (DBusGProxyCall, DBusGProxyCallNotify): New. (dbus_g_proxy_begin_call): Change prototype to take callback, user data, and destroy function. This replaces dbus_g_pending_call_set_notify. (dbus_g_proxy_cancel_call): Prototype. (DBusGAsyncData): Delete, shouldn't be needed anymore. * glib/dbus-gproxy.c (struct _DBusGProxy): Add call_id_counter and pending_calls map. (struct _DBusGProxyManager): Add bus_proxy member, which is an internal proxy for calls to the bus. Remove pending_nameowner_calls, now the internal proxy keeps track. (dbus_g_proxy_manager_unref): Unref bus proxy, remove reference to pending_nameowner_calls. (got_name_owner_cb): Update prototype, and use dbus_g_proxy_end_call. (got_name_owner_cb): Remove reference to pending_nameowner_calls. (dbus_g_proxy_manager_register): Delete directly libdbus code in favor of using internal proxy. (dbus_g_proxy_manager_unregister): Update to use dbus_g_proxy_cancel_call for any pending GetNameOwner call. (dbus_g_proxy_init): Initialize pending calls map. (dbus_g_proxy_constructor): New. (dbus_g_proxy_class_init): Add get/set property functions, constructor, and add NAME, PATH, and INTERFACE properties. (cancel_pending_call): New function. (dbus_g_proxy_dispose): Iterate over any outstanding calls and cancel them. (dbus_g_proxy_set_property, dbus_g_proxy_get_property): New. (GPendingNotifyClosure): New structure. (d_pending_call_notify, d_pending_call_free): Moved here from dbus-glib.c. (DBUS_G_VALUE_ARRAY_COLLECT_ALL): Moved around to satisfy function ordering. (manager_begin_bus_call): New internal function for talking to internal bus proxy. (dbus_g_proxy_new): Construct object using GObjet properties. (dbus_g_proxy_begin_call_internal): Update to take user data, etc. Create closure of same, and insert call into map of pending calls. (dbus_g_proxy_end_call_internal): Take call id instead of pending call. Look up pending call in current set. Remove it when we've completed. (dbus_g_pending_call_end, dbus_g_proxy_end_call_internal): Delete. (dbus_g_proxy_begin_call): Change API to take callback, user data, and destroy function directly. (dbus_g_proxy_end_call): Update to take DBusGProxyCall. (dbus_g_proxy_call): Invoke with NULL callback. (dbus_g_proxy_cancel_call): New function, replaces dbus_g_pending_call_cancel. * glib/dbus-gparser.c (validate_signature): Fix call to dbus_set_g_error. * glib/dbus-gobject.c (dbus_g_object_type_dbus_metadata_quark): New quark for attaching metadata to GType. (info_hash): Delete. (lookup_object_info): Look up using quark. (dbus_g_object_type_install_info): Check that a type is classed, not that it's an object. Also just install type data using quark instead of using global hash. * glib/dbus-glib.c (dbus_g_pending_call_ref) (dbus_g_pending_call_unref, dbus_pending_call_get_g_type) (GPendingNotifyClosure): Delete. (d_pending_call_notify, d_pending_call_free): Move to dbus-gproxy.c. (dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete. * glib/dbus-binding-tool-glib.c (generate_client_glue): Disable async client method generation until we can fix it... * tools/dbus-viewer.c (load_child_nodes): Use dbus_g_proxy_call. (load_from_service_thread_func): Ditto. * tools/dbus-names-model.c (struct NamesModel): Hold DBusGProxyCall. (have_names_notify): Update prototype, use dbus_g_proxy_cancel_call. (names_model_reload): Update for new dbus_g_proxy_begin_call API. * tools/dbus-monitor.c (filter_func): Update for print_message API change. * test/glib/test-dbus-glib.c: Add more tests for async invocations. Update many begin_call/end_call pairs to just use dbus_g_proxy_call. * tools/dbus-send.c (main): Add --print-reply=literal mode. This allows us to dump print-introspect.c. * tools/dbus-print-message.h (print_message): Add literal argument to print_message which is intended to allow printing arguments without metadata like "string=". * tools/dbus-print-message.c (print_iter): Add literal argument. (print_message): Allow printing string messages literally.
This commit is contained in:
parent
42c4a46d66
commit
2ca6e95764
15 changed files with 706 additions and 538 deletions
104
ChangeLog
104
ChangeLog
|
|
@ -1,3 +1,107 @@
|
|||
2005-07-06 Colin Walters <walters@verbum.org>
|
||||
|
||||
* dbus/dbus-glib.h (DBusGPendingCall, DBusGPendingCallNotify)
|
||||
(DBUS_TYPE_G_PENDING_CALL, dbus_g_pending_call_get_g_type)
|
||||
(dbus_g_pending_call_ref, dbus_g_pending_call_unref): Delete.
|
||||
(dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel):
|
||||
Delete in favor of dbus_g_proxy_begin_call and
|
||||
dbus_g_proxy_cancel_call.
|
||||
(DBusGProxyCall, DBusGProxyCallNotify): New.
|
||||
(dbus_g_proxy_begin_call): Change prototype to take callback, user
|
||||
data, and destroy function. This replaces
|
||||
dbus_g_pending_call_set_notify.
|
||||
(dbus_g_proxy_cancel_call): Prototype.
|
||||
(DBusGAsyncData): Delete, shouldn't be needed anymore.
|
||||
|
||||
* glib/dbus-gproxy.c (struct _DBusGProxy): Add call_id_counter and
|
||||
pending_calls map.
|
||||
(struct _DBusGProxyManager): Add bus_proxy member, which is an
|
||||
internal proxy for calls to the bus. Remove
|
||||
pending_nameowner_calls, now the internal proxy keeps track.
|
||||
(dbus_g_proxy_manager_unref): Unref bus proxy, remove reference to
|
||||
pending_nameowner_calls.
|
||||
(got_name_owner_cb): Update prototype, and use
|
||||
dbus_g_proxy_end_call.
|
||||
(got_name_owner_cb): Remove reference to pending_nameowner_calls.
|
||||
(dbus_g_proxy_manager_register): Delete directly libdbus code in
|
||||
favor of using internal proxy.
|
||||
(dbus_g_proxy_manager_unregister): Update to use
|
||||
dbus_g_proxy_cancel_call for any pending GetNameOwner call.
|
||||
(dbus_g_proxy_init): Initialize pending calls map.
|
||||
(dbus_g_proxy_constructor): New.
|
||||
(dbus_g_proxy_class_init): Add get/set property functions,
|
||||
constructor, and add NAME, PATH, and INTERFACE properties.
|
||||
(cancel_pending_call): New function.
|
||||
(dbus_g_proxy_dispose): Iterate over any outstanding calls and
|
||||
cancel them.
|
||||
(dbus_g_proxy_set_property, dbus_g_proxy_get_property): New.
|
||||
(GPendingNotifyClosure): New structure.
|
||||
(d_pending_call_notify, d_pending_call_free): Moved here from
|
||||
dbus-glib.c.
|
||||
(DBUS_G_VALUE_ARRAY_COLLECT_ALL): Moved around to satisfy function
|
||||
ordering.
|
||||
(manager_begin_bus_call): New internal function for talking to
|
||||
internal bus proxy.
|
||||
(dbus_g_proxy_new): Construct object using GObjet properties.
|
||||
(dbus_g_proxy_begin_call_internal): Update to take user data, etc.
|
||||
Create closure of same, and insert call into map of pending calls.
|
||||
(dbus_g_proxy_end_call_internal): Take call id instead of pending
|
||||
call. Look up pending call in current set. Remove it when we've
|
||||
completed.
|
||||
(dbus_g_pending_call_end, dbus_g_proxy_end_call_internal): Delete.
|
||||
(dbus_g_proxy_begin_call): Change API to take callback, user data,
|
||||
and destroy function directly.
|
||||
(dbus_g_proxy_end_call): Update to take DBusGProxyCall.
|
||||
(dbus_g_proxy_call): Invoke with NULL callback.
|
||||
(dbus_g_proxy_cancel_call): New function, replaces
|
||||
dbus_g_pending_call_cancel.
|
||||
|
||||
* glib/dbus-gparser.c (validate_signature): Fix call to
|
||||
dbus_set_g_error.
|
||||
|
||||
* glib/dbus-gobject.c (dbus_g_object_type_dbus_metadata_quark):
|
||||
New quark for attaching metadata to GType.
|
||||
(info_hash): Delete.
|
||||
(lookup_object_info): Look up using quark.
|
||||
(dbus_g_object_type_install_info): Check that a type is classed,
|
||||
not that it's an object. Also just install type data using quark
|
||||
instead of using global hash.
|
||||
|
||||
* glib/dbus-glib.c (dbus_g_pending_call_ref)
|
||||
(dbus_g_pending_call_unref, dbus_pending_call_get_g_type)
|
||||
(GPendingNotifyClosure): Delete.
|
||||
(d_pending_call_notify, d_pending_call_free): Move to dbus-gproxy.c.
|
||||
(dbus_g_pending_call_set_notify, dbus_g_pending_call_cancel): Delete.
|
||||
|
||||
* glib/dbus-binding-tool-glib.c (generate_client_glue): Disable async
|
||||
client method generation until we can fix it...
|
||||
|
||||
* tools/dbus-viewer.c (load_child_nodes): Use dbus_g_proxy_call.
|
||||
(load_from_service_thread_func): Ditto.
|
||||
|
||||
* tools/dbus-names-model.c (struct NamesModel): Hold
|
||||
DBusGProxyCall.
|
||||
(have_names_notify): Update prototype, use
|
||||
dbus_g_proxy_cancel_call.
|
||||
(names_model_reload): Update for new dbus_g_proxy_begin_call API.
|
||||
|
||||
* tools/dbus-monitor.c (filter_func): Update for print_message
|
||||
API change.
|
||||
|
||||
* test/glib/test-dbus-glib.c: Add more tests for async
|
||||
invocations. Update many begin_call/end_call pairs to just use
|
||||
dbus_g_proxy_call.
|
||||
|
||||
* tools/dbus-send.c (main): Add --print-reply=literal mode. This
|
||||
allows us to dump print-introspect.c.
|
||||
|
||||
* tools/dbus-print-message.h (print_message): Add literal argument
|
||||
to print_message which is intended to allow printing arguments without
|
||||
metadata like "string=".
|
||||
|
||||
* tools/dbus-print-message.c (print_iter): Add literal argument.
|
||||
(print_message): Allow printing string messages literally.
|
||||
|
||||
2005-07-05 Colin Walters <walters@verbum.org>
|
||||
|
||||
* glib/dbus-gproxy.c (marshal_dbus_message_to_g_marshaller):
|
||||
|
|
|
|||
|
|
@ -40,39 +40,21 @@ typedef struct _DBusGConnection DBusGConnection;
|
|||
* Convert to DBusMessage with dbus_g_message_get_message() in dbus-glib-lowlevel.h
|
||||
*/
|
||||
typedef struct _DBusGMessage DBusGMessage;
|
||||
/**
|
||||
* Deliberately not possible to convert to DBusPendingCall
|
||||
*/
|
||||
typedef struct _DBusGPendingCall DBusGPendingCall;
|
||||
|
||||
typedef void (* DBusGPendingCallNotify) (DBusGPendingCall *pending,
|
||||
void *user_data);
|
||||
|
||||
|
||||
#define DBUS_TYPE_G_CONNECTION (dbus_g_connection_get_g_type ())
|
||||
#define DBUS_TYPE_G_MESSAGE (dbus_g_message_get_g_type ())
|
||||
#define DBUS_TYPE_G_PENDING_CALL (dbus_g_message_get_g_type ())
|
||||
GType dbus_g_connection_get_g_type (void) G_GNUC_CONST;
|
||||
GType dbus_g_message_get_g_type (void) G_GNUC_CONST;
|
||||
GType dbus_g_pending_call_get_g_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
DBusGConnection* dbus_g_connection_ref (DBusGConnection *connection);
|
||||
void dbus_g_connection_unref (DBusGConnection *connection);
|
||||
DBusGPendingCall* dbus_g_pending_call_ref (DBusGPendingCall *call);
|
||||
void dbus_g_pending_call_unref (DBusGPendingCall *call);
|
||||
DBusGMessage* dbus_g_message_ref (DBusGMessage *message);
|
||||
void dbus_g_message_unref (DBusGMessage *message);
|
||||
|
||||
void dbus_g_connection_flush (DBusGConnection *connection);
|
||||
|
||||
void dbus_g_pending_call_set_notify (DBusGPendingCall *call,
|
||||
DBusGPendingCallNotify callback,
|
||||
void *callback_data,
|
||||
GDestroyNotify free_data_func);
|
||||
void dbus_g_pending_call_cancel (DBusGPendingCall *call);
|
||||
|
||||
|
||||
GQuark dbus_g_error_quark (void);
|
||||
#define DBUS_GERROR dbus_g_error_quark ()
|
||||
|
||||
|
|
@ -221,6 +203,11 @@ typedef struct _DBusGProxyClass DBusGProxyClass;
|
|||
#define DBUS_G_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUS_TYPE_G_PROXY, DBusGProxyClass))
|
||||
|
||||
|
||||
typedef struct _DBusGProxyCall DBusGProxyCall;
|
||||
typedef void (* DBusGProxyCallNotify) (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call_id,
|
||||
void *user_data);
|
||||
|
||||
GType dbus_g_proxy_get_type (void) G_GNUC_CONST;
|
||||
DBusGProxy* dbus_g_proxy_new_for_name (DBusGConnection *connection,
|
||||
const char *name,
|
||||
|
|
@ -266,15 +253,20 @@ void dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
|
|||
GType first_arg_type,
|
||||
...);
|
||||
|
||||
DBusGPendingCall* dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
||||
DBusGProxyCall * dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy,
|
||||
GType first_arg_type,
|
||||
...);
|
||||
gboolean dbus_g_proxy_end_call (DBusGProxy *proxy,
|
||||
DBusGPendingCall *pending,
|
||||
DBusGProxyCall *call,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
...);
|
||||
void dbus_g_proxy_cancel_call (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call);
|
||||
|
||||
const char* dbus_g_proxy_get_path (DBusGProxy *proxy);
|
||||
|
||||
|
|
@ -288,12 +280,6 @@ void dbus_g_method_return (DBusGMethodInvocation *con
|
|||
|
||||
void dbus_g_method_return_error (DBusGMethodInvocation *context, GError *error);
|
||||
|
||||
typedef struct {
|
||||
DBusGProxy *proxy;
|
||||
gpointer cb;
|
||||
gpointer userdata;
|
||||
} DBusGAsyncData;
|
||||
|
||||
#undef DBUS_INSIDE_DBUS_GLIB_H
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -1350,7 +1350,9 @@ generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error
|
|||
|
||||
WRITE_OR_LOSE ("G_TYPE_INVALID);\n}\n\n");
|
||||
|
||||
#if 0
|
||||
write_async_method_client (channel, interface, method, error);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!write_printf_to_iochannel ("#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_%s */\n\n", channel, error, iface_prefix))
|
||||
|
|
|
|||
140
glib/dbus-glib.c
140
glib/dbus-glib.c
|
|
@ -111,30 +111,6 @@ dbus_g_message_unref (DBusGMessage *gmessage)
|
|||
dbus_message_unref (c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments refcount on a pending call.
|
||||
*
|
||||
* @param call the call
|
||||
* @returns the same call
|
||||
*/
|
||||
DBusGPendingCall*
|
||||
dbus_g_pending_call_ref (DBusGPendingCall *call)
|
||||
{
|
||||
dbus_pending_call_ref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
|
||||
return call;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements refcount on a pending call.
|
||||
*
|
||||
* @param call the call
|
||||
*/
|
||||
void
|
||||
dbus_g_pending_call_unref (DBusGPendingCall *call)
|
||||
{
|
||||
dbus_pending_call_unref (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call));
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of DBUS_GERROR error domain. See documentation
|
||||
* for GError in GLib reference manual.
|
||||
|
|
@ -234,24 +210,6 @@ dbus_message_get_g_type (void)
|
|||
return our_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GLib type ID for a DBusPendingCall boxed type.
|
||||
*
|
||||
* @returns GLib type
|
||||
*/
|
||||
GType
|
||||
dbus_pending_call_get_g_type (void)
|
||||
{
|
||||
static GType our_type = 0;
|
||||
|
||||
if (our_type == 0)
|
||||
our_type = g_boxed_type_register_static ("DBusPendingCall",
|
||||
(GBoxedCopyFunc) dbus_pending_call_ref,
|
||||
(GBoxedFreeFunc) dbus_pending_call_unref);
|
||||
|
||||
return our_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GLib type ID for a DBusGConnection boxed type.
|
||||
*
|
||||
|
|
@ -288,24 +246,6 @@ dbus_g_message_get_g_type (void)
|
|||
return our_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GLib type ID for a DBusGPendingCall boxed type.
|
||||
*
|
||||
* @returns GLib type
|
||||
*/
|
||||
GType
|
||||
dbus_g_pending_call_get_g_type (void)
|
||||
{
|
||||
static GType our_type = 0;
|
||||
|
||||
if (our_type == 0)
|
||||
our_type = g_boxed_type_register_static ("DBusGPendingCall",
|
||||
(GBoxedCopyFunc) dbus_g_pending_call_ref,
|
||||
(GBoxedFreeFunc) dbus_g_pending_call_unref);
|
||||
|
||||
return our_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DBusConnection corresponding to this DBusGConnection.
|
||||
* The return value does not have its refcount incremented.
|
||||
|
|
@ -330,86 +270,6 @@ dbus_g_message_get_message (DBusGMessage *gmessage)
|
|||
return DBUS_MESSAGE_FROM_G_MESSAGE (gmessage);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DBusGPendingCallNotify func;
|
||||
void *data;
|
||||
GDestroyNotify free_data_func;
|
||||
} GPendingNotifyClosure;
|
||||
|
||||
static void
|
||||
d_pending_call_notify (DBusPendingCall *dcall,
|
||||
void *data)
|
||||
{
|
||||
GPendingNotifyClosure *closure = data;
|
||||
DBusGPendingCall *gcall = DBUS_G_PENDING_CALL_FROM_PENDING_CALL (dcall);
|
||||
|
||||
(* closure->func) (gcall, closure->data);
|
||||
}
|
||||
|
||||
static void
|
||||
d_pending_call_free (void *data)
|
||||
{
|
||||
GPendingNotifyClosure *closure = data;
|
||||
|
||||
if (closure->free_data_func)
|
||||
(* closure->free_data_func) (closure->data);
|
||||
|
||||
g_free (closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a notification to be invoked when the pending call
|
||||
* is ready to be ended without blocking.
|
||||
* You can call dbus_g_proxy_end_call() at any time,
|
||||
* but it will block if no reply or error has been received yet.
|
||||
* This function lets you handle the reply asynchronously.
|
||||
*
|
||||
* @param call the pending call
|
||||
* @param callback the callback
|
||||
* @param callback_data data for the callback
|
||||
* @param free_data_func free the callback data with this
|
||||
*/
|
||||
void
|
||||
dbus_g_pending_call_set_notify (DBusGPendingCall *call,
|
||||
DBusGPendingCallNotify callback,
|
||||
void *callback_data,
|
||||
GDestroyNotify free_data_func)
|
||||
{
|
||||
GPendingNotifyClosure *closure;
|
||||
DBusPendingCall *dcall;
|
||||
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
closure = g_new (GPendingNotifyClosure, 1);
|
||||
|
||||
closure->func = callback;
|
||||
closure->data = callback_data;
|
||||
closure->free_data_func = free_data_func;
|
||||
|
||||
dcall = DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call);
|
||||
dbus_pending_call_set_notify (dcall, d_pending_call_notify,
|
||||
closure,
|
||||
d_pending_call_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a pending call. Does not affect the reference count
|
||||
* of the call, but it means you will never be notified of call
|
||||
* completion, and can't call dbus_g_proxy_end_call().
|
||||
*
|
||||
* @param call the call
|
||||
*/
|
||||
void
|
||||
dbus_g_pending_call_cancel (DBusGPendingCall *call)
|
||||
{
|
||||
DBusPendingCall *dcall;
|
||||
|
||||
dcall = DBUS_PENDING_CALL_FROM_G_PENDING_CALL (call);
|
||||
|
||||
dbus_pending_call_cancel (dcall);
|
||||
}
|
||||
|
||||
/** @} */ /* end of public API */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ typedef struct
|
|||
} DBusGErrorInfo;
|
||||
|
||||
static GStaticRWLock globals_lock = G_STATIC_RW_LOCK_INIT;
|
||||
static GHashTable *info_hash = NULL;
|
||||
static GHashTable *marshal_table = NULL;
|
||||
static GData *error_metadata = NULL;
|
||||
|
||||
|
|
@ -222,6 +221,16 @@ propsig_iterate (const char *data, const char **iface, const char **name)
|
|||
return string_table_next (data);
|
||||
}
|
||||
|
||||
static GQuark
|
||||
dbus_g_object_type_dbus_metadata_quark (void)
|
||||
{
|
||||
static GQuark quark;
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_from_static_string ("DBusGObjectTypeDBusMetadataQuark");
|
||||
return quark;
|
||||
}
|
||||
|
||||
static const DBusGObjectInfo *
|
||||
lookup_object_info (GObject *object)
|
||||
{
|
||||
|
|
@ -230,16 +239,11 @@ lookup_object_info (GObject *object)
|
|||
|
||||
ret = NULL;
|
||||
|
||||
g_static_rw_lock_reader_lock (&globals_lock);
|
||||
|
||||
if (info_hash == NULL)
|
||||
goto out;
|
||||
|
||||
for (classtype = G_TYPE_FROM_INSTANCE (object); classtype != 0; classtype = g_type_parent (classtype))
|
||||
{
|
||||
const DBusGObjectInfo *info;
|
||||
|
||||
info = g_hash_table_lookup (info_hash, g_type_class_peek (classtype));
|
||||
info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ());
|
||||
|
||||
if (info != NULL && info->format_version == 0)
|
||||
{
|
||||
|
|
@ -248,9 +252,6 @@ lookup_object_info (GObject *object)
|
|||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_static_rw_lock_reader_unlock (&globals_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1355,28 +1356,13 @@ void
|
|||
dbus_g_object_type_install_info (GType object_type,
|
||||
const DBusGObjectInfo *info)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
g_return_if_fail (G_TYPE_IS_OBJECT (object_type));
|
||||
g_return_if_fail (G_TYPE_IS_CLASSED (object_type));
|
||||
|
||||
dbus_g_value_types_init ();
|
||||
|
||||
object_class = g_type_class_ref (object_type);
|
||||
|
||||
g_return_if_fail (G_IS_OBJECT_CLASS (object_class));
|
||||
|
||||
g_static_rw_lock_writer_lock (&globals_lock);
|
||||
|
||||
if (info_hash == NULL)
|
||||
{
|
||||
info_hash = g_hash_table_new (NULL, NULL); /* direct hash */
|
||||
}
|
||||
|
||||
g_hash_table_replace (info_hash, object_class, (void*) info);
|
||||
|
||||
g_static_rw_lock_writer_unlock (&globals_lock);
|
||||
|
||||
g_type_class_unref (object_class);
|
||||
g_type_set_qdata (object_type,
|
||||
dbus_g_object_type_dbus_metadata_quark (),
|
||||
(gpointer) info);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ validate_signature (const char *str,
|
|||
|
||||
if (!dbus_signature_validate (str, &derror))
|
||||
{
|
||||
dbus_set_g_error (&derror, error);
|
||||
dbus_set_g_error (error, &derror);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
#define DBUS_G_PROXY_CALL_TO_ID(x) (GPOINTER_TO_UINT(x))
|
||||
#define DBUS_G_PROXY_ID_TO_CALL(x) (GUINT_TO_POINTER(x))
|
||||
|
||||
/**
|
||||
* @addtogroup DBusGLibInternals
|
||||
*
|
||||
|
|
@ -56,11 +59,16 @@ struct _DBusGProxy
|
|||
char *path; /**< Path messages go to or NULL */
|
||||
char *interface; /**< Interface messages go to or NULL */
|
||||
|
||||
DBusGPendingCall *name_call;/**< Pending call to retrieve name owner */
|
||||
DBusGProxyCall *name_call; /**< Pending call id to retrieve name owner */
|
||||
guint for_owner : 1; /**< Whether or not this proxy is for a name owner */
|
||||
guint associated : 1; /**< Whether or not this proxy is associated (for name proxies) */
|
||||
|
||||
/* FIXME: make threadsafe? */
|
||||
guint call_id_counter; /**< Integer counter for pending calls */
|
||||
|
||||
GData *signal_signatures; /**< D-BUS signatures for each signal */
|
||||
|
||||
GHashTable *pending_calls; /**< Calls made on this proxy which have not yet returned */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -73,18 +81,42 @@ struct _DBusGProxyClass
|
|||
|
||||
static void dbus_g_proxy_init (DBusGProxy *proxy);
|
||||
static void dbus_g_proxy_class_init (DBusGProxyClass *klass);
|
||||
static GObject *dbus_g_proxy_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_properties);
|
||||
static void dbus_g_proxy_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void dbus_g_proxy_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void dbus_g_proxy_finalize (GObject *object);
|
||||
static void dbus_g_proxy_dispose (GObject *object);
|
||||
static void dbus_g_proxy_destroy (DBusGProxy *proxy);
|
||||
static void dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy,
|
||||
DBusMessage *message);
|
||||
|
||||
static gboolean dbus_g_pending_call_end (DBusGConnection *connection,
|
||||
DBusGProxy *proxycon,
|
||||
DBusGPendingCall *pending,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
...);
|
||||
static DBusGProxyCall *manager_begin_bus_call (DBusGProxyManager *manager,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy,
|
||||
GType first_arg_type,
|
||||
...);
|
||||
static guint dbus_g_proxy_begin_call_internal (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy,
|
||||
GValueArray *args);
|
||||
static gboolean dbus_g_proxy_end_call_internal (DBusGProxy *proxy,
|
||||
guint call_id,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
va_list args);
|
||||
|
||||
/**
|
||||
* A list of proxies with a given name+path+interface, used to
|
||||
|
|
@ -112,6 +144,8 @@ struct _DBusGProxyManager
|
|||
int refcount; /**< Reference count */
|
||||
DBusConnection *connection; /**< Connection we're associated with. */
|
||||
|
||||
DBusGProxy *bus_proxy; /**< Special internal proxy used to talk to the bus */
|
||||
|
||||
GHashTable *proxy_lists; /**< Hash used to route incoming signals
|
||||
* and iterate over proxies
|
||||
*/
|
||||
|
|
@ -119,9 +153,6 @@ struct _DBusGProxyManager
|
|||
* base name -> [name,name,...] for proxies which
|
||||
* are for names.
|
||||
*/
|
||||
GSList *pending_nameowner_calls; /**< List to keep track of pending
|
||||
* GetNameOwner calls
|
||||
*/
|
||||
GSList *unassociated_proxies; /**< List of name proxies for which
|
||||
* there was no result for
|
||||
* GetNameOwner
|
||||
|
|
@ -168,7 +199,7 @@ dbus_g_proxy_manager_get (DBusConnection *connection)
|
|||
|
||||
manager->refcount = 1;
|
||||
manager->connection = connection;
|
||||
|
||||
|
||||
g_static_mutex_init (&manager->lock);
|
||||
|
||||
/* Proxy managers keep the connection alive, which means that
|
||||
|
|
@ -215,6 +246,9 @@ dbus_g_proxy_manager_unref (DBusGProxyManager *manager)
|
|||
{
|
||||
UNLOCK_MANAGER (manager);
|
||||
|
||||
if (manager->bus_proxy)
|
||||
g_object_unref (manager->bus_proxy);
|
||||
|
||||
if (manager->proxy_lists)
|
||||
{
|
||||
/* can't have any proxies left since they hold
|
||||
|
|
@ -238,7 +272,6 @@ dbus_g_proxy_manager_unref (DBusGProxyManager *manager)
|
|||
manager->owner_names = NULL;
|
||||
}
|
||||
|
||||
g_assert (manager->pending_nameowner_calls == NULL);
|
||||
g_assert (manager->unassociated_proxies == NULL);
|
||||
|
||||
g_static_mutex_free (&manager->lock);
|
||||
|
|
@ -723,13 +756,13 @@ dbus_g_proxy_manager_replace_name_owner (DBusGProxyManager *manager,
|
|||
}
|
||||
|
||||
static void
|
||||
got_name_owner_cb (DBusGPendingCall *pending,
|
||||
got_name_owner_cb (DBusGProxy *bus_proxy,
|
||||
DBusGProxyCall *call,
|
||||
void *user_data)
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
GError *error;
|
||||
char *owner;
|
||||
GSList *link;
|
||||
|
||||
proxy = user_data;
|
||||
error = NULL;
|
||||
|
|
@ -737,15 +770,9 @@ got_name_owner_cb (DBusGPendingCall *pending,
|
|||
|
||||
LOCK_MANAGER (proxy->manager);
|
||||
|
||||
link = g_slist_find (proxy->manager->pending_nameowner_calls, pending);
|
||||
g_assert (link != NULL);
|
||||
|
||||
if (!dbus_g_pending_call_end (DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection),
|
||||
NULL,
|
||||
pending,
|
||||
&error,
|
||||
G_TYPE_STRING, &owner,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_end_call (bus_proxy, call, &error,
|
||||
G_TYPE_STRING, &owner,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NAME_HAS_NO_OWNER)
|
||||
{
|
||||
|
|
@ -767,7 +794,6 @@ got_name_owner_cb (DBusGPendingCall *pending,
|
|||
|
||||
out:
|
||||
proxy->name_call = NULL;
|
||||
proxy->manager->pending_nameowner_calls = g_slist_delete_link (proxy->manager->pending_nameowner_calls, link);
|
||||
UNLOCK_MANAGER (proxy->manager);
|
||||
g_free (owner);
|
||||
}
|
||||
|
|
@ -911,46 +937,14 @@ dbus_g_proxy_manager_register (DBusGProxyManager *manager,
|
|||
|
||||
if (!dbus_g_proxy_manager_lookup_name_owner (manager, proxy->name, &info, &owner))
|
||||
{
|
||||
DBusPendingCall *pending;
|
||||
DBusGPendingCall *gpending;
|
||||
DBusMessage *request, *reply;
|
||||
|
||||
g_assert (owner == NULL);
|
||||
|
||||
reply = NULL;
|
||||
|
||||
request = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS,
|
||||
"GetNameOwner");
|
||||
if (request == NULL)
|
||||
g_error ("Out of memory");
|
||||
|
||||
if (!dbus_message_append_args (request,
|
||||
DBUS_TYPE_STRING, &(proxy->name),
|
||||
DBUS_TYPE_INVALID))
|
||||
g_error ("Out of memory");
|
||||
|
||||
if (!dbus_connection_send_with_reply (manager->connection,
|
||||
request,
|
||||
&pending,
|
||||
-1))
|
||||
g_error ("Out of memory");
|
||||
g_assert (pending != NULL);
|
||||
|
||||
gpending = DBUS_G_PENDING_CALL_FROM_PENDING_CALL (pending);
|
||||
|
||||
/* It's safe to keep a reference to proxy here;
|
||||
* when the proxy is unreffed we cancel the call
|
||||
*/
|
||||
dbus_g_pending_call_set_notify (gpending,
|
||||
got_name_owner_cb,
|
||||
proxy,
|
||||
NULL);
|
||||
proxy->name_call = manager_begin_bus_call (manager, "GetNameOwner",
|
||||
got_name_owner_cb,
|
||||
proxy, NULL,
|
||||
G_TYPE_STRING,
|
||||
proxy->name,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
proxy->associated = FALSE;
|
||||
proxy->name_call = gpending;
|
||||
manager->pending_nameowner_calls = g_slist_prepend (manager->pending_nameowner_calls, gpending);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1003,14 +997,10 @@ dbus_g_proxy_manager_unregister (DBusGProxyManager *manager,
|
|||
{
|
||||
GSList *link;
|
||||
|
||||
if (proxy->name_call != NULL)
|
||||
if (proxy->name_call != 0)
|
||||
{
|
||||
link = g_slist_find (manager->pending_nameowner_calls, proxy->name_call);
|
||||
g_assert (link != NULL);
|
||||
|
||||
dbus_g_pending_call_cancel (proxy->name_call);
|
||||
|
||||
manager->pending_nameowner_calls = g_slist_delete_link (manager->pending_nameowner_calls, link);
|
||||
dbus_g_proxy_cancel_call (manager->bus_proxy, proxy->name_call);
|
||||
proxy->name_call = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1022,7 +1012,7 @@ dbus_g_proxy_manager_unregister (DBusGProxyManager *manager,
|
|||
}
|
||||
else
|
||||
{
|
||||
g_assert (proxy->name_call == NULL);
|
||||
g_assert (proxy->name_call == 0);
|
||||
|
||||
dbus_g_proxy_manager_unmonitor_name_owner (manager, proxy->name);
|
||||
}
|
||||
|
|
@ -1267,6 +1257,13 @@ marshal_dbus_message_to_g_marshaller (GClosure *closure,
|
|||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_PATH,
|
||||
PROP_INTERFACE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -1282,6 +1279,31 @@ static void
|
|||
dbus_g_proxy_init (DBusGProxy *proxy)
|
||||
{
|
||||
g_datalist_init (&proxy->signal_signatures);
|
||||
proxy->pending_calls = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) dbus_pending_call_unref);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
dbus_g_proxy_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_properties)
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
DBusGProxyClass *klass;
|
||||
GObjectClass *parent_class;
|
||||
|
||||
klass = DBUS_G_PROXY_CLASS (g_type_class_peek (DBUS_TYPE_G_PROXY));
|
||||
|
||||
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
|
||||
|
||||
proxy = DBUS_G_PROXY (parent_class->constructor (type, n_construct_properties,
|
||||
construct_properties));
|
||||
|
||||
proxy->for_owner = (proxy->name[0] == ':');
|
||||
proxy->name_call = 0;
|
||||
proxy->associated = FALSE;
|
||||
|
||||
return G_OBJECT (proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1290,9 +1312,37 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass)
|
|||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->set_property = dbus_g_proxy_set_property;
|
||||
object_class->get_property = dbus_g_proxy_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
"name",
|
||||
"name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PATH,
|
||||
g_param_spec_string ("path",
|
||||
"path",
|
||||
"path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INTERFACE,
|
||||
g_param_spec_string ("interface",
|
||||
"interface",
|
||||
"interface",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
object_class->finalize = dbus_g_proxy_finalize;
|
||||
object_class->dispose = dbus_g_proxy_dispose;
|
||||
object_class->constructor = dbus_g_proxy_constructor;
|
||||
|
||||
signals[DESTROY] =
|
||||
g_signal_new ("destroy",
|
||||
|
|
@ -1313,6 +1363,15 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass)
|
|||
G_TYPE_NONE, 2, DBUS_TYPE_MESSAGE, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_pending_call (gpointer key, gpointer val, gpointer data)
|
||||
{
|
||||
DBusGProxyCall *call = key;
|
||||
DBusGProxy *proxy = data;
|
||||
|
||||
dbus_g_proxy_cancel_call (proxy, call);
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_g_proxy_dispose (GObject *object)
|
||||
{
|
||||
|
|
@ -1320,12 +1379,16 @@ dbus_g_proxy_dispose (GObject *object)
|
|||
|
||||
proxy = DBUS_G_PROXY (object);
|
||||
|
||||
if (proxy->manager)
|
||||
/* Cancel outgoing pending calls */
|
||||
g_hash_table_foreach (proxy->pending_calls, cancel_pending_call, proxy);
|
||||
g_hash_table_destroy (proxy->pending_calls);
|
||||
|
||||
if (proxy->manager && proxy != proxy->manager->bus_proxy)
|
||||
{
|
||||
dbus_g_proxy_manager_unregister (proxy->manager, proxy);
|
||||
dbus_g_proxy_manager_unref (proxy->manager);
|
||||
proxy->manager = NULL;
|
||||
}
|
||||
proxy->manager = NULL;
|
||||
|
||||
g_datalist_clear (&proxy->signal_signatures);
|
||||
|
||||
|
|
@ -1359,6 +1422,56 @@ dbus_g_proxy_destroy (DBusGProxy *proxy)
|
|||
g_object_run_dispose (G_OBJECT (proxy));
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_g_proxy_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DBusGProxy *proxy = DBUS_G_PROXY (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
proxy->name = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
case PROP_PATH:
|
||||
proxy->path = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
case PROP_INTERFACE:
|
||||
proxy->interface = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_g_proxy_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DBusGProxy *proxy = DBUS_G_PROXY (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, proxy->name);
|
||||
break;
|
||||
case PROP_PATH:
|
||||
g_value_set_string (value, proxy->path);
|
||||
break;
|
||||
case PROP_INTERFACE:
|
||||
g_value_set_string (value, proxy->interface);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is to avoid people using g_signal_connect() directly,
|
||||
* to avoid confusion with local signal names, and because
|
||||
* of the horribly broken current setup (signals are added
|
||||
|
|
@ -1514,6 +1627,91 @@ dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy,
|
|||
goto out;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
guint call_id;
|
||||
DBusGProxyCallNotify func;
|
||||
void *data;
|
||||
GDestroyNotify free_data_func;
|
||||
} GPendingNotifyClosure;
|
||||
|
||||
static void
|
||||
d_pending_call_notify (DBusPendingCall *dcall,
|
||||
void *data)
|
||||
{
|
||||
GPendingNotifyClosure *closure = data;
|
||||
|
||||
(* closure->func) (closure->proxy, DBUS_G_PROXY_ID_TO_CALL (closure->call_id), closure->data);
|
||||
}
|
||||
|
||||
static void
|
||||
d_pending_call_free (void *data)
|
||||
{
|
||||
GPendingNotifyClosure *closure = data;
|
||||
|
||||
if (closure->free_data_func)
|
||||
(* closure->free_data_func) (closure->data);
|
||||
|
||||
g_free (closure);
|
||||
}
|
||||
|
||||
#define DBUS_G_VALUE_ARRAY_COLLECT_ALL(VALARRAY, FIRST_ARG_TYPE, ARGS) \
|
||||
do { \
|
||||
GType valtype; \
|
||||
int i = 0; \
|
||||
VALARRAY = g_value_array_new (6); \
|
||||
valtype = FIRST_ARG_TYPE; \
|
||||
while (valtype != G_TYPE_INVALID) \
|
||||
{ \
|
||||
const char *collect_err; \
|
||||
GValue *val; \
|
||||
g_value_array_append (VALARRAY, NULL); \
|
||||
val = g_value_array_get_nth (VALARRAY, i); \
|
||||
g_value_init (val, valtype); \
|
||||
collect_err = NULL; \
|
||||
G_VALUE_COLLECT (val, ARGS, G_VALUE_NOCOPY_CONTENTS, &collect_err); \
|
||||
valtype = va_arg (ARGS, GType); \
|
||||
i++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
DBusGProxyCall *
|
||||
manager_begin_bus_call (DBusGProxyManager *manager,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy,
|
||||
GType first_arg_type,
|
||||
...)
|
||||
{
|
||||
DBusGProxyCall *call;
|
||||
va_list args;
|
||||
GValueArray *arg_values;
|
||||
|
||||
va_start (args, first_arg_type);
|
||||
|
||||
if (!manager->bus_proxy)
|
||||
{
|
||||
manager->bus_proxy = g_object_new (DBUS_TYPE_G_PROXY,
|
||||
"name", DBUS_SERVICE_DBUS,
|
||||
"path", DBUS_PATH_DBUS,
|
||||
"interface", DBUS_INTERFACE_DBUS,
|
||||
NULL);
|
||||
manager->bus_proxy->manager = manager;
|
||||
}
|
||||
|
||||
DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args);
|
||||
|
||||
call = DBUS_G_PROXY_ID_TO_CALL (dbus_g_proxy_begin_call_internal (manager->bus_proxy, method, notify, user_data, destroy, arg_values));
|
||||
|
||||
g_value_array_free (arg_values);
|
||||
|
||||
va_end (args);
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
/** @} End of DBusGLibInternals */
|
||||
|
||||
/** @addtogroup DBusGLib
|
||||
|
|
@ -1563,21 +1761,13 @@ dbus_g_proxy_new (DBusGConnection *connection,
|
|||
|
||||
g_assert (connection != NULL);
|
||||
|
||||
proxy = g_object_new (DBUS_TYPE_G_PROXY, NULL);
|
||||
proxy = g_object_new (DBUS_TYPE_G_PROXY, "name", name, "path", path_name, "interface", interface_name, NULL);
|
||||
|
||||
/* These should all be construct-only mandatory properties,
|
||||
* for now we just don't let people use g_object_new().
|
||||
*/
|
||||
|
||||
proxy->manager = dbus_g_proxy_manager_get (DBUS_CONNECTION_FROM_G_CONNECTION (connection));
|
||||
|
||||
proxy->name = g_strdup (name);
|
||||
proxy->path = g_strdup (path_name);
|
||||
proxy->interface = g_strdup (interface_name);
|
||||
|
||||
proxy->for_owner = (proxy->name[0] == ':');
|
||||
proxy->name_call = NULL;
|
||||
proxy->associated = FALSE;
|
||||
|
||||
dbus_g_proxy_manager_register (proxy->manager, proxy);
|
||||
|
||||
|
|
@ -1830,33 +2020,18 @@ dbus_g_proxy_marshal_args_to_message (DBusGProxy *proxy,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define DBUS_G_VALUE_ARRAY_COLLECT_ALL(VALARRAY, FIRST_ARG_TYPE, ARGS) \
|
||||
do { \
|
||||
GType valtype; \
|
||||
int i = 0; \
|
||||
VALARRAY = g_value_array_new (6); \
|
||||
valtype = FIRST_ARG_TYPE; \
|
||||
while (valtype != G_TYPE_INVALID) \
|
||||
{ \
|
||||
const char *collect_err; \
|
||||
GValue *val; \
|
||||
g_value_array_append (VALARRAY, NULL); \
|
||||
val = g_value_array_get_nth (VALARRAY, i); \
|
||||
g_value_init (val, valtype); \
|
||||
collect_err = NULL; \
|
||||
G_VALUE_COLLECT (val, ARGS, G_VALUE_NOCOPY_CONTENTS, &collect_err); \
|
||||
valtype = va_arg (ARGS, GType); \
|
||||
i++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static DBusGPendingCall *
|
||||
dbus_g_proxy_begin_call_internal (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
GValueArray *args)
|
||||
static guint
|
||||
dbus_g_proxy_begin_call_internal (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy,
|
||||
GValueArray *args)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusPendingCall *pending;
|
||||
GPendingNotifyClosure *closure;
|
||||
guint call_id;
|
||||
|
||||
g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE);
|
||||
g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE);
|
||||
|
|
@ -1874,16 +2049,32 @@ dbus_g_proxy_begin_call_internal (DBusGProxy *proxy,
|
|||
goto oom;
|
||||
g_assert (pending != NULL);
|
||||
|
||||
return DBUS_G_PENDING_CALL_FROM_PENDING_CALL (pending);
|
||||
call_id = ++proxy->call_id_counter;
|
||||
|
||||
if (notify != NULL)
|
||||
{
|
||||
closure = g_new (GPendingNotifyClosure, 1);
|
||||
closure->proxy = proxy; /* No need to ref as the lifecycle is tied to proxy */
|
||||
closure->call_id = call_id;
|
||||
closure->func = notify;
|
||||
closure->data = user_data;
|
||||
closure->free_data_func = destroy;
|
||||
dbus_pending_call_set_notify (pending, d_pending_call_notify,
|
||||
closure,
|
||||
d_pending_call_free);
|
||||
}
|
||||
|
||||
g_hash_table_insert (proxy->pending_calls, GUINT_TO_POINTER (call_id), pending);
|
||||
|
||||
return call_id;
|
||||
oom:
|
||||
g_error ("Out of memory");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_g_pending_call_end_valist (DBusGConnection *connection,
|
||||
DBusGProxy *proxycon,
|
||||
DBusGPendingCall *pending,
|
||||
dbus_g_proxy_end_call_internal (DBusGProxy *proxy,
|
||||
guint call_id,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
va_list args)
|
||||
|
|
@ -1896,13 +2087,17 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection,
|
|||
int n_retvals_processed;
|
||||
gboolean ret;
|
||||
GType valtype;
|
||||
DBusPendingCall *pending;
|
||||
|
||||
reply = NULL;
|
||||
ret = FALSE;
|
||||
n_retvals_processed = 0;
|
||||
over = 0;
|
||||
dbus_pending_call_block (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending));
|
||||
reply = dbus_pending_call_steal_reply (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending));
|
||||
|
||||
pending = g_hash_table_lookup (proxy->pending_calls, GUINT_TO_POINTER (call_id));
|
||||
|
||||
dbus_pending_call_block (pending);
|
||||
reply = dbus_pending_call_steal_reply (pending);
|
||||
|
||||
g_assert (reply != NULL);
|
||||
|
||||
|
|
@ -1921,9 +2116,8 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection,
|
|||
GValue gvalue = { 0, };
|
||||
DBusGValueMarshalCtx context;
|
||||
|
||||
context.gconnection = connection;
|
||||
context.proxy = proxycon;
|
||||
|
||||
context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection);
|
||||
context.proxy = proxy;
|
||||
|
||||
arg_type = dbus_message_iter_get_arg_type (&msgiter);
|
||||
if (arg_type == DBUS_TYPE_INVALID)
|
||||
|
|
@ -2039,76 +2233,44 @@ dbus_g_pending_call_end_valist (DBusGConnection *connection,
|
|||
}
|
||||
va_end (args_unwind);
|
||||
|
||||
if (pending)
|
||||
dbus_g_pending_call_unref (pending);
|
||||
g_hash_table_remove (proxy->pending_calls, GUINT_TO_POINTER (call_id));
|
||||
|
||||
if (reply)
|
||||
dbus_message_unref (reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_g_pending_call_end (DBusGConnection *connection,
|
||||
DBusGProxy *proxycon,
|
||||
DBusGPendingCall *pending,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
gboolean ret;
|
||||
|
||||
va_start (args, first_arg_type);
|
||||
|
||||
ret = dbus_g_pending_call_end_valist (connection, proxycon, pending,
|
||||
error, first_arg_type, args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_g_proxy_end_call_internal (DBusGProxy *proxy,
|
||||
DBusGPendingCall *pending,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
va_list args)
|
||||
{
|
||||
return dbus_g_pending_call_end_valist (DBUS_G_CONNECTION_FROM_CONNECTION (proxy->manager->connection),
|
||||
proxy,
|
||||
pending,
|
||||
error,
|
||||
first_arg_type,
|
||||
args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invokes a method on a remote interface. This function does not
|
||||
* block; instead it returns an opaque #DBusPendingCall object that
|
||||
* tracks the pending call. The method call will not be sent over the
|
||||
* wire until the application returns to the main loop, or blocks in
|
||||
* dbus_connection_flush() to write out pending data. The call will
|
||||
* be completed after a timeout, or when a reply is received.
|
||||
* To collect the results of the call (which may be an error,
|
||||
* or a reply), use dbus_g_proxy_end_call().
|
||||
* Asynchronously invokes a method on a remote interface. The method
|
||||
* call will not be sent over the wire until the application returns
|
||||
* to the main loop, or blocks in dbus_connection_flush() to write out
|
||||
* pending data. The call will be completed after a timeout, or when
|
||||
* a reply is received. When the call returns, the callback specified
|
||||
* will be invoked; you can then collect the results of the call
|
||||
* (which may be an error, or a reply), use dbus_g_proxy_end_call().
|
||||
*
|
||||
* @todo this particular function shouldn't die on out of memory,
|
||||
* since you should be able to do a call with large arguments.
|
||||
*
|
||||
* @param proxy a proxy for a remote interface
|
||||
* @param method the name of the method to invoke
|
||||
* @param notify callback to be invoked when method returns
|
||||
* @param user_data user data passed to callback
|
||||
* @param destroy function called to destroy user_data
|
||||
* @param first_arg_type type of the first argument
|
||||
*
|
||||
* @returns opaque pending call object
|
||||
* @returns call identifier
|
||||
* */
|
||||
DBusGPendingCall*
|
||||
dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
GType first_arg_type,
|
||||
...)
|
||||
DBusGProxyCall *
|
||||
dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
||||
const char *method,
|
||||
DBusGProxyCallNotify notify,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy,
|
||||
GType first_arg_type,
|
||||
...)
|
||||
{
|
||||
DBusGPendingCall *pending;
|
||||
guint call_id;
|
||||
va_list args;
|
||||
GValueArray *arg_values;
|
||||
|
||||
|
|
@ -2116,21 +2278,21 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
|||
|
||||
DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args);
|
||||
|
||||
pending = dbus_g_proxy_begin_call_internal (proxy, method, arg_values);
|
||||
call_id = dbus_g_proxy_begin_call_internal (proxy, method, notify, user_data, destroy, arg_values);
|
||||
|
||||
g_value_array_free (arg_values);
|
||||
|
||||
va_end (args);
|
||||
|
||||
return pending;
|
||||
return DBUS_G_PROXY_ID_TO_CALL (call_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the results of a method call. The method call was normally
|
||||
* initiated with dbus_g_proxy_end_call(). This function will block if
|
||||
* the results haven't yet been received; use
|
||||
* dbus_g_pending_call_set_notify() to be notified asynchronously that a
|
||||
* pending call has been completed. If it's completed, it will not block.
|
||||
* initiated with dbus_g_proxy_end_call(). You may use this function
|
||||
* outside of the callback given to dbus_g_proxy_begin_call; in that
|
||||
* case this function will block if the results haven't yet been
|
||||
* received.
|
||||
*
|
||||
* If the call results in an error, the error is set as normal for
|
||||
* GError and the function returns #FALSE.
|
||||
|
|
@ -2139,17 +2301,15 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy,
|
|||
* method are stored in the provided varargs list.
|
||||
* The list should be terminated with G_TYPE_INVALID.
|
||||
*
|
||||
* This function unrefs the pending call.
|
||||
*
|
||||
* @param proxy a proxy for a remote interface
|
||||
* @param pending the pending call from dbus_g_proxy_begin_call()
|
||||
* @param call_id the pending call ID from dbus_g_proxy_begin_call()
|
||||
* @param error return location for an error
|
||||
* @param first_arg_type type of first "out" argument
|
||||
* @returns #FALSE if an error is set
|
||||
*/
|
||||
gboolean
|
||||
dbus_g_proxy_end_call (DBusGProxy *proxy,
|
||||
DBusGPendingCall *pending,
|
||||
DBusGProxyCall *call,
|
||||
GError **error,
|
||||
GType first_arg_type,
|
||||
...)
|
||||
|
|
@ -2159,7 +2319,7 @@ dbus_g_proxy_end_call (DBusGProxy *proxy,
|
|||
|
||||
va_start (args, first_arg_type);
|
||||
|
||||
ret = dbus_g_proxy_end_call_internal (proxy, pending, error, first_arg_type, args);
|
||||
ret = dbus_g_proxy_end_call_internal (proxy, GPOINTER_TO_UINT (call), error, first_arg_type, args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
|
|
@ -2187,7 +2347,7 @@ dbus_g_proxy_call (DBusGProxy *proxy,
|
|||
...)
|
||||
{
|
||||
gboolean ret;
|
||||
DBusGPendingCall *pending;
|
||||
guint call_id;
|
||||
va_list args;
|
||||
GValueArray *in_args;
|
||||
|
||||
|
|
@ -2195,12 +2355,12 @@ dbus_g_proxy_call (DBusGProxy *proxy,
|
|||
|
||||
DBUS_G_VALUE_ARRAY_COLLECT_ALL (in_args, first_arg_type, args);
|
||||
|
||||
pending = dbus_g_proxy_begin_call_internal (proxy, method, in_args);
|
||||
call_id = dbus_g_proxy_begin_call_internal (proxy, method, NULL, NULL, NULL, in_args);
|
||||
|
||||
g_value_array_free (in_args);
|
||||
|
||||
first_arg_type = va_arg (args, GType);
|
||||
ret = dbus_g_proxy_end_call_internal (proxy, pending, error, first_arg_type, args);
|
||||
ret = dbus_g_proxy_end_call_internal (proxy, call_id, error, first_arg_type, args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
|
|
@ -2255,6 +2415,35 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy,
|
|||
g_error ("Out of memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a pending method call. The method call was normally
|
||||
* initiated with dbus_g_proxy_begin_call(). This function
|
||||
* may not be used on pending calls that have already been
|
||||
* ended with dbus_g_proxy_end_call.
|
||||
*
|
||||
* @param proxy a proxy for a remote interface
|
||||
* @param call_id the pending call ID from dbus_g_proxy_begin_call()
|
||||
*/
|
||||
void
|
||||
dbus_g_proxy_cancel_call (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call)
|
||||
{
|
||||
guint call_id;
|
||||
DBusPendingCall *pending;
|
||||
|
||||
g_return_if_fail (DBUS_IS_G_PROXY (proxy));
|
||||
g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy));
|
||||
|
||||
call_id = DBUS_G_PROXY_CALL_TO_ID (call);
|
||||
|
||||
pending = g_hash_table_lookup (proxy->pending_calls, GUINT_TO_POINTER (call_id));
|
||||
g_return_if_fail (pending != NULL);
|
||||
|
||||
dbus_pending_call_cancel (pending);
|
||||
|
||||
g_hash_table_remove (proxy->pending_calls, GUINT_TO_POINTER (call_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the interface we're proxying for. Does not
|
||||
* block or wait for a reply. The message is only actually written out
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ static gboolean proxy_destroyed = FALSE;
|
|||
static gboolean proxy_destroy_and_nameowner = FALSE;
|
||||
static gboolean proxy_destroy_and_nameowner_complete = FALSE;
|
||||
|
||||
static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
|
||||
static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
|
||||
|
||||
static gboolean
|
||||
timed_exit (gpointer loop)
|
||||
{
|
||||
|
|
@ -168,8 +171,59 @@ sig2_signal_handler (DBusGProxy *proxy,
|
|||
g_source_remove (exit_timeout);
|
||||
}
|
||||
|
||||
static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
|
||||
static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
|
||||
static DBusGProxyCall *echo_call;
|
||||
static guint n_times_echo_cb_entered;
|
||||
static void
|
||||
echo_received_cb (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error;
|
||||
char *echo_data;
|
||||
|
||||
g_assert (call == echo_call);
|
||||
g_assert (data == NULL);
|
||||
|
||||
error = NULL;
|
||||
echo_data = NULL;
|
||||
n_times_echo_cb_entered++;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_STRING,
|
||||
&echo_data,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete async Echo", error);
|
||||
g_assert (echo_data != NULL);
|
||||
g_print ("Async echo gave \"%s\"", echo_data);
|
||||
g_main_loop_quit (loop);
|
||||
g_source_remove (exit_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
increment_received_cb (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error;
|
||||
char *echo_data;
|
||||
guint val;
|
||||
|
||||
g_assert (!strcmp (data, "moo"));
|
||||
|
||||
error = NULL;
|
||||
echo_data = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_UINT, &val,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete (async) Increment call", error);
|
||||
|
||||
if (val != 43)
|
||||
lose ("Increment call returned %d, should be 43", val);
|
||||
|
||||
g_print ("Async increment gave \"%d\"", val);
|
||||
g_main_loop_quit (loop);
|
||||
g_source_remove (exit_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
lose (const char *str, ...)
|
||||
|
|
@ -215,10 +269,10 @@ main (int argc, char **argv)
|
|||
DBusGProxy *driver;
|
||||
DBusGProxy *proxy;
|
||||
DBusGProxy *proxy2;
|
||||
DBusGPendingCall *call;
|
||||
char **name_list;
|
||||
guint name_list_len;
|
||||
guint i;
|
||||
DBusGProxyCall *call;
|
||||
guint32 result;
|
||||
char *v_STRING_2;
|
||||
guint32 v_UINT32_2;
|
||||
|
|
@ -262,12 +316,11 @@ main (int argc, char **argv)
|
|||
NULL);
|
||||
/* Call ListNames method */
|
||||
|
||||
call = dbus_g_proxy_begin_call (driver, "ListNames", G_TYPE_INVALID);
|
||||
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (driver, call, &error,
|
||||
G_TYPE_STRV, &name_list,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (driver, "ListNames", &error,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRV, &name_list,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete ListNames call", error);
|
||||
|
||||
g_print ("Names on the message bus:\n");
|
||||
|
|
@ -285,53 +338,42 @@ main (int argc, char **argv)
|
|||
|
||||
g_print ("calling ThisMethodDoesNotExist\n");
|
||||
/* Test handling of unknown method */
|
||||
call = dbus_g_proxy_begin_call (driver, "ThisMethodDoesNotExist",
|
||||
G_TYPE_STRING,
|
||||
"blah blah blah blah blah",
|
||||
G_TYPE_INT,
|
||||
10,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
error = NULL;
|
||||
if (dbus_g_proxy_end_call (driver, call, &error,
|
||||
G_TYPE_INVALID))
|
||||
if (dbus_g_proxy_call (driver, "ThisMethodDoesNotExist", &error,
|
||||
G_TYPE_STRING,
|
||||
"blah blah blah blah blah",
|
||||
G_TYPE_INT,
|
||||
10,
|
||||
G_TYPE_INVALID, G_TYPE_INVALID) != FALSE)
|
||||
lose ("Calling nonexistent method succeeded!");
|
||||
|
||||
g_print ("Got EXPECTED error from calling unknown method: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_clear_error (&error);
|
||||
|
||||
run_mainloop ();
|
||||
|
||||
/* Activate a service */
|
||||
g_print ("Activating echo service\n");
|
||||
call = dbus_g_proxy_begin_call (driver, "StartServiceByName",
|
||||
G_TYPE_STRING,
|
||||
"org.freedesktop.DBus.TestSuiteEchoService",
|
||||
G_TYPE_UINT,
|
||||
0,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (driver, call, &error,
|
||||
G_TYPE_UINT, &result,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (driver, "StartServiceByName", &error,
|
||||
G_TYPE_STRING,
|
||||
"org.freedesktop.DBus.TestSuiteEchoService",
|
||||
G_TYPE_UINT, 0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &result,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Activate call", error);
|
||||
|
||||
g_print ("Starting echo service result = 0x%x\n", result);
|
||||
|
||||
/* Activate a service again */
|
||||
g_print ("Activating echo service again\n");
|
||||
call = dbus_g_proxy_begin_call (driver, "StartServiceByName",
|
||||
G_TYPE_STRING,
|
||||
"org.freedesktop.DBus.TestSuiteEchoService",
|
||||
G_TYPE_UINT,
|
||||
0,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (driver, call, &error,
|
||||
G_TYPE_UINT, &result,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (driver, "StartServiceByName", &error,
|
||||
G_TYPE_STRING,
|
||||
"org.freedesktop.DBus.TestSuiteEchoService",
|
||||
G_TYPE_UINT,
|
||||
0,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &result,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Activate call", error);
|
||||
|
||||
g_print ("Duplicate start of echo service = 0x%x\n", result);
|
||||
|
|
@ -351,20 +393,25 @@ main (int argc, char **argv)
|
|||
run_mainloop ();
|
||||
|
||||
g_print ("Calling Echo\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "Echo",
|
||||
G_TYPE_STRING,
|
||||
"my string hello",
|
||||
G_TYPE_INVALID);
|
||||
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (proxy, "Echo", &error,
|
||||
G_TYPE_STRING, "my string hello",
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Echo call", error);
|
||||
|
||||
g_print ("String echoed = \"%s\"\n", v_STRING_2);
|
||||
g_free (v_STRING_2);
|
||||
|
||||
g_print ("Calling Echo (async)\n");
|
||||
echo_call = dbus_g_proxy_begin_call (proxy, "Echo",
|
||||
echo_received_cb, NULL, NULL,
|
||||
G_TYPE_STRING, "my string hello",
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_connection_flush (connection);
|
||||
exit_timeout = g_timeout_add (5000, timed_exit, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
/* Test oneway call and signal handling */
|
||||
|
||||
g_print ("Testing Foo emission\n");
|
||||
|
|
@ -417,10 +464,8 @@ main (int argc, char **argv)
|
|||
lose_gerror ("Failed to create proxy for name owner", error);
|
||||
|
||||
g_print ("Calling DoNothing\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "DoNothing",
|
||||
G_TYPE_INVALID);
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (proxy, "DoNothing", &error,
|
||||
G_TYPE_INVALID, G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete DoNothing call", error);
|
||||
|
||||
g_print ("Calling Increment\n");
|
||||
|
|
@ -431,15 +476,24 @@ main (int argc, char **argv)
|
|||
G_TYPE_UINT, &v_UINT32_2,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Increment call", error);
|
||||
g_assert (n_times_echo_cb_entered == 1);
|
||||
|
||||
if (v_UINT32_2 != 43)
|
||||
lose ("Increment call returned %d, should be 43", v_UINT32_2);
|
||||
|
||||
call = dbus_g_proxy_begin_call (proxy, "Increment",
|
||||
increment_received_cb, g_strdup ("moo"), g_free,
|
||||
G_TYPE_UINT, 42,
|
||||
G_TYPE_INVALID);
|
||||
dbus_g_connection_flush (connection);
|
||||
exit_timeout = g_timeout_add (5000, timed_exit, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_print ("Calling ThrowError\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "ThrowError", G_TYPE_INVALID);
|
||||
error = NULL;
|
||||
if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID) != FALSE)
|
||||
if (dbus_g_proxy_call (proxy, "ThrowError", &error,
|
||||
G_TYPE_INVALID, G_TYPE_INVALID) != FALSE)
|
||||
lose ("ThrowError call unexpectedly succeeded!");
|
||||
|
||||
if (!dbus_g_error_has_name (error, "org.freedesktop.DBus.Tests.MyObject.Foo"))
|
||||
lose ("ThrowError call returned unexpected error \"%s\": %s", dbus_g_error_get_name (error),
|
||||
error->message);
|
||||
|
|
@ -447,14 +501,13 @@ main (int argc, char **argv)
|
|||
g_print ("ThrowError failed (as expected) returned error: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_print ("Calling Uppercase\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "Uppercase",
|
||||
G_TYPE_STRING, "foobar",
|
||||
G_TYPE_INVALID);
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
g_print ("Calling Uppercase\n");
|
||||
if (!dbus_g_proxy_call (proxy, "Uppercase", &error,
|
||||
G_TYPE_STRING, "foobar",
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Uppercase call", error);
|
||||
if (strcmp ("FOOBAR", v_STRING_2) != 0)
|
||||
lose ("Uppercase call returned unexpected string %s", v_STRING_2);
|
||||
|
|
@ -463,16 +516,14 @@ main (int argc, char **argv)
|
|||
run_mainloop ();
|
||||
|
||||
g_print ("Calling ManyArgs\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "ManyArgs",
|
||||
G_TYPE_UINT, 26,
|
||||
G_TYPE_STRING, "bazwhee",
|
||||
G_TYPE_DOUBLE, G_PI,
|
||||
G_TYPE_INVALID);
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_DOUBLE, &v_DOUBLE_2,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (proxy, "ManyArgs", &error,
|
||||
G_TYPE_UINT, 26,
|
||||
G_TYPE_STRING, "bazwhee",
|
||||
G_TYPE_DOUBLE, G_PI,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_DOUBLE, &v_DOUBLE_2,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete ManyArgs call", error);
|
||||
if (v_DOUBLE_2 < 55 || v_DOUBLE_2 > 56)
|
||||
lose ("ManyArgs call returned unexpected double value %f", v_DOUBLE_2);
|
||||
|
|
@ -827,9 +878,9 @@ main (int argc, char **argv)
|
|||
DBUS_TYPE_G_OBJECT_PATH,
|
||||
&ret_path,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete (wrapped) Objpath call 2", error);
|
||||
lose_gerror ("Failed to complete Objpath call 2", error);
|
||||
if (strcmp ("/org/freedesktop/DBus/Tests/MyTestObject2", ret_path) != 0)
|
||||
lose ("(wrapped) objpath call 2 returned unexpected path %s",
|
||||
lose ("Objpath call 2 returned unexpected path %s",
|
||||
ret_path);
|
||||
|
||||
ret_proxy = dbus_g_proxy_new_for_name_owner (connection,
|
||||
|
|
@ -837,6 +888,7 @@ main (int argc, char **argv)
|
|||
ret_path,
|
||||
"org.freedesktop.DBus.Tests.FooObject",
|
||||
&error);
|
||||
g_free (ret_path);
|
||||
|
||||
val = 0;
|
||||
if (!org_freedesktop_DBus_Tests_FooObject_get_value (ret_proxy, &val, &error))
|
||||
|
|
@ -982,7 +1034,7 @@ main (int argc, char **argv)
|
|||
lose ("Didn't get proxy_destroyed");
|
||||
g_print ("Proxy destroyed successfully\n");
|
||||
|
||||
g_object_unref (G_OBJECT (proxy));
|
||||
/* Don't need to unref, proxy was destroyed */
|
||||
|
||||
run_mainloop ();
|
||||
|
||||
|
|
@ -1122,12 +1174,10 @@ main (int argc, char **argv)
|
|||
lose_gerror ("Failed to create proxy for name owner", error);
|
||||
|
||||
g_print ("Testing introspect\n");
|
||||
call = dbus_g_proxy_begin_call (proxy, "Introspect",
|
||||
G_TYPE_INVALID);
|
||||
error = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (proxy, "Introspect", &error,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &v_STRING_2,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to complete Introspect call", error);
|
||||
|
||||
/* Could just do strcmp(), but that seems more fragile */
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ filter_func (DBusConnection *connection,
|
|||
DBusMessage *message,
|
||||
void *user_data)
|
||||
{
|
||||
print_message (message);
|
||||
print_message (message, FALSE);
|
||||
|
||||
if (dbus_message_is_signal (message,
|
||||
DBUS_INTERFACE_LOCAL,
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct NamesModel
|
|||
GtkListStore parent;
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *driver_proxy;
|
||||
DBusGPendingCall *pending_list_names;
|
||||
DBusGProxyCall *pending_list_names;
|
||||
};
|
||||
|
||||
struct NamesModelClass
|
||||
|
|
@ -59,7 +59,8 @@ struct NamesModelClass
|
|||
#define NAMES_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_NAMES_MODEL, NamesModelClass))
|
||||
|
||||
static void
|
||||
have_names_notify (DBusGPendingCall *call,
|
||||
have_names_notify (DBusGProxy *proxy,
|
||||
DBusGProxyCall *call,
|
||||
void *data)
|
||||
{
|
||||
NamesModel *names_model;
|
||||
|
|
@ -69,7 +70,7 @@ have_names_notify (DBusGPendingCall *call,
|
|||
|
||||
names_model = NAMES_MODEL (data);
|
||||
|
||||
g_assert (names_model->pending_list_names);
|
||||
g_assert (names_model->pending_list_names == call);
|
||||
g_assert (names_model->driver_proxy);
|
||||
|
||||
names = NULL;
|
||||
|
|
@ -195,8 +196,8 @@ names_model_reload (NamesModel *names_model)
|
|||
|
||||
if (names_model->pending_list_names)
|
||||
{
|
||||
dbus_g_pending_call_cancel (names_model->pending_list_names);
|
||||
dbus_g_pending_call_unref (names_model->pending_list_names);
|
||||
dbus_g_proxy_cancel_call (names_model->driver_proxy,
|
||||
names_model->pending_list_names);
|
||||
names_model->pending_list_names = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -208,10 +209,8 @@ names_model_reload (NamesModel *names_model)
|
|||
names_model->pending_list_names =
|
||||
dbus_g_proxy_begin_call (names_model->driver_proxy,
|
||||
"ListNames",
|
||||
have_names_notify, names_model, NULL,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
dbus_g_pending_call_set_notify (names_model->pending_list_names,
|
||||
have_names_notify, names_model, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ type_to_name (int message_type)
|
|||
}
|
||||
|
||||
static void
|
||||
print_iter (DBusMessageIter *iter, int depth)
|
||||
print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
|
@ -62,7 +62,11 @@ print_iter (DBusMessageIter *iter, int depth)
|
|||
{
|
||||
case DBUS_TYPE_STRING:
|
||||
dbus_message_iter_get_basic (iter, &str);
|
||||
printf ("string \"%s\"\n", str);
|
||||
if (!literal)
|
||||
printf ("string \"");
|
||||
printf ("%s", str);
|
||||
if (!literal)
|
||||
printf ("\"\n");
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_INT32:
|
||||
|
|
@ -97,7 +101,7 @@ print_iter (DBusMessageIter *iter, int depth)
|
|||
dbus_message_iter_recurse (iter, &subiter);
|
||||
|
||||
printf ("variant:");
|
||||
print_iter (&subiter, depth);
|
||||
print_iter (&subiter, literal, depth);
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_ARRAY:
|
||||
|
|
@ -110,7 +114,7 @@ print_iter (DBusMessageIter *iter, int depth)
|
|||
printf("[");
|
||||
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
|
||||
{
|
||||
print_iter (&subiter, depth);
|
||||
print_iter (&subiter, literal, depth);
|
||||
dbus_message_iter_next (&subiter);
|
||||
if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID)
|
||||
printf (",");
|
||||
|
|
@ -125,9 +129,9 @@ print_iter (DBusMessageIter *iter, int depth)
|
|||
dbus_message_iter_recurse (iter, &subiter);
|
||||
|
||||
printf("{");
|
||||
print_iter (&subiter, depth);
|
||||
print_iter (&subiter, literal, depth);
|
||||
dbus_message_iter_next (&subiter);
|
||||
print_iter (&subiter, depth);
|
||||
print_iter (&subiter, literal, depth);
|
||||
printf("}");
|
||||
break;
|
||||
}
|
||||
|
|
@ -141,7 +145,7 @@ print_iter (DBusMessageIter *iter, int depth)
|
|||
}
|
||||
|
||||
void
|
||||
print_message (DBusMessage *message)
|
||||
print_message (DBusMessage *message, dbus_bool_t literal)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
const char *sender;
|
||||
|
|
@ -151,37 +155,40 @@ print_message (DBusMessage *message)
|
|||
message_type = dbus_message_get_type (message);
|
||||
sender = dbus_message_get_sender (message);
|
||||
destination = dbus_message_get_destination (message);
|
||||
|
||||
printf ("%s sender=%s -> dest=%s",
|
||||
type_to_name (message_type),
|
||||
sender ? sender : "(null sender)",
|
||||
destination ? destination : "(null destination)");
|
||||
|
||||
switch (message_type)
|
||||
|
||||
if (!literal)
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
printf (" interface=%s; member=%s\n",
|
||||
dbus_message_get_interface (message),
|
||||
dbus_message_get_member (message));
|
||||
break;
|
||||
printf ("%s sender=%s -> dest=%s",
|
||||
type_to_name (message_type),
|
||||
sender ? sender : "(null sender)",
|
||||
destination ? destination : "(null destination)");
|
||||
|
||||
switch (message_type)
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
printf (" interface=%s; member=%s\n",
|
||||
dbus_message_get_interface (message),
|
||||
dbus_message_get_member (message));
|
||||
break;
|
||||
|
||||
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
||||
printf ("\n");
|
||||
break;
|
||||
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case DBUS_MESSAGE_TYPE_ERROR:
|
||||
printf (" error_name=%s\n",
|
||||
dbus_message_get_error_name (message));
|
||||
break;
|
||||
case DBUS_MESSAGE_TYPE_ERROR:
|
||||
printf (" error_name=%s\n",
|
||||
dbus_message_get_error_name (message));
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("\n");
|
||||
break;
|
||||
default:
|
||||
printf ("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dbus_message_iter_init (message, &iter);
|
||||
print_iter (&iter, 1);
|
||||
print_iter (&iter, literal, 1);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,6 @@
|
|||
#include <string.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
void print_message (DBusMessage *message);
|
||||
void print_message (DBusMessage *message, dbus_bool_t literal);
|
||||
|
||||
#endif /* DBUS_PRINT_MESSAGE_H */
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ static const char *appname;
|
|||
static void
|
||||
usage (int ecode)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
|
||||
fprintf (stderr, "Usage: %s [--help] [--system | --session] [--dest=NAME] [--type=TYPE] [--print-reply=(literal)] [--reply-timeout=MSEC] <destination object path> <message name> [contents ...]\n", appname);
|
||||
exit (ecode);
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +183,7 @@ main (int argc, char *argv[])
|
|||
DBusError error;
|
||||
DBusMessage *message;
|
||||
int print_reply;
|
||||
int print_reply_literal;
|
||||
int reply_timeout;
|
||||
DBusMessageIter iter;
|
||||
int i;
|
||||
|
|
@ -199,6 +200,7 @@ main (int argc, char *argv[])
|
|||
usage (1);
|
||||
|
||||
print_reply = FALSE;
|
||||
print_reply_literal = FALSE;
|
||||
reply_timeout = -1;
|
||||
|
||||
for (i = 1; i < argc && name == NULL; i++)
|
||||
|
|
@ -209,10 +211,12 @@ main (int argc, char *argv[])
|
|||
type = DBUS_BUS_SYSTEM;
|
||||
else if (strcmp (arg, "--session") == 0)
|
||||
type = DBUS_BUS_SESSION;
|
||||
else if (strcmp (arg, "--print-reply") == 0)
|
||||
else if (strncmp (arg, "--print-reply", 13) == 0)
|
||||
{
|
||||
print_reply = TRUE;
|
||||
message_type = DBUS_MESSAGE_TYPE_METHOD_CALL;
|
||||
if (*(arg + 13) != '\0')
|
||||
print_reply_literal = TRUE;
|
||||
}
|
||||
else if (strstr (arg, "--reply-timeout=") == arg)
|
||||
{
|
||||
|
|
@ -436,7 +440,7 @@ main (int argc, char *argv[])
|
|||
|
||||
if (reply)
|
||||
{
|
||||
print_message (reply);
|
||||
print_message (reply, print_reply_literal);
|
||||
dbus_message_unref (reply);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,14 +147,12 @@ load_child_nodes (const char *service_name,
|
|||
while (tmp != NULL)
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
DBusGPendingCall *call;
|
||||
char *data;
|
||||
NodeInfo *child;
|
||||
NodeInfo *complete_child;
|
||||
int save_len;
|
||||
|
||||
complete_child = NULL;
|
||||
call = NULL;
|
||||
|
||||
child = tmp->data;
|
||||
|
||||
|
|
@ -183,17 +181,11 @@ load_child_nodes (const char *service_name,
|
|||
goto done;
|
||||
}
|
||||
|
||||
call = dbus_g_proxy_begin_call (proxy, "Introspect",
|
||||
G_TYPE_INVALID);
|
||||
|
||||
data = NULL;
|
||||
if (!dbus_g_proxy_end_call (proxy, call, error, G_TYPE_STRING, &data,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
call = NULL;
|
||||
if (!dbus_g_proxy_call (proxy, "Introspect", error,
|
||||
G_TYPE_STRING, &data,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_INVALID))
|
||||
goto done;
|
||||
}
|
||||
call = NULL;
|
||||
|
||||
complete_child = description_load_from_string (data, -1, error);
|
||||
g_free (data);
|
||||
|
|
@ -204,8 +196,6 @@ load_child_nodes (const char *service_name,
|
|||
}
|
||||
|
||||
done:
|
||||
if (call)
|
||||
dbus_g_pending_call_unref (call);
|
||||
g_object_unref (proxy);
|
||||
|
||||
if (complete_child == NULL)
|
||||
|
|
@ -271,7 +261,6 @@ static void*
|
|||
load_from_service_thread_func (void *thread_data)
|
||||
{
|
||||
DBusGProxy *root_proxy;
|
||||
DBusGPendingCall *call;
|
||||
const char *data;
|
||||
NodeInfo *node;
|
||||
GString *path;
|
||||
|
|
@ -280,7 +269,6 @@ load_from_service_thread_func (void *thread_data)
|
|||
lfsd = thread_data;
|
||||
|
||||
node = NULL;
|
||||
call = NULL;
|
||||
path = NULL;
|
||||
|
||||
#if 1
|
||||
|
|
@ -304,19 +292,15 @@ load_from_service_thread_func (void *thread_data)
|
|||
}
|
||||
#endif
|
||||
|
||||
call = dbus_g_proxy_begin_call (root_proxy, "Introspect",
|
||||
G_TYPE_INVALID);
|
||||
|
||||
data = NULL;
|
||||
if (!dbus_g_proxy_end_call (root_proxy, call, &lfsd->error, G_TYPE_STRING, &data,
|
||||
G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (root_proxy, "Introspect", &lfsd->error,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &data,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
call = NULL;
|
||||
g_printerr ("Failed to Introspect() %s\n",
|
||||
dbus_g_proxy_get_bus_name (root_proxy));
|
||||
dbus_g_proxy_get_bus_name (root_proxy));
|
||||
goto out;
|
||||
}
|
||||
call = NULL;
|
||||
|
||||
node = description_load_from_string (data, -1, &lfsd->error);
|
||||
|
||||
|
|
@ -338,9 +322,6 @@ load_from_service_thread_func (void *thread_data)
|
|||
}
|
||||
|
||||
out:
|
||||
if (call)
|
||||
dbus_g_pending_call_unref (call);
|
||||
|
||||
g_object_unref (root_proxy);
|
||||
|
||||
if (path)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ main (int argc, char *argv[])
|
|||
{
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *proxy;
|
||||
DBusGPendingCall *call;
|
||||
GError *error;
|
||||
const char *service;
|
||||
const char *path;
|
||||
|
|
@ -64,9 +63,10 @@ main (int argc, char *argv[])
|
|||
proxy = dbus_g_proxy_new_for_name (connection,
|
||||
service, path,
|
||||
DBUS_INTERFACE_INTROSPECTABLE);
|
||||
call = dbus_g_proxy_begin_call (proxy, "Introspect", G_TYPE_INVALID);
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING,
|
||||
&introspect_data, G_TYPE_INVALID))
|
||||
if (!dbus_g_proxy_call (proxy, "Introspect", &error,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_STRING, &introspect_data,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
fprintf (stderr, "Failed to get introspection data: %s\n",
|
||||
error->message);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue