1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-gcall.c convenience routines for calling methods, etc.
4 * Copyright (C) 2003 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "dbus-glib.h"
27 * @addtogroup DBusGLibInternals
32 typedef struct DBusGProxyManager DBusGProxyManager;
35 * Internals of DBusGProxy
39 GObject parent; /**< Parent instance */
41 DBusGProxyManager *manager; /**< Proxy manager */
42 char *service; /**< Service messages go to or NULL */
43 char *path; /**< Path messages go to or NULL */
44 char *interface; /**< Interface messages go to or NULL */
48 * Class struct for DBusGProxy
50 struct DBusGProxyClass
52 GObjectClass parent_class;
55 static void dbus_gproxy_init (DBusGProxy *proxy);
56 static void dbus_gproxy_class_init (DBusGProxyClass *klass);
57 static void dbus_gproxy_finalize (GObject *object);
58 static void dbus_gproxy_dispose (GObject *object);
59 static void dbus_gproxy_destroy (DBusGProxy *proxy);
60 static void dbus_gproxy_emit_received (DBusGProxy *proxy,
61 DBusMessage *message);
65 * A list of proxies with a given service+path+interface, used to route incoming
72 char name[4]; /**< service (empty string for none), nul byte,
80 * DBusGProxyManager's primary task is to route signals to the proxies
81 * those signals are emitted on. In order to do this it also has to
82 * track the owners of the services proxies are bound to.
84 struct DBusGProxyManager
86 GStaticMutex lock; /**< Thread lock */
87 int refcount; /**< Reference count */
88 DBusConnection *connection; /**< Connection we're associated with. */
90 GHashTable *proxy_lists; /**< Hash used to route incoming signals
91 * and iterate over proxies
96 static void dbus_gproxy_manager_ref (DBusGProxyManager *manager);
97 static DBusHandlerResult dbus_gproxy_manager_filter (DBusConnection *connection,
101 /** Lock the DBusGProxyManager */
102 #define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock))
103 /** Unlock the DBusGProxyManager */
104 #define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock))
106 static int gproxy_manager_slot = -1;
108 /* Lock controlling get/set manager as data on each connection */
109 static GStaticMutex connection_gproxy_lock = G_STATIC_MUTEX_INIT;
111 static DBusGProxyManager*
112 dbus_gproxy_manager_get (DBusConnection *connection)
114 DBusGProxyManager *manager;
116 dbus_connection_allocate_data_slot (&gproxy_manager_slot);
117 if (gproxy_manager_slot < 0)
118 g_error ("out of memory");
120 g_static_mutex_lock (&connection_gproxy_lock);
122 manager = dbus_connection_get_data (connection, gproxy_manager_slot);
125 dbus_connection_free_data_slot (&gproxy_manager_slot);
126 dbus_gproxy_manager_ref (manager);
127 g_static_mutex_unlock (&connection_gproxy_lock);
131 manager = g_new0 (DBusGProxyManager, 1);
133 manager->refcount = 1;
134 manager->connection = connection;
136 g_static_mutex_init (&manager->lock);
138 /* Proxy managers keep the connection alive, which means that
139 * DBusGProxy indirectly does. To free a connection you have to free
140 * all the proxies referring to it.
142 dbus_connection_ref (manager->connection);
144 dbus_connection_set_data (connection, gproxy_manager_slot,
147 dbus_connection_add_filter (connection, dbus_gproxy_manager_filter,
150 g_static_mutex_unlock (&connection_gproxy_lock);
156 dbus_gproxy_manager_ref (DBusGProxyManager *manager)
158 g_assert (manager != NULL);
159 g_assert (manager->refcount > 0);
161 LOCK_MANAGER (manager);
163 manager->refcount += 1;
165 UNLOCK_MANAGER (manager);
169 dbus_gproxy_manager_unref (DBusGProxyManager *manager)
171 g_assert (manager != NULL);
172 g_assert (manager->refcount > 0);
174 LOCK_MANAGER (manager);
175 manager->refcount -= 1;
176 if (manager->refcount == 0)
178 UNLOCK_MANAGER (manager);
180 if (manager->proxy_lists)
182 /* can't have any proxies left since they hold
183 * a reference to the proxy manager.
185 g_assert (g_hash_table_size (manager->proxy_lists) == 0);
187 g_hash_table_destroy (manager->proxy_lists);
188 manager->proxy_lists = NULL;
191 g_static_mutex_free (&manager->lock);
193 g_static_mutex_lock (&connection_gproxy_lock);
195 dbus_connection_remove_filter (manager->connection, dbus_gproxy_manager_filter,
198 dbus_connection_set_data (manager->connection,
202 g_static_mutex_unlock (&connection_gproxy_lock);
204 dbus_connection_unref (manager->connection);
207 dbus_connection_free_data_slot (&gproxy_manager_slot);
211 UNLOCK_MANAGER (manager);
216 tristring_hash (gconstpointer key)
223 for (p += 1; *p != '\0'; p++)
224 h = (h << 5) - h + *p;
227 /* skip nul and do the next substring */
228 for (p += 1; *p != '\0'; p++)
229 h = (h << 5) - h + *p;
231 /* skip nul again and another substring */
232 for (p += 1; *p != '\0'; p++)
233 h = (h << 5) - h + *p;
239 strequal_len (const char *a,
252 if (memcmp (a, b, a_len) != 0)
261 tristring_equal (gconstpointer a,
268 if (!strequal_len (ap, bp, &len))
274 if (!strequal_len (ap, bp, &len))
280 if (strcmp (ap, bp) != 0)
287 tristring_alloc_from_strings (size_t padding_before,
290 const char *interface)
292 size_t service_len, iface_len, path_len, len;
296 service_len = strlen (service);
300 path_len = strlen (path);
302 iface_len = strlen (interface);
304 tri = g_malloc (padding_before + service_len + path_len + iface_len + 3);
306 len = padding_before;
309 memcpy (&tri[len], service, service_len);
315 g_assert (len == (padding_before + service_len + 1));
317 memcpy (&tri[len], path, path_len);
322 g_assert (len == (padding_before + service_len + path_len + 2));
324 memcpy (&tri[len], interface, iface_len);
329 g_assert (len == (padding_before + service_len + path_len + iface_len + 3));
335 tristring_from_proxy (DBusGProxy *proxy)
337 return tristring_alloc_from_strings (0,
344 tristring_from_message (DBusMessage *message)
346 return tristring_alloc_from_strings (0,
347 dbus_message_get_sender (message),
348 dbus_message_get_path (message),
349 dbus_message_get_interface (message));
352 static DBusGProxyList*
353 gproxy_list_new (DBusGProxy *first_proxy)
355 DBusGProxyList *list;
357 list = (void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (DBusGProxyList, name),
358 first_proxy->service,
360 first_proxy->interface);
361 list->proxies = NULL;
367 gproxy_list_free (DBusGProxyList *list)
369 /* we don't hold a reference to the proxies in the list,
370 * as they ref the GProxyManager
372 g_slist_free (list->proxies);
378 gproxy_get_match_rule (DBusGProxy *proxy)
380 /* FIXME Escaping is required here */
383 return g_strdup_printf ("type='signal',sender='%s',path='%s',interface='%s'",
384 proxy->service, proxy->path, proxy->interface);
386 return g_strdup_printf ("type='signal',path='%s',interface='%s'",
387 proxy->path, proxy->interface);
391 dbus_gproxy_manager_register (DBusGProxyManager *manager,
394 DBusGProxyList *list;
396 LOCK_MANAGER (manager);
398 if (manager->proxy_lists == NULL)
401 manager->proxy_lists = g_hash_table_new_full (tristring_hash,
404 (GFreeFunc) gproxy_list_free);
410 tri = tristring_from_proxy (proxy);
412 list = g_hash_table_lookup (manager->proxy_lists, tri);
419 list = gproxy_list_new (proxy);
421 g_hash_table_replace (manager->proxy_lists,
425 if (list->proxies == NULL)
427 /* We have to add the match rule to the server,
428 * but FIXME only if the server is a message bus,
429 * not if it's a peer.
433 rule = gproxy_get_match_rule (proxy);
435 /* We don't check for errors; it's not like anyone would handle them,
436 * and we don't want a round trip here.
438 dbus_bus_add_match (manager->connection,
444 g_assert (g_slist_find (list->proxies, proxy) == NULL);
446 list->proxies = g_slist_prepend (list->proxies, proxy);
448 UNLOCK_MANAGER (manager);
452 dbus_gproxy_manager_unregister (DBusGProxyManager *manager,
455 DBusGProxyList *list;
458 LOCK_MANAGER (manager);
460 #ifndef G_DISABLE_CHECKS
461 if (manager->proxy_lists == NULL)
463 g_warning ("Trying to unregister a proxy but there aren't any registered");
468 tri = tristring_from_proxy (proxy);
470 list = g_hash_table_lookup (manager->proxy_lists, tri);
472 #ifndef G_DISABLE_CHECKS
475 g_warning ("Trying to unregister a proxy but it isn't registered");
480 g_assert (g_slist_find (list->proxies, proxy) != NULL);
482 list->proxies = g_slist_remove (list->proxies, proxy);
484 g_assert (g_slist_find (list->proxies, proxy) == NULL);
486 if (list->proxies == NULL)
488 g_hash_table_remove (manager->proxy_lists,
493 if (g_hash_table_size (manager->proxy_lists) == 0)
495 g_hash_table_destroy (manager->proxy_lists);
496 manager->proxy_lists = NULL;
501 UNLOCK_MANAGER (manager);
505 list_proxies_foreach (gpointer key,
509 DBusGProxyList *list;
519 DBusGProxy *proxy = DBUS_GPROXY (tmp->data);
521 g_object_ref (proxy);
522 *ret = g_slist_prepend (*ret, proxy);
529 dbus_gproxy_manager_list_all (DBusGProxyManager *manager)
535 if (manager->proxy_lists)
537 g_hash_table_foreach (manager->proxy_lists,
538 list_proxies_foreach,
545 static DBusHandlerResult
546 dbus_gproxy_manager_filter (DBusConnection *connection,
547 DBusMessage *message,
550 DBusGProxyManager *manager;
552 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
553 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
557 dbus_gproxy_manager_ref (manager);
559 LOCK_MANAGER (manager);
561 if (dbus_message_is_signal (message,
562 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
565 /* Destroy all the proxies, quite possibly resulting in unreferencing
566 * the proxy manager and the connection as well.
571 all = dbus_gproxy_manager_list_all (manager);
578 proxy = DBUS_GPROXY (tmp->data);
580 UNLOCK_MANAGER (manager);
581 dbus_gproxy_destroy (proxy);
582 g_object_unref (G_OBJECT (proxy));
583 LOCK_MANAGER (manager);
590 #ifndef G_DISABLE_CHECKS
591 if (manager->proxy_lists != NULL)
592 g_warning ("Disconnection emitted \"destroy\" on all DBusGProxy, but somehow new proxies were created in response to one of those destroy signals. This will cause a memory leak.");
598 DBusGProxyList *list;
600 tri = tristring_from_message (message);
602 if (manager->proxy_lists)
603 list = g_hash_table_lookup (manager->proxy_lists, tri);
608 g_print ("proxy got %s,%s,%s = list %p\n",
610 tri + strlen (tri) + 1,
611 tri + strlen (tri) + 1 + strlen (tri + strlen (tri) + 1) + 1,
617 /* Emit the signal */
624 copy = g_slist_copy (list->proxies);
625 g_slist_foreach (copy, (GFunc) g_object_ref, NULL);
632 proxy = DBUS_GPROXY (tmp->data);
634 UNLOCK_MANAGER (manager);
635 dbus_gproxy_emit_received (proxy, message);
636 g_object_unref (G_OBJECT (proxy));
637 LOCK_MANAGER (manager);
646 UNLOCK_MANAGER (manager);
647 dbus_gproxy_manager_unref (manager);
649 /* "Handling" signals doesn't make sense, they are for everyone
652 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
657 /* ---------- DBusGProxy -------------- */
668 static void *parent_class;
669 static guint signals[LAST_SIGNAL] = { 0 };
672 dbus_gproxy_init (DBusGProxy *proxy)
678 dbus_gproxy_class_init (DBusGProxyClass *klass)
680 GObjectClass *object_class = G_OBJECT_CLASS (klass);
682 parent_class = g_type_class_peek_parent (klass);
684 object_class->finalize = dbus_gproxy_finalize;
685 object_class->dispose = dbus_gproxy_dispose;
688 g_signal_new ("destroy",
689 G_OBJECT_CLASS_TYPE (object_class),
690 G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
693 g_cclosure_marshal_VOID__VOID,
697 g_signal_new ("received",
698 G_OBJECT_CLASS_TYPE (object_class),
699 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
702 g_cclosure_marshal_VOID__BOXED,
709 dbus_gproxy_dispose (GObject *object)
713 proxy = DBUS_GPROXY (object);
715 g_signal_emit (object, signals[DESTROY], 0);
717 G_OBJECT_CLASS (parent_class)->dispose (object);
721 dbus_gproxy_finalize (GObject *object)
725 proxy = DBUS_GPROXY (object);
729 dbus_gproxy_manager_unregister (proxy->manager, proxy);
730 dbus_gproxy_manager_unref (proxy->manager);
733 g_free (proxy->service);
734 g_free (proxy->path);
735 g_free (proxy->interface);
737 G_OBJECT_CLASS (parent_class)->finalize (object);
741 dbus_gproxy_destroy (DBusGProxy *proxy)
743 /* FIXME do we need the GTK_IN_DESTRUCTION style flag
746 g_object_run_dispose (G_OBJECT (proxy));
750 create_signal_detail (const char *interface,
755 str = g_string_new (interface);
757 g_string_append (str, ".");
759 g_string_append (str, signal);
761 return g_string_free (str, FALSE);
765 dbus_gproxy_emit_received (DBusGProxy *proxy,
766 DBusMessage *message)
768 const char *interface;
773 interface = dbus_message_get_interface (message);
774 signal = dbus_message_get_member (message);
776 g_assert (interface != NULL);
777 g_assert (signal != NULL);
779 detail = create_signal_detail (interface, signal);
781 /* If the quark isn't preexisting, there's no way there
782 * are any handlers connected. We don't want to create
783 * extra quarks for every possible signal.
785 q = g_quark_try_string (detail);
788 g_signal_emit (G_OBJECT (proxy),
796 /** @} End of DBusGLibInternals */
798 /** @addtogroup DBusGLib
803 * Standard GObject get_type() function for DBusGProxy.
805 * @returns type ID for DBusGProxy class
808 dbus_gproxy_get_type (void)
810 static GType object_type = 0;
814 static const GTypeInfo object_info =
816 sizeof (DBusGProxyClass),
817 (GBaseInitFunc) NULL,
818 (GBaseFinalizeFunc) NULL,
819 (GClassInitFunc) dbus_gproxy_class_init,
820 NULL, /* class_finalize */
821 NULL, /* class_data */
824 (GInstanceInitFunc) dbus_gproxy_init,
827 object_type = g_type_register_static (G_TYPE_OBJECT,
836 dbus_gproxy_new (DBusConnection *connection,
837 const char *service_name,
838 const char *path_name,
839 const char *interface_name)
843 g_assert (connection != NULL);
845 proxy = g_object_new (DBUS_TYPE_GPROXY, NULL);
847 /* These should all be construct-only mandatory properties,
848 * for now we just don't let people use g_object_new().
851 proxy->manager = dbus_gproxy_manager_get (connection);
853 proxy->service = g_strdup (service_name);
854 proxy->path = g_strdup (path_name);
855 proxy->interface = g_strdup (interface_name);
857 dbus_gproxy_manager_register (proxy->manager, proxy);
863 * Creates a new proxy for a remote interface exported by a service on
864 * a message bus. Method calls and signal connections over this proxy
865 * will go to the service owner; the service owner is expected to
866 * support the given interface name. THE SERVICE OWNER MAY CHANGE OVER
867 * TIME, for example between two different method calls. If you need a
868 * fixed owner, you need to request the current owner and bind a proxy
869 * to that rather than to the generic service name; see
870 * dbus_gproxy_new_for_service_owner().
872 * A service-associated proxy only makes sense with a message bus,
873 * not for app-to-app direct dbus connections.
875 * This proxy will only emit the "destroy" signal if the #DBusConnection
876 * is disconnected or the proxy is has no remaining references.
878 * @param connection the connection to the remote bus
879 * @param service_name name of the service on the message bus
880 * @param path_name name of the object inside the service to call methods on
881 * @param interface_name name of the interface to call methods on
882 * @returns new proxy object
885 dbus_gproxy_new_for_service (DBusConnection *connection,
886 const char *service_name,
887 const char *path_name,
888 const char *interface_name)
892 g_return_val_if_fail (connection != NULL, NULL);
893 g_return_val_if_fail (service_name != NULL, NULL);
894 g_return_val_if_fail (path_name != NULL, NULL);
895 g_return_val_if_fail (interface_name != NULL, NULL);
897 proxy = dbus_gproxy_new (connection, service_name,
898 path_name, interface_name);
904 * Similar to dbus_gproxy_new_for_service(), but makes a round-trip
905 * request to the message bus to get the current service owner, then
906 * binds the proxy specifically to the current owner. As a result, the
907 * service owner will not change over time, and the proxy will emit
908 * the "destroy" signal when the owner disappears from the message
911 * An example of the difference between dbus_gproxy_new_for_service()
912 * and dbus_gproxy_new_for_service_owner(): if you pass the service name
913 * "org.freedesktop.Database" dbus_gproxy_new_for_service() remains bound
914 * to that name as it changes owner. dbus_gproxy_new_for_service_owner()
915 * will fail if the service has no owner. If the service has an owner,
916 * dbus_gproxy_new_for_service_owner() will bind to the unique name
917 * of that owner rather than the generic service name.
919 * @param connection the connection to the remote bus
920 * @param service_name name of the service on the message bus
921 * @param path_name name of the object inside the service to call methods on
922 * @param interface_name name of the interface to call methods on
923 * @param error return location for an error
924 * @returns new proxy object, or #NULL on error
927 dbus_gproxy_new_for_service_owner (DBusConnection *connection,
928 const char *service_name,
929 const char *path_name,
930 const char *interface_name,
933 g_return_val_if_fail (connection != NULL, NULL);
934 g_return_val_if_fail (service_name != NULL, NULL);
935 g_return_val_if_fail (path_name != NULL, NULL);
936 g_return_val_if_fail (interface_name != NULL, NULL);
942 * Creates a proxy for an object in peer application (one
943 * we're directly connected to). That is, this function is
944 * intended for use when there's no message bus involved,
945 * we're doing a simple 1-to-1 communication between two
949 * @param connection the connection to the peer
950 * @param path_name name of the object inside the peer to call methods on
951 * @param interface_name name of the interface to call methods on
952 * @returns new proxy object
956 dbus_gproxy_new_for_peer (DBusConnection *connection,
957 const char *path_name,
958 const char *interface_name)
962 g_return_val_if_fail (connection != NULL, NULL);
963 g_return_val_if_fail (path_name != NULL, NULL);
964 g_return_val_if_fail (interface_name != NULL, NULL);
966 proxy = dbus_gproxy_new (connection, NULL,
967 path_name, interface_name);
973 * Invokes a method on a remote interface. This function does not
974 * block; instead it returns an opaque #DBusPendingCall object that
975 * tracks the pending call. The method call will not be sent over the
976 * wire until the application returns to the main loop, or blocks in
977 * dbus_connection_flush() to write out pending data. The call will
978 * be completed after a timeout, or when a reply is received.
979 * To collect the results of the call (which may be an error,
980 * or a reply), use dbus_gproxy_end_call().
982 * @todo this particular function shouldn't die on out of memory,
983 * since you should be able to do a call with large arguments.
985 * @param proxy a proxy for a remote interface
986 * @param method the name of the method to invoke
987 * @param first_arg_type type of the first argument
989 * @returns opaque pending call object
992 dbus_gproxy_begin_call (DBusGProxy *proxy,
997 DBusPendingCall *pending;
998 DBusMessage *message;
1001 g_return_val_if_fail (DBUS_IS_GPROXY (proxy), NULL);
1003 message = dbus_message_new_method_call (proxy->service,
1007 if (message == NULL)
1010 va_start (args, first_arg_type);
1011 if (!dbus_message_append_args_valist (message, first_arg_type,
1016 if (!dbus_connection_send_with_reply (proxy->manager->connection,
1025 /* FIXME we should create a pending call that's
1026 * immediately completed with an error status without
1027 * ever going on the wire.
1030 g_error ("Out of memory");
1035 * Collects the results of a method call. The method call was normally
1036 * initiated with dbus_gproxy_end_call(). This function will block if
1037 * the results haven't yet been received; use
1038 * dbus_pending_call_set_notify() to be notified asynchronously that a
1039 * pending call has been completed. Use
1040 * dbus_pending_call_get_completed() to check whether a call has been
1041 * completed. If it's completed, it will not block.
1043 * If the call results in an error, the error is set as normal for
1044 * GError and the function returns #FALSE.
1046 * Otherwise, the "out" parameters and return value of the
1047 * method are stored in the provided varargs list.
1048 * The list should be terminated with DBUS_TYPE_INVALID.
1050 * This function doesn't affect the reference count of the
1051 * #DBusPendingCall, the caller of dbus_gproxy_begin_call() still owns
1054 * @param proxy a proxy for a remote interface
1055 * @param pending the pending call from dbus_gproxy_begin_call()
1056 * @param error return location for an error
1057 * @param first_arg_type type of first "out" argument
1058 * @returns #FALSE if an error is set */
1060 dbus_gproxy_end_call (DBusGProxy *proxy,
1061 DBusPendingCall *pending,
1066 DBusMessage *message;
1070 g_return_val_if_fail (DBUS_IS_GPROXY (proxy), FALSE);
1071 g_return_val_if_fail (pending != NULL, FALSE);
1073 dbus_pending_call_block (pending);
1074 message = dbus_pending_call_get_reply (pending);
1076 g_assert (message != NULL);
1078 dbus_error_init (&derror);
1080 switch (dbus_message_get_type (message))
1082 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
1083 va_start (args, first_arg_type);
1084 if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args))
1093 case DBUS_MESSAGE_TYPE_ERROR:
1094 dbus_set_error_from_message (&derror, message);
1098 dbus_set_error (&derror, DBUS_ERROR_FAILED,
1099 "Reply was neither a method return nor an exception");
1104 dbus_set_g_error (error, &derror);
1105 dbus_error_free (&derror);
1110 * Sends a method call message as with dbus_gproxy_begin_call(), but
1111 * does not ask for a reply or allow you to receive one.
1113 * @todo this particular function shouldn't die on out of memory,
1114 * since you should be able to do a call with large arguments.
1116 * @param proxy a proxy for a remote interface
1117 * @param method the name of the method to invoke
1118 * @param first_arg_type type of the first argument
1121 dbus_gproxy_call_no_reply (DBusGProxy *proxy,
1126 DBusMessage *message;
1129 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1131 message = dbus_message_new_method_call (proxy->service,
1135 if (message == NULL)
1138 dbus_message_set_no_reply (message, TRUE);
1140 va_start (args, first_arg_type);
1141 if (!dbus_message_append_args_valist (message, first_arg_type,
1146 if (!dbus_connection_send (proxy->manager->connection,
1154 g_error ("Out of memory");
1158 * Sends a message to the interface we're proxying for. Does not
1159 * block or wait for a reply. The message is only actually written out
1160 * when you return to the main loop or block in
1161 * dbus_connection_flush().
1163 * The message is modified to be addressed to the target interface.
1164 * That is, a destination service field or whatever is needed will be
1165 * added to the message. The basic point of this function is to add
1166 * the necessary header fields, otherwise it's equivalent to
1167 * dbus_connection_send().
1169 * This function adds a reference to the message, so the caller
1170 * still owns its original reference.
1172 * @param proxy a proxy for a remote interface
1173 * @param message the message to address and send
1174 * @param client_serial return location for message's serial, or #NULL */
1176 dbus_gproxy_send (DBusGProxy *proxy,
1177 DBusMessage *message,
1178 dbus_uint32_t *client_serial)
1180 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1184 if (!dbus_message_set_destination (message, proxy->service))
1185 g_error ("Out of memory");
1189 if (!dbus_message_set_path (message, proxy->path))
1190 g_error ("Out of memory");
1192 if (proxy->interface)
1194 if (!dbus_message_set_interface (message, proxy->interface))
1195 g_error ("Out of memory");
1198 if (!dbus_connection_send (proxy->manager->connection, message, client_serial))
1199 g_error ("Out of memory\n");
1203 dbus_gproxy_connect_signal (DBusGProxy *proxy,
1204 const char *signal_name,
1205 DBusGProxySignalHandler handler,
1207 GClosureNotify free_data_func)
1212 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1213 g_return_if_fail (signal_name != NULL);
1214 g_return_if_fail (handler != NULL);
1216 detail = create_signal_detail (proxy->interface, signal_name);
1218 closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func);
1219 g_signal_connect_closure_by_id (G_OBJECT (proxy),
1221 g_quark_from_string (detail),
1228 dbus_gproxy_disconnect_signal (DBusGProxy *proxy,
1229 const char *signal_name,
1230 DBusGProxySignalHandler handler,
1236 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1237 g_return_if_fail (signal_name != NULL);
1238 g_return_if_fail (handler != NULL);
1240 detail = create_signal_detail (proxy->interface, signal_name);
1241 q = g_quark_try_string (detail);
1244 #ifndef G_DISABLE_CHECKS
1247 g_warning ("%s: No signal handlers for %s found on this DBusGProxy",
1248 G_GNUC_FUNCTION, signal_name);
1253 g_signal_handlers_disconnect_matched (G_OBJECT (proxy),
1254 G_SIGNAL_MATCH_DETAIL |
1255 G_SIGNAL_MATCH_FUNC |
1256 G_SIGNAL_MATCH_DATA,
1260 G_CALLBACK (handler), data);
1263 /** @} End of DBusGLib public */
1265 #ifdef DBUS_BUILD_TESTS
1268 * @ingroup DBusGLibInternals
1269 * Unit test for GLib proxy functions
1270 * @returns #TRUE on success.
1273 _dbus_gproxy_test (void)
1280 #endif /* DBUS_BUILD_TESTS */