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 2.0
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 DBusGProxyManager *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);
155 static DBusGProxyManager *
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);
171 dbus_gproxy_manager_unref (DBusGProxyManager *manager)
173 g_assert (manager != NULL);
174 g_assert (manager->refcount > 0);
176 LOCK_MANAGER (manager);
177 manager->refcount -= 1;
178 if (manager->refcount == 0)
180 UNLOCK_MANAGER (manager);
182 if (manager->proxy_lists)
184 /* can't have any proxies left since they hold
185 * a reference to the proxy manager.
187 g_assert (g_hash_table_size (manager->proxy_lists) == 0);
189 g_hash_table_destroy (manager->proxy_lists);
190 manager->proxy_lists = NULL;
193 g_static_mutex_free (&manager->lock);
195 g_static_mutex_lock (&connection_gproxy_lock);
197 dbus_connection_remove_filter (manager->connection, dbus_gproxy_manager_filter,
200 dbus_connection_set_data (manager->connection,
204 g_static_mutex_unlock (&connection_gproxy_lock);
206 dbus_connection_unref (manager->connection);
209 dbus_connection_free_data_slot (&gproxy_manager_slot);
213 UNLOCK_MANAGER (manager);
218 tristring_hash (gconstpointer key)
225 for (p += 1; *p != '\0'; p++)
226 h = (h << 5) - h + *p;
229 /* skip nul and do the next substring */
230 for (p += 1; *p != '\0'; p++)
231 h = (h << 5) - h + *p;
233 /* skip nul again and another substring */
234 for (p += 1; *p != '\0'; p++)
235 h = (h << 5) - h + *p;
241 strequal_len (const char *a,
254 if (memcmp (a, b, a_len) != 0)
263 tristring_equal (gconstpointer a,
270 if (!strequal_len (ap, bp, &len))
276 if (!strequal_len (ap, bp, &len))
282 if (strcmp (ap, bp) != 0)
289 tristring_alloc_from_strings (size_t padding_before,
292 const char *interface)
294 size_t service_len, iface_len, path_len, len;
298 service_len = strlen (service);
302 path_len = strlen (path);
304 iface_len = strlen (interface);
306 tri = g_malloc (padding_before + service_len + path_len + iface_len + 3);
308 len = padding_before;
311 memcpy (&tri[len], service, service_len);
317 g_assert (len == (padding_before + service_len + 1));
319 memcpy (&tri[len], path, path_len);
324 g_assert (len == (padding_before + service_len + path_len + 2));
326 memcpy (&tri[len], interface, iface_len);
331 g_assert (len == (padding_before + service_len + path_len + iface_len + 3));
337 tristring_from_proxy (DBusGProxy *proxy)
339 return tristring_alloc_from_strings (0,
346 tristring_from_message (DBusMessage *message)
348 return tristring_alloc_from_strings (0,
349 dbus_message_get_sender (message),
350 dbus_message_get_path (message),
351 dbus_message_get_interface (message));
354 static DBusGProxyList*
355 gproxy_list_new (DBusGProxy *first_proxy)
357 DBusGProxyList *list;
359 list = (void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (DBusGProxyList, name),
360 first_proxy->service,
362 first_proxy->interface);
363 list->proxies = NULL;
369 gproxy_list_free (DBusGProxyList *list)
371 /* we don't hold a reference to the proxies in the list,
372 * as they ref the GProxyManager
374 g_slist_free (list->proxies);
380 gproxy_get_match_rule (DBusGProxy *proxy)
382 /* FIXME Escaping is required here */
385 return g_strdup_printf ("type='signal',sender='%s',path='%s',interface='%s'",
386 proxy->service, proxy->path, proxy->interface);
388 return g_strdup_printf ("type='signal',path='%s',interface='%s'",
389 proxy->path, proxy->interface);
393 dbus_gproxy_manager_register (DBusGProxyManager *manager,
396 DBusGProxyList *list;
398 LOCK_MANAGER (manager);
400 if (manager->proxy_lists == NULL)
403 manager->proxy_lists = g_hash_table_new_full (tristring_hash,
406 (GFreeFunc) gproxy_list_free);
412 tri = tristring_from_proxy (proxy);
414 list = g_hash_table_lookup (manager->proxy_lists, tri);
421 list = gproxy_list_new (proxy);
423 g_hash_table_replace (manager->proxy_lists,
427 if (list->proxies == NULL)
429 /* We have to add the match rule to the server,
430 * but FIXME only if the server is a message bus,
431 * not if it's a peer.
435 rule = gproxy_get_match_rule (proxy);
437 /* We don't check for errors; it's not like anyone would handle them,
438 * and we don't want a round trip here.
440 dbus_bus_add_match (manager->connection,
446 g_assert (g_slist_find (list->proxies, proxy) == NULL);
448 list->proxies = g_slist_prepend (list->proxies, proxy);
450 UNLOCK_MANAGER (manager);
454 dbus_gproxy_manager_unregister (DBusGProxyManager *manager,
457 DBusGProxyList *list;
460 LOCK_MANAGER (manager);
462 #ifndef G_DISABLE_CHECKS
463 if (manager->proxy_lists == NULL)
465 g_warning ("Trying to unregister a proxy but there aren't any registered");
470 tri = tristring_from_proxy (proxy);
472 list = g_hash_table_lookup (manager->proxy_lists, tri);
474 #ifndef G_DISABLE_CHECKS
477 g_warning ("Trying to unregister a proxy but it isn't registered");
482 g_assert (g_slist_find (list->proxies, proxy) != NULL);
484 list->proxies = g_slist_remove (list->proxies, proxy);
486 g_assert (g_slist_find (list->proxies, proxy) == NULL);
488 if (list->proxies == NULL)
490 g_hash_table_remove (manager->proxy_lists,
495 if (g_hash_table_size (manager->proxy_lists) == 0)
497 g_hash_table_destroy (manager->proxy_lists);
498 manager->proxy_lists = NULL;
503 UNLOCK_MANAGER (manager);
507 list_proxies_foreach (gpointer key,
511 DBusGProxyList *list;
521 DBusGProxy *proxy = DBUS_GPROXY (tmp->data);
523 g_object_ref (proxy);
524 *ret = g_slist_prepend (*ret, proxy);
531 dbus_gproxy_manager_list_all (DBusGProxyManager *manager)
537 if (manager->proxy_lists)
539 g_hash_table_foreach (manager->proxy_lists,
540 list_proxies_foreach,
547 static DBusHandlerResult
548 dbus_gproxy_manager_filter (DBusConnection *connection,
549 DBusMessage *message,
552 DBusGProxyManager *manager;
554 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
555 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
559 dbus_gproxy_manager_ref (manager);
561 LOCK_MANAGER (manager);
563 if (dbus_message_is_signal (message,
564 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
567 /* Destroy all the proxies, quite possibly resulting in unreferencing
568 * the proxy manager and the connection as well.
573 all = dbus_gproxy_manager_list_all (manager);
580 proxy = DBUS_GPROXY (tmp->data);
582 UNLOCK_MANAGER (manager);
583 dbus_gproxy_destroy (proxy);
584 g_object_unref (G_OBJECT (proxy));
585 LOCK_MANAGER (manager);
592 #ifndef G_DISABLE_CHECKS
593 if (manager->proxy_lists != NULL)
594 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.");
600 DBusGProxyList *list;
602 tri = tristring_from_message (message);
604 if (manager->proxy_lists)
605 list = g_hash_table_lookup (manager->proxy_lists, tri);
610 g_print ("proxy got %s,%s,%s = list %p\n",
612 tri + strlen (tri) + 1,
613 tri + strlen (tri) + 1 + strlen (tri + strlen (tri) + 1) + 1,
619 /* Emit the signal */
626 copy = g_slist_copy (list->proxies);
627 g_slist_foreach (copy, (GFunc) g_object_ref, NULL);
634 proxy = DBUS_GPROXY (tmp->data);
636 UNLOCK_MANAGER (manager);
637 dbus_gproxy_emit_received (proxy, message);
638 g_object_unref (G_OBJECT (proxy));
639 LOCK_MANAGER (manager);
648 UNLOCK_MANAGER (manager);
649 dbus_gproxy_manager_unref (manager);
651 /* "Handling" signals doesn't make sense, they are for everyone
654 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
659 /* ---------- DBusGProxy -------------- */
670 static void *parent_class;
671 static guint signals[LAST_SIGNAL] = { 0 };
674 dbus_gproxy_init (DBusGProxy *proxy)
680 dbus_gproxy_class_init (DBusGProxyClass *klass)
682 GObjectClass *object_class = G_OBJECT_CLASS (klass);
684 parent_class = g_type_class_peek_parent (klass);
686 object_class->finalize = dbus_gproxy_finalize;
687 object_class->dispose = dbus_gproxy_dispose;
690 g_signal_new ("destroy",
691 G_OBJECT_CLASS_TYPE (object_class),
692 G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
695 g_cclosure_marshal_VOID__VOID,
699 g_signal_new ("received",
700 G_OBJECT_CLASS_TYPE (object_class),
701 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
704 g_cclosure_marshal_VOID__BOXED,
711 dbus_gproxy_dispose (GObject *object)
715 proxy = DBUS_GPROXY (object);
717 g_signal_emit (object, signals[DESTROY], 0);
719 G_OBJECT_CLASS (parent_class)->dispose (object);
723 dbus_gproxy_finalize (GObject *object)
727 proxy = DBUS_GPROXY (object);
731 dbus_gproxy_manager_unregister (proxy->manager, proxy);
732 dbus_gproxy_manager_unref (proxy->manager);
735 g_free (proxy->service);
736 g_free (proxy->path);
737 g_free (proxy->interface);
739 G_OBJECT_CLASS (parent_class)->finalize (object);
743 dbus_gproxy_destroy (DBusGProxy *proxy)
745 /* FIXME do we need the GTK_IN_DESTRUCTION style flag
748 g_object_run_dispose (G_OBJECT (proxy));
752 create_signal_detail (const char *interface,
757 str = g_string_new (interface);
759 g_string_append (str, ".");
761 g_string_append (str, signal);
763 return g_string_free (str, FALSE);
767 dbus_gproxy_emit_received (DBusGProxy *proxy,
768 DBusMessage *message)
770 const char *interface;
775 interface = dbus_message_get_interface (message);
776 signal = dbus_message_get_member (message);
778 g_assert (interface != NULL);
779 g_assert (signal != NULL);
781 detail = create_signal_detail (interface, signal);
783 /* If the quark isn't preexisting, there's no way there
784 * are any handlers connected. We don't want to create
785 * extra quarks for every possible signal.
787 q = g_quark_try_string (detail);
790 g_signal_emit (G_OBJECT (proxy),
798 /** @} End of DBusGLibInternals */
800 /** @addtogroup DBusGLib
805 * Standard GObject get_type() function for DBusGProxy.
807 * @returns type ID for DBusGProxy class
810 dbus_gproxy_get_type (void)
812 static GType object_type = 0;
816 static const GTypeInfo object_info =
818 sizeof (DBusGProxyClass),
819 (GBaseInitFunc) NULL,
820 (GBaseFinalizeFunc) NULL,
821 (GClassInitFunc) dbus_gproxy_class_init,
822 NULL, /* class_finalize */
823 NULL, /* class_data */
826 (GInstanceInitFunc) dbus_gproxy_init,
829 object_type = g_type_register_static (G_TYPE_OBJECT,
838 dbus_gproxy_new (DBusConnection *connection,
839 const char *service_name,
840 const char *path_name,
841 const char *interface_name)
845 g_assert (connection != NULL);
847 proxy = g_object_new (DBUS_TYPE_GPROXY, NULL);
849 /* These should all be construct-only mandatory properties,
850 * for now we just don't let people use g_object_new().
853 proxy->manager = dbus_gproxy_manager_get (connection);
855 proxy->service = g_strdup (service_name);
856 proxy->path = g_strdup (path_name);
857 proxy->interface = g_strdup (interface_name);
859 dbus_gproxy_manager_register (proxy->manager, proxy);
865 * Creates a new proxy for a remote interface exported by a service on
866 * a message bus. Method calls and signal connections over this proxy
867 * will go to the service owner; the service owner is expected to
868 * support the given interface name. THE SERVICE OWNER MAY CHANGE OVER
869 * TIME, for example between two different method calls. If you need a
870 * fixed owner, you need to request the current owner and bind a proxy
871 * to that rather than to the generic service name; see
872 * dbus_gproxy_new_for_service_owner().
874 * A service-associated proxy only makes sense with a message bus,
875 * not for app-to-app direct dbus connections.
877 * This proxy will only emit the "destroy" signal if the #DBusConnection
878 * is disconnected or the proxy is has no remaining references.
880 * @param connection the connection to the remote bus
881 * @param service_name name of the service on the message bus
882 * @param path_name name of the object inside the service to call methods on
883 * @param interface_name name of the interface to call methods on
884 * @returns new proxy object
887 dbus_gproxy_new_for_service (DBusConnection *connection,
888 const char *service_name,
889 const char *path_name,
890 const char *interface_name)
894 g_return_val_if_fail (connection != NULL, NULL);
895 g_return_val_if_fail (service_name != NULL, NULL);
896 g_return_val_if_fail (path_name != NULL, NULL);
897 g_return_val_if_fail (interface_name != NULL, NULL);
899 proxy = dbus_gproxy_new (connection, service_name,
900 path_name, interface_name);
906 * Similar to dbus_gproxy_new_for_service(), but makes a round-trip
907 * request to the message bus to get the current service owner, then
908 * binds the proxy specifically to the current owner. As a result, the
909 * service owner will not change over time, and the proxy will emit
910 * the "destroy" signal when the owner disappears from the message
913 * An example of the difference between dbus_gproxy_new_for_service()
914 * and dbus_gproxy_new_for_service_owner(): if you pass the service name
915 * "org.freedesktop.Database" dbus_gproxy_new_for_service() remains bound
916 * to that name as it changes owner. dbus_gproxy_new_for_service_owner()
917 * will fail if the service has no owner. If the service has an owner,
918 * dbus_gproxy_new_for_service_owner() will bind to the unique name
919 * of that owner rather than the generic service name.
921 * @param connection the connection to the remote bus
922 * @param service_name name of the service on the message bus
923 * @param path_name name of the object inside the service to call methods on
924 * @param interface_name name of the interface to call methods on
925 * @param error return location for an error
926 * @returns new proxy object, or #NULL on error
929 dbus_gproxy_new_for_service_owner (DBusConnection *connection,
930 const char *service_name,
931 const char *path_name,
932 const char *interface_name,
935 g_return_val_if_fail (connection != NULL, NULL);
936 g_return_val_if_fail (service_name != NULL, NULL);
937 g_return_val_if_fail (path_name != NULL, NULL);
938 g_return_val_if_fail (interface_name != NULL, NULL);
944 * Creates a proxy for an object in peer application (one
945 * we're directly connected to). That is, this function is
946 * intended for use when there's no message bus involved,
947 * we're doing a simple 1-to-1 communication between two
951 * @param connection the connection to the peer
952 * @param path_name name of the object inside the peer to call methods on
953 * @param interface_name name of the interface to call methods on
954 * @returns new proxy object
958 dbus_gproxy_new_for_peer (DBusConnection *connection,
959 const char *path_name,
960 const char *interface_name)
964 g_return_val_if_fail (connection != NULL, NULL);
965 g_return_val_if_fail (path_name != NULL, NULL);
966 g_return_val_if_fail (interface_name != NULL, NULL);
968 proxy = dbus_gproxy_new (connection, NULL,
969 path_name, interface_name);
975 * Invokes a method on a remote interface. This function does not
976 * block; instead it returns an opaque #DBusPendingCall object that
977 * tracks the pending call. The method call will not be sent over the
978 * wire until the application returns to the main loop, or blocks in
979 * dbus_connection_flush() to write out pending data. The call will
980 * be completed after a timeout, or when a reply is received.
981 * To collect the results of the call (which may be an error,
982 * or a reply), use dbus_gproxy_end_call().
984 * @todo this particular function shouldn't die on out of memory,
985 * since you should be able to do a call with large arguments.
987 * @param proxy a proxy for a remote interface
988 * @param method the name of the method to invoke
989 * @param first_arg_type type of the first argument
991 * @returns opaque pending call object
994 dbus_gproxy_begin_call (DBusGProxy *proxy,
999 DBusPendingCall *pending;
1000 DBusMessage *message;
1003 g_return_val_if_fail (DBUS_IS_GPROXY (proxy), NULL);
1005 message = dbus_message_new_method_call (proxy->service,
1009 if (message == NULL)
1012 va_start (args, first_arg_type);
1013 if (!dbus_message_append_args_valist (message, first_arg_type,
1018 if (!dbus_connection_send_with_reply (proxy->manager->connection,
1027 /* FIXME we should create a pending call that's
1028 * immediately completed with an error status without
1029 * ever going on the wire.
1032 g_error ("Out of memory");
1037 * Collects the results of a method call. The method call was normally
1038 * initiated with dbus_gproxy_end_call(). This function will block if
1039 * the results haven't yet been received; use
1040 * dbus_pending_call_set_notify() to be notified asynchronously that a
1041 * pending call has been completed. Use
1042 * dbus_pending_call_get_completed() to check whether a call has been
1043 * completed. If it's completed, it will not block.
1045 * If the call results in an error, the error is set as normal for
1046 * GError and the function returns #FALSE.
1048 * Otherwise, the "out" parameters and return value of the
1049 * method are stored in the provided varargs list.
1050 * The list should be terminated with DBUS_TYPE_INVALID.
1052 * This function doesn't affect the reference count of the
1053 * #DBusPendingCall, the caller of dbus_gproxy_begin_call() still owns
1056 * @param proxy a proxy for a remote interface
1057 * @param pending the pending call from dbus_gproxy_begin_call()
1058 * @param error return location for an error
1059 * @param first_arg_type type of first "out" argument
1060 * @returns #FALSE if an error is set */
1062 dbus_gproxy_end_call (DBusGProxy *proxy,
1063 DBusPendingCall *pending,
1068 DBusMessage *message;
1072 g_return_val_if_fail (DBUS_IS_GPROXY (proxy), FALSE);
1073 g_return_val_if_fail (pending != NULL, FALSE);
1075 dbus_pending_call_block (pending);
1076 message = dbus_pending_call_get_reply (pending);
1078 g_assert (message != NULL);
1080 dbus_error_init (&derror);
1082 switch (dbus_message_get_type (message))
1084 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
1085 va_start (args, first_arg_type);
1086 if (!dbus_message_get_args_valist (message, &derror, first_arg_type, args))
1095 case DBUS_MESSAGE_TYPE_ERROR:
1096 dbus_set_error_from_message (&derror, message);
1100 dbus_set_error (&derror, DBUS_ERROR_FAILED,
1101 "Reply was neither a method return nor an exception");
1106 dbus_set_g_error (error, &derror);
1107 dbus_error_free (&derror);
1112 * Sends a method call message as with dbus_gproxy_begin_call(), but
1113 * does not ask for a reply or allow you to receive one.
1115 * @todo this particular function shouldn't die on out of memory,
1116 * since you should be able to do a call with large arguments.
1118 * @param proxy a proxy for a remote interface
1119 * @param method the name of the method to invoke
1120 * @param first_arg_type type of the first argument
1123 dbus_gproxy_call_no_reply (DBusGProxy *proxy,
1128 DBusMessage *message;
1131 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1133 message = dbus_message_new_method_call (proxy->service,
1137 if (message == NULL)
1140 dbus_message_set_no_reply (message, TRUE);
1142 va_start (args, first_arg_type);
1143 if (!dbus_message_append_args_valist (message, first_arg_type,
1148 if (!dbus_connection_send (proxy->manager->connection,
1156 g_error ("Out of memory");
1160 * Sends a message to the interface we're proxying for. Does not
1161 * block or wait for a reply. The message is only actually written out
1162 * when you return to the main loop or block in
1163 * dbus_connection_flush().
1165 * The message is modified to be addressed to the target interface.
1166 * That is, a destination service field or whatever is needed will be
1167 * added to the message. The basic point of this function is to add
1168 * the necessary header fields, otherwise it's equivalent to
1169 * dbus_connection_send().
1171 * This function adds a reference to the message, so the caller
1172 * still owns its original reference.
1174 * @param proxy a proxy for a remote interface
1175 * @param message the message to address and send
1176 * @param client_serial return location for message's serial, or #NULL */
1178 dbus_gproxy_send (DBusGProxy *proxy,
1179 DBusMessage *message,
1180 dbus_uint32_t *client_serial)
1182 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1186 if (!dbus_message_set_destination (message, proxy->service))
1187 g_error ("Out of memory");
1191 if (!dbus_message_set_path (message, proxy->path))
1192 g_error ("Out of memory");
1194 if (proxy->interface)
1196 if (!dbus_message_set_interface (message, proxy->interface))
1197 g_error ("Out of memory");
1200 if (!dbus_connection_send (proxy->manager->connection, message, client_serial))
1201 g_error ("Out of memory\n");
1205 dbus_gproxy_connect_signal (DBusGProxy *proxy,
1206 const char *signal_name,
1207 DBusGProxySignalHandler handler,
1209 GClosureNotify free_data_func)
1214 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1215 g_return_if_fail (signal_name != NULL);
1216 g_return_if_fail (handler != NULL);
1218 detail = create_signal_detail (proxy->interface, signal_name);
1220 closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func);
1221 g_signal_connect_closure_by_id (G_OBJECT (proxy),
1223 g_quark_from_string (detail),
1230 dbus_gproxy_disconnect_signal (DBusGProxy *proxy,
1231 const char *signal_name,
1232 DBusGProxySignalHandler handler,
1238 g_return_if_fail (DBUS_IS_GPROXY (proxy));
1239 g_return_if_fail (signal_name != NULL);
1240 g_return_if_fail (handler != NULL);
1242 detail = create_signal_detail (proxy->interface, signal_name);
1243 q = g_quark_try_string (detail);
1246 #ifndef G_DISABLE_CHECKS
1249 g_warning ("%s: No signal handlers for %s found on this DBusGProxy",
1250 G_GNUC_FUNCTION, signal_name);
1255 g_signal_handlers_disconnect_matched (G_OBJECT (proxy),
1256 G_SIGNAL_MATCH_DETAIL |
1257 G_SIGNAL_MATCH_FUNC |
1258 G_SIGNAL_MATCH_DATA,
1262 G_CALLBACK (handler), data);
1265 /** @} End of DBusGLib public */
1267 #ifdef DBUS_BUILD_TESTS
1270 * @ingroup DBusGLibInternals
1271 * Unit test for GLib proxy functions
1272 * @returns #TRUE on success.
1275 _dbus_gproxy_test (void)
1282 #endif /* DBUS_BUILD_TESTS */