2003-08-14 22:49:13 +00:00
/* -*- mode: C; c-file-style: "gnu" -*- */
2005-01-31 23:17:19 +00:00
/* dbus-gproxy.c Proxy for remote objects
2003-08-14 22:49:13 +00:00
*
2005-01-31 23:17:19 +00:00
* Copyright ( C ) 2003 , 2004 , 2005 Red Hat , Inc .
2003-08-14 22:49:13 +00:00
*
2004-08-10 03:07:01 +00:00
* Licensed under the Academic Free License version 2.1
2003-08-14 22:49:13 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
2004-06-20 15:28:15 +00:00
# include <dbus/dbus-glib.h>
# include <dbus/dbus-glib-lowlevel.h>
# include "dbus-gutils.h"
2005-01-31 02:55:12 +00:00
# include "dbus-gmarshal.h"
# include "dbus-gvalue.h"
2003-09-23 23:47:09 +00:00
# include <string.h>
2003-08-14 22:49:13 +00:00
/**
* @ addtogroup DBusGLibInternals
*
* @ {
*/
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
/**
* DBusGProxyManager typedef
*/
2003-09-23 23:47:09 +00:00
typedef struct DBusGProxyManager DBusGProxyManager ;
/**
* Internals of DBusGProxy
*/
struct DBusGProxy
{
GObject parent ; /**< Parent instance */
DBusGProxyManager * manager ; /**< Proxy manager */
2005-01-18 20:42:15 +00:00
char * name ; /**< Name messages go to or NULL */
2003-09-23 23:47:09 +00:00
char * path ; /**< Path messages go to or NULL */
char * interface ; /**< Interface messages go to or NULL */
2005-01-31 02:55:12 +00:00
GData * signal_signatures ; /**< D-BUS signatures for each signal */
2003-09-23 23:47:09 +00:00
} ;
2003-09-24 02:58:14 +00:00
/**
* Class struct for DBusGProxy
*/
2003-09-23 23:47:09 +00:00
struct DBusGProxyClass
{
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
GObjectClass parent_class ; /**< Parent class */
2003-09-23 23:47:09 +00:00
} ;
2005-01-31 02:55:12 +00:00
static void dbus_g_proxy_init ( DBusGProxy * proxy ) ;
static void dbus_g_proxy_class_init ( DBusGProxyClass * klass ) ;
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 ) ;
2003-09-23 23:47:09 +00:00
/**
2005-01-18 20:42:15 +00:00
* A list of proxies with a given name + path + interface , used to
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
* route incoming signals .
2003-09-23 23:47:09 +00:00
*/
typedef struct
{
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
GSList * proxies ; /**< The list of proxies */
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
char name [ 4 ] ; /**< name (empty string for none), nul byte,
2003-09-23 23:47:09 +00:00
* path , nul byte ,
* interface , nul byte
*/
} DBusGProxyList ;
2003-09-22 03:11:12 +00:00
/**
* DBusGProxyManager ' s primary task is to route signals to the proxies
* those signals are emitted on . In order to do this it also has to
2005-01-18 20:42:15 +00:00
* track the owners of the names proxies are bound to .
2003-09-22 03:11:12 +00:00
*/
2003-09-23 23:47:09 +00:00
struct DBusGProxyManager
2003-09-22 03:11:12 +00:00
{
GStaticMutex lock ; /**< Thread lock */
int refcount ; /**< Reference count */
2003-09-22 23:50:52 +00:00
DBusConnection * connection ; /**< Connection we're associated with. */
2003-09-22 03:11:12 +00:00
2003-09-23 23:47:09 +00:00
GHashTable * proxy_lists ; /**< Hash used to route incoming signals
* and iterate over proxies
*/
} ;
2004-06-20 15:28:15 +00:00
static DBusGProxyManager * dbus_g_proxy_manager_ref ( DBusGProxyManager * manager ) ;
2005-01-18 20:42:15 +00:00
static DBusHandlerResult dbus_g_proxy_manager_filter ( DBusConnection * connection ,
DBusMessage * message ,
void * user_data ) ;
2003-09-22 03:11:12 +00:00
/** Lock the DBusGProxyManager */
# define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock))
/** Unlock the DBusGProxyManager */
# define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock))
2004-06-20 15:28:15 +00:00
static int g_proxy_manager_slot = - 1 ;
2003-09-22 23:50:52 +00:00
/* Lock controlling get/set manager as data on each connection */
2004-06-20 15:28:15 +00:00
static GStaticMutex connection_g_proxy_lock = G_STATIC_MUTEX_INIT ;
2003-09-22 23:50:52 +00:00
2003-09-22 03:11:12 +00:00
static DBusGProxyManager *
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_get ( DBusConnection * connection )
2003-09-22 03:11:12 +00:00
{
DBusGProxyManager * manager ;
2004-06-20 15:28:15 +00:00
dbus_connection_allocate_data_slot ( & g_proxy_manager_slot ) ;
if ( g_proxy_manager_slot < 0 )
2003-09-22 23:50:52 +00:00
g_error ( " out of memory " ) ;
2004-06-20 15:28:15 +00:00
g_static_mutex_lock ( & connection_g_proxy_lock ) ;
2003-09-22 23:50:52 +00:00
2004-06-20 15:28:15 +00:00
manager = dbus_connection_get_data ( connection , g_proxy_manager_slot ) ;
2003-09-22 23:50:52 +00:00
if ( manager ! = NULL )
{
2004-06-20 15:28:15 +00:00
dbus_connection_free_data_slot ( & g_proxy_manager_slot ) ;
dbus_g_proxy_manager_ref ( manager ) ;
g_static_mutex_unlock ( & connection_g_proxy_lock ) ;
2003-09-22 23:50:52 +00:00
return manager ;
}
2003-09-22 03:11:12 +00:00
manager = g_new0 ( DBusGProxyManager , 1 ) ;
manager - > refcount = 1 ;
2003-09-22 23:50:52 +00:00
manager - > connection = connection ;
2003-09-22 03:11:12 +00:00
g_static_mutex_init ( & manager - > lock ) ;
2003-09-22 23:50:52 +00:00
/* Proxy managers keep the connection alive, which means that
* DBusGProxy indirectly does . To free a connection you have to free
* all the proxies referring to it .
*/
dbus_connection_ref ( manager - > connection ) ;
2004-06-20 15:28:15 +00:00
dbus_connection_set_data ( connection , g_proxy_manager_slot ,
2003-09-22 23:50:52 +00:00
manager , NULL ) ;
2004-06-20 15:28:15 +00:00
dbus_connection_add_filter ( connection , dbus_g_proxy_manager_filter ,
2003-09-23 23:47:09 +00:00
manager , NULL ) ;
2004-06-20 15:28:15 +00:00
g_static_mutex_unlock ( & connection_g_proxy_lock ) ;
2003-09-22 23:50:52 +00:00
2003-09-22 03:11:12 +00:00
return manager ;
}
2003-11-27 01:25:50 +00:00
static DBusGProxyManager *
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_ref ( DBusGProxyManager * manager )
2003-09-22 03:11:12 +00:00
{
g_assert ( manager ! = NULL ) ;
g_assert ( manager - > refcount > 0 ) ;
LOCK_MANAGER ( manager ) ;
manager - > refcount + = 1 ;
UNLOCK_MANAGER ( manager ) ;
2003-11-27 01:25:50 +00:00
return manager ;
2003-09-22 03:11:12 +00:00
}
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_unref ( DBusGProxyManager * manager )
2003-09-22 03:11:12 +00:00
{
g_assert ( manager ! = NULL ) ;
g_assert ( manager - > refcount > 0 ) ;
LOCK_MANAGER ( manager ) ;
manager - > refcount - = 1 ;
if ( manager - > refcount = = 0 )
{
UNLOCK_MANAGER ( manager ) ;
2003-09-23 23:47:09 +00:00
if ( manager - > proxy_lists )
{
2003-09-24 02:58:14 +00:00
/* can't have any proxies left since they hold
* a reference to the proxy manager .
*/
g_assert ( g_hash_table_size ( manager - > proxy_lists ) = = 0 ) ;
2003-09-23 23:47:09 +00:00
g_hash_table_destroy ( manager - > proxy_lists ) ;
manager - > proxy_lists = NULL ;
}
2003-09-22 03:11:12 +00:00
g_static_mutex_free ( & manager - > lock ) ;
2004-06-20 15:28:15 +00:00
g_static_mutex_lock ( & connection_g_proxy_lock ) ;
2003-09-23 23:47:09 +00:00
2004-06-20 15:28:15 +00:00
dbus_connection_remove_filter ( manager - > connection , dbus_g_proxy_manager_filter ,
2003-09-23 23:47:09 +00:00
manager ) ;
2003-09-22 23:50:52 +00:00
dbus_connection_set_data ( manager - > connection ,
2004-06-20 15:28:15 +00:00
g_proxy_manager_slot ,
2003-09-22 23:50:52 +00:00
NULL , NULL ) ;
2004-06-20 15:28:15 +00:00
g_static_mutex_unlock ( & connection_g_proxy_lock ) ;
2003-09-22 23:50:52 +00:00
dbus_connection_unref ( manager - > connection ) ;
2003-09-22 03:11:12 +00:00
g_free ( manager ) ;
2003-09-22 23:50:52 +00:00
2004-06-20 15:28:15 +00:00
dbus_connection_free_data_slot ( & g_proxy_manager_slot ) ;
2003-09-22 03:11:12 +00:00
}
else
{
UNLOCK_MANAGER ( manager ) ;
}
}
2003-09-23 23:47:09 +00:00
static guint
tristring_hash ( gconstpointer key )
2003-08-14 22:49:13 +00:00
{
2003-09-23 23:47:09 +00:00
const char * p = key ;
guint h = * p ;
if ( h )
{
for ( p + = 1 ; * p ! = ' \0 ' ; p + + )
h = ( h < < 5 ) - h + * p ;
}
/* skip nul and do the next substring */
for ( p + = 1 ; * p ! = ' \0 ' ; p + + )
h = ( h < < 5 ) - h + * p ;
/* skip nul again and another substring */
for ( p + = 1 ; * p ! = ' \0 ' ; p + + )
h = ( h < < 5 ) - h + * p ;
2003-09-23 04:20:06 +00:00
2003-09-23 23:47:09 +00:00
return h ;
}
2003-08-14 22:49:13 +00:00
2003-09-23 23:47:09 +00:00
static gboolean
strequal_len ( const char * a ,
const char * b ,
size_t * lenp )
2003-09-23 04:20:06 +00:00
{
2003-09-23 23:47:09 +00:00
size_t a_len ;
size_t b_len ;
a_len = strlen ( a ) ;
b_len = strlen ( b ) ;
if ( a_len ! = b_len )
return FALSE ;
if ( memcmp ( a , b , a_len ) ! = 0 )
return FALSE ;
* lenp = a_len ;
return TRUE ;
}
static gboolean
tristring_equal ( gconstpointer a ,
gconstpointer b )
{
const char * ap = a ;
const char * bp = b ;
size_t len ;
if ( ! strequal_len ( ap , bp , & len ) )
return FALSE ;
ap + = len + 1 ;
bp + = len + 1 ;
if ( ! strequal_len ( ap , bp , & len ) )
return FALSE ;
ap + = len + 1 ;
bp + = len + 1 ;
if ( strcmp ( ap , bp ) ! = 0 )
return FALSE ;
return TRUE ;
}
static char *
tristring_alloc_from_strings ( size_t padding_before ,
2005-01-18 20:42:15 +00:00
const char * name ,
2003-09-23 23:47:09 +00:00
const char * path ,
const char * interface )
{
2005-01-18 20:42:15 +00:00
size_t name_len , iface_len , path_len , len ;
2003-09-23 23:47:09 +00:00
char * tri ;
2005-01-18 20:42:15 +00:00
if ( name )
name_len = strlen ( name ) ;
2003-09-23 23:47:09 +00:00
else
2005-01-18 20:42:15 +00:00
name_len = 0 ;
2003-09-23 23:47:09 +00:00
path_len = strlen ( path ) ;
iface_len = strlen ( interface ) ;
2005-01-18 20:42:15 +00:00
tri = g_malloc ( padding_before + name_len + path_len + iface_len + 3 ) ;
2003-09-23 23:47:09 +00:00
len = padding_before ;
2005-01-18 20:42:15 +00:00
if ( name )
memcpy ( & tri [ len ] , name , name_len ) ;
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
len + = name_len ;
2003-09-23 23:47:09 +00:00
tri [ len ] = ' \0 ' ;
len + = 1 ;
2005-01-18 20:42:15 +00:00
g_assert ( len = = ( padding_before + name_len + 1 ) ) ;
2003-09-23 23:47:09 +00:00
memcpy ( & tri [ len ] , path , path_len ) ;
len + = path_len ;
tri [ len ] = ' \0 ' ;
len + = 1 ;
2005-01-18 20:42:15 +00:00
g_assert ( len = = ( padding_before + name_len + path_len + 2 ) ) ;
2003-09-23 23:47:09 +00:00
memcpy ( & tri [ len ] , interface , iface_len ) ;
len + = iface_len ;
tri [ len ] = ' \0 ' ;
len + = 1 ;
2005-01-18 20:42:15 +00:00
g_assert ( len = = ( padding_before + name_len + path_len + iface_len + 3 ) ) ;
2003-09-23 23:47:09 +00:00
return tri ;
}
static char *
tristring_from_proxy ( DBusGProxy * proxy )
{
return tristring_alloc_from_strings ( 0 ,
2005-01-18 20:42:15 +00:00
proxy - > name ,
2003-09-23 23:47:09 +00:00
proxy - > path ,
proxy - > interface ) ;
}
static char *
tristring_from_message ( DBusMessage * message )
{
2005-02-05 04:15:57 +00:00
const char * path ;
const char * interface ;
path = dbus_message_get_path ( message ) ;
interface = dbus_message_get_interface ( message ) ;
g_assert ( path ) ;
g_assert ( interface ) ;
2003-09-23 23:47:09 +00:00
return tristring_alloc_from_strings ( 0 ,
dbus_message_get_sender ( message ) ,
2005-02-05 04:15:57 +00:00
path , interface ) ;
2003-09-23 23:47:09 +00:00
}
static DBusGProxyList *
2004-06-20 15:28:15 +00:00
g_proxy_list_new ( DBusGProxy * first_proxy )
2003-09-23 23:47:09 +00:00
{
DBusGProxyList * list ;
list = ( void * ) tristring_alloc_from_strings ( G_STRUCT_OFFSET ( DBusGProxyList , name ) ,
2005-01-18 20:42:15 +00:00
first_proxy - > name ,
2003-09-23 23:47:09 +00:00
first_proxy - > path ,
first_proxy - > interface ) ;
list - > proxies = NULL ;
return list ;
}
static void
2004-06-20 15:28:15 +00:00
g_proxy_list_free ( DBusGProxyList * list )
2003-09-23 23:47:09 +00:00
{
/* we don't hold a reference to the proxies in the list,
* as they ref the GProxyManager
*/
g_slist_free ( list - > proxies ) ;
g_free ( list ) ;
}
static char *
2004-06-20 15:28:15 +00:00
g_proxy_get_match_rule ( DBusGProxy * proxy )
2003-09-23 23:47:09 +00:00
{
2003-10-21 05:46:52 +00:00
/* FIXME Escaping is required here */
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
if ( proxy - > name )
2003-10-16 Havoc Pennington <hp@redhat.com>
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess
* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received
* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak
* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.
* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set
* dbus/dbus-internals.c: add pid to assertion failure messages
* dbus/dbus-connection.c: add message type code to the debug spew
* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo
* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead
* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate
* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct
* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)
* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR
* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing
* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused
* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.
2003-10-16 06:34:51 +00:00
return g_strdup_printf ( " type='signal',sender='%s',path='%s',interface='%s' " ,
2005-01-18 20:42:15 +00:00
proxy - > name , proxy - > path , proxy - > interface ) ;
2003-09-23 23:47:09 +00:00
else
return g_strdup_printf ( " type='signal',path='%s',interface='%s' " ,
proxy - > path , proxy - > interface ) ;
}
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_register ( DBusGProxyManager * manager ,
2005-01-18 20:42:15 +00:00
DBusGProxy * proxy )
2003-09-23 23:47:09 +00:00
{
DBusGProxyList * list ;
LOCK_MANAGER ( manager ) ;
if ( manager - > proxy_lists = = NULL )
{
list = NULL ;
manager - > proxy_lists = g_hash_table_new_full ( tristring_hash ,
tristring_equal ,
NULL ,
2004-06-20 15:28:15 +00:00
( GFreeFunc ) g_proxy_list_free ) ;
2003-09-23 23:47:09 +00:00
}
else
{
char * tri ;
tri = tristring_from_proxy ( proxy ) ;
list = g_hash_table_lookup ( manager - > proxy_lists , tri ) ;
g_free ( tri ) ;
}
if ( list = = NULL )
{
2004-06-20 15:28:15 +00:00
list = g_proxy_list_new ( proxy ) ;
2003-09-23 23:47:09 +00:00
g_hash_table_replace ( manager - > proxy_lists ,
list - > name , list ) ;
}
if ( list - > proxies = = NULL )
{
/* We have to add the match rule to the server,
* but FIXME only if the server is a message bus ,
* not if it ' s a peer .
*/
char * rule ;
2004-06-20 15:28:15 +00:00
rule = g_proxy_get_match_rule ( proxy ) ;
2003-09-23 23:47:09 +00:00
/* We don't check for errors; it's not like anyone would handle them,
* and we don ' t want a round trip here .
*/
dbus_bus_add_match ( manager - > connection ,
rule , NULL ) ;
g_free ( rule ) ;
}
g_assert ( g_slist_find ( list - > proxies , proxy ) = = NULL ) ;
list - > proxies = g_slist_prepend ( list - > proxies , proxy ) ;
UNLOCK_MANAGER ( manager ) ;
}
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_unregister ( DBusGProxyManager * manager ,
2003-09-23 23:47:09 +00:00
DBusGProxy * proxy )
{
DBusGProxyList * list ;
char * tri ;
LOCK_MANAGER ( manager ) ;
2003-09-24 02:58:14 +00:00
# ifndef G_DISABLE_CHECKS
2003-09-23 23:47:09 +00:00
if ( manager - > proxy_lists = = NULL )
{
2003-10-12 05:59:39 +00:00
g_warning ( " Trying to unregister a proxy but there aren't any registered " ) ;
2003-09-23 23:47:09 +00:00
return ;
}
2003-09-24 02:58:14 +00:00
# endif
2003-09-23 23:47:09 +00:00
tri = tristring_from_proxy ( proxy ) ;
list = g_hash_table_lookup ( manager - > proxy_lists , tri ) ;
2003-09-24 02:58:14 +00:00
# ifndef G_DISABLE_CHECKS
2003-09-23 23:47:09 +00:00
if ( list = = NULL )
{
2003-10-12 05:59:39 +00:00
g_warning ( " Trying to unregister a proxy but it isn't registered " ) ;
2003-09-23 23:47:09 +00:00
return ;
}
2003-09-24 02:58:14 +00:00
# endif
2003-09-23 23:47:09 +00:00
g_assert ( g_slist_find ( list - > proxies , proxy ) ! = NULL ) ;
list - > proxies = g_slist_remove ( list - > proxies , proxy ) ;
g_assert ( g_slist_find ( list - > proxies , proxy ) = = NULL ) ;
2003-09-24 02:58:14 +00:00
2003-10-12 05:59:39 +00:00
if ( list - > proxies = = NULL )
{
g_hash_table_remove ( manager - > proxy_lists ,
tri ) ;
list = NULL ;
}
2003-09-24 02:58:14 +00:00
if ( g_hash_table_size ( manager - > proxy_lists ) = = 0 )
{
g_hash_table_destroy ( manager - > proxy_lists ) ;
manager - > proxy_lists = NULL ;
}
2003-10-12 05:59:39 +00:00
g_free ( tri ) ;
2003-09-23 23:47:09 +00:00
UNLOCK_MANAGER ( manager ) ;
}
2003-09-24 02:58:14 +00:00
static void
list_proxies_foreach ( gpointer key ,
gpointer value ,
gpointer user_data )
{
DBusGProxyList * list ;
GSList * * ret ;
GSList * tmp ;
list = value ;
ret = user_data ;
tmp = list - > proxies ;
while ( tmp ! = NULL )
{
2004-06-20 15:28:15 +00:00
DBusGProxy * proxy = DBUS_G_PROXY ( tmp - > data ) ;
2003-09-24 02:58:14 +00:00
g_object_ref ( proxy ) ;
* ret = g_slist_prepend ( * ret , proxy ) ;
tmp = tmp - > next ;
}
}
static GSList *
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_list_all ( DBusGProxyManager * manager )
2003-09-24 02:58:14 +00:00
{
GSList * ret ;
ret = NULL ;
if ( manager - > proxy_lists )
{
g_hash_table_foreach ( manager - > proxy_lists ,
list_proxies_foreach ,
& ret ) ;
}
return ret ;
}
2003-09-23 23:47:09 +00:00
static DBusHandlerResult
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_filter ( DBusConnection * connection ,
2005-02-05 04:15:57 +00:00
DBusMessage * message ,
void * user_data )
2003-09-23 23:47:09 +00:00
{
DBusGProxyManager * manager ;
if ( dbus_message_get_type ( message ) ! = DBUS_MESSAGE_TYPE_SIGNAL )
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED ;
2003-09-24 02:58:14 +00:00
manager = user_data ;
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_ref ( manager ) ;
2003-09-24 02:58:14 +00:00
LOCK_MANAGER ( manager ) ;
2003-09-23 23:47:09 +00:00
if ( dbus_message_is_signal ( message ,
DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL ,
" Disconnected " ) )
{
2003-09-24 02:58:14 +00:00
/* Destroy all the proxies, quite possibly resulting in unreferencing
* the proxy manager and the connection as well .
2003-09-23 23:47:09 +00:00
*/
2003-09-24 02:58:14 +00:00
GSList * all ;
GSList * tmp ;
2004-06-20 15:28:15 +00:00
all = dbus_g_proxy_manager_list_all ( manager ) ;
2003-09-24 02:58:14 +00:00
tmp = all ;
while ( tmp ! = NULL )
{
DBusGProxy * proxy ;
2004-06-20 15:28:15 +00:00
proxy = DBUS_G_PROXY ( tmp - > data ) ;
2003-09-24 02:58:14 +00:00
UNLOCK_MANAGER ( manager ) ;
2004-06-20 15:28:15 +00:00
dbus_g_proxy_destroy ( proxy ) ;
2003-09-24 02:58:14 +00:00
g_object_unref ( G_OBJECT ( proxy ) ) ;
LOCK_MANAGER ( manager ) ;
tmp = tmp - > next ;
}
g_slist_free ( all ) ;
# ifndef G_DISABLE_CHECKS
if ( manager - > proxy_lists ! = NULL )
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. " ) ;
# endif
2003-09-23 23:47:09 +00:00
}
else
{
char * tri ;
DBusGProxyList * list ;
2005-02-05 04:15:57 +00:00
/* dbus spec requires these, libdbus validates */
g_assert ( dbus_message_get_path ( message ) ! = NULL ) ;
g_assert ( dbus_message_get_interface ( message ) ! = NULL ) ;
g_assert ( dbus_message_get_member ( message ) ! = NULL ) ;
2003-09-23 23:47:09 +00:00
tri = tristring_from_message ( message ) ;
2003-08-16 21:28:47 +00:00
2003-09-23 23:47:09 +00:00
if ( manager - > proxy_lists )
list = g_hash_table_lookup ( manager - > proxy_lists , tri ) ;
else
list = NULL ;
2003-10-21 05:46:52 +00:00
#if 0
g_print ( " proxy got %s,%s,%s = list %p \n " ,
tri ,
tri + strlen ( tri ) + 1 ,
tri + strlen ( tri ) + 1 + strlen ( tri + strlen ( tri ) + 1 ) + 1 ,
list ) ;
# endif
2003-09-23 23:47:09 +00:00
g_free ( tri ) ;
2003-09-24 02:58:14 +00:00
/* Emit the signal */
2003-09-23 23:47:09 +00:00
if ( list ! = NULL )
{
2003-09-24 02:58:14 +00:00
GSList * tmp ;
GSList * copy ;
2003-09-23 23:47:09 +00:00
2003-09-24 02:58:14 +00:00
copy = g_slist_copy ( list - > proxies ) ;
g_slist_foreach ( copy , ( GFunc ) g_object_ref , NULL ) ;
tmp = copy ;
while ( tmp ! = NULL )
{
DBusGProxy * proxy ;
2004-06-20 15:28:15 +00:00
proxy = DBUS_G_PROXY ( tmp - > data ) ;
2003-09-24 02:58:14 +00:00
UNLOCK_MANAGER ( manager ) ;
2005-01-31 02:55:12 +00:00
dbus_g_proxy_emit_remote_signal ( proxy , message ) ;
2003-09-24 02:58:14 +00:00
g_object_unref ( G_OBJECT ( proxy ) ) ;
LOCK_MANAGER ( manager ) ;
tmp = tmp - > next ;
}
g_slist_free ( copy ) ;
2003-09-23 23:47:09 +00:00
}
}
2003-09-24 02:58:14 +00:00
UNLOCK_MANAGER ( manager ) ;
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_unref ( manager ) ;
2003-09-23 23:47:09 +00:00
/* "Handling" signals doesn't make sense, they are for everyone
* who cares
*/
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED ;
}
/* ---------- DBusGProxy -------------- */
2005-02-05 04:15:57 +00:00
# define DBUS_G_PROXY_DESTROYED(proxy) (DBUS_G_PROXY (proxy)->manager == NULL)
2005-01-31 23:17:19 +00:00
static void
marshal_dbus_message_to_g_marshaller ( GClosure * closure ,
GValue * return_value ,
guint n_param_values ,
const GValue * param_values ,
gpointer invocation_hint ,
gpointer marshal_data ) ;
2003-09-23 23:47:09 +00:00
enum
{
2003-09-24 02:58:14 +00:00
DESTROY ,
2005-01-31 23:17:19 +00:00
RECEIVED ,
2003-09-23 23:47:09 +00:00
LAST_SIGNAL
} ;
2003-09-23 04:20:06 +00:00
static void * parent_class ;
2003-09-23 23:47:09 +00:00
static guint signals [ LAST_SIGNAL ] = { 0 } ;
2003-09-23 04:20:06 +00:00
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_init ( DBusGProxy * proxy )
2003-08-14 22:49:13 +00:00
{
2005-01-31 02:55:12 +00:00
g_datalist_init ( & proxy - > signal_signatures ) ;
2003-09-23 04:20:06 +00:00
}
2003-08-14 22:49:13 +00:00
2003-09-23 04:20:06 +00:00
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_class_init ( DBusGProxyClass * klass )
2003-09-23 04:20:06 +00:00
{
GObjectClass * object_class = G_OBJECT_CLASS ( klass ) ;
2003-08-16 21:28:47 +00:00
2003-09-23 04:20:06 +00:00
parent_class = g_type_class_peek_parent ( klass ) ;
2004-06-20 15:28:15 +00:00
object_class - > finalize = dbus_g_proxy_finalize ;
object_class - > dispose = dbus_g_proxy_dispose ;
2003-09-24 02:58:14 +00:00
signals [ DESTROY ] =
g_signal_new ( " destroy " ,
G_OBJECT_CLASS_TYPE ( object_class ) ,
G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS ,
0 ,
NULL , NULL ,
g_cclosure_marshal_VOID__VOID ,
G_TYPE_NONE , 0 ) ;
2003-08-14 22:49:13 +00:00
2005-01-31 23:17:19 +00:00
signals [ RECEIVED ] =
g_signal_new ( " received " ,
G_OBJECT_CLASS_TYPE ( object_class ) ,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED ,
0 ,
NULL , NULL ,
marshal_dbus_message_to_g_marshaller ,
G_TYPE_NONE , 2 , DBUS_TYPE_MESSAGE , G_TYPE_STRING ) ;
}
2003-09-24 02:58:14 +00:00
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_dispose ( GObject * object )
2003-09-24 02:58:14 +00:00
{
DBusGProxy * proxy ;
2004-06-20 15:28:15 +00:00
proxy = DBUS_G_PROXY ( object ) ;
2003-09-24 02:58:14 +00:00
2005-02-05 04:15:57 +00:00
if ( proxy - > manager )
{
dbus_g_proxy_manager_unregister ( proxy - > manager , proxy ) ;
dbus_g_proxy_manager_unref ( proxy - > manager ) ;
proxy - > manager = NULL ;
}
2005-01-31 02:55:12 +00:00
g_datalist_clear ( & proxy - > signal_signatures ) ;
2003-09-24 02:58:14 +00:00
g_signal_emit ( object , signals [ DESTROY ] , 0 ) ;
G_OBJECT_CLASS ( parent_class ) - > dispose ( object ) ;
}
2003-09-23 04:20:06 +00:00
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_finalize ( GObject * object )
2003-09-23 04:20:06 +00:00
{
DBusGProxy * proxy ;
2005-02-05 04:15:57 +00:00
2004-06-20 15:28:15 +00:00
proxy = DBUS_G_PROXY ( object ) ;
2003-09-23 04:20:06 +00:00
2005-02-05 04:15:57 +00:00
g_return_if_fail ( DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
g_free ( proxy - > name ) ;
2003-09-23 04:20:06 +00:00
g_free ( proxy - > path ) ;
g_free ( proxy - > interface ) ;
2003-08-16 21:28:47 +00:00
2003-09-23 04:20:06 +00:00
G_OBJECT_CLASS ( parent_class ) - > finalize ( object ) ;
2003-08-14 22:49:13 +00:00
}
2003-09-24 02:58:14 +00:00
static void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_destroy ( DBusGProxy * proxy )
2003-09-24 02:58:14 +00:00
{
/* FIXME do we need the GTK_IN_DESTRUCTION style flag
* from GtkObject ?
*/
g_object_run_dispose ( G_OBJECT ( proxy ) ) ;
}
2005-01-31 02:55:12 +00:00
/* 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
* globally to all proxies )
*/
2003-09-23 23:47:09 +00:00
static char *
2005-01-31 02:55:12 +00:00
create_signal_name ( const char * interface ,
const char * signal )
2003-09-23 23:47:09 +00:00
{
GString * str ;
2005-01-31 02:55:12 +00:00
char * p ;
2003-09-23 23:47:09 +00:00
str = g_string_new ( interface ) ;
2005-01-31 02:55:12 +00:00
g_string_append ( str , " - " ) ;
2003-09-23 23:47:09 +00:00
g_string_append ( str , signal ) ;
2005-01-31 02:55:12 +00:00
/* GLib will silently barf on '.' in signal names */
p = str - > str ;
while ( * p )
{
if ( * p = = ' . ' )
* p = ' - ' ;
+ + p ;
}
2003-09-23 23:47:09 +00:00
return g_string_free ( str , FALSE ) ;
}
2005-01-31 23:17:19 +00:00
static GSignalCMarshaller
lookup_g_marshaller ( DBusGProxy * proxy ,
const char * signature )
{
/* The "proxy" arg would eventually be used if you could provide
* a marshaller when adding a signal to the proxy
*/
# define MATCH1(sig, t0) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == '\0')
# define MATCH2(sig, t0, t1) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == (DBUS_TYPE_##t1) && (sig)[2] == '\0')
# define MATCH3(sig, t0, t1, t2) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == (DBUS_TYPE_##t1) && (sig)[2] == (DBUS_TYPE_##t2) && (sig)[3] == '\0')
switch ( * signature )
{
case ' \0 ' :
return g_cclosure_marshal_VOID__VOID ;
case DBUS_TYPE_BOOLEAN :
if ( MATCH1 ( signature , BOOLEAN ) )
return g_cclosure_marshal_VOID__BOOLEAN ;
break ;
case DBUS_TYPE_BYTE :
if ( MATCH1 ( signature , BYTE ) )
return g_cclosure_marshal_VOID__UCHAR ;
break ;
case DBUS_TYPE_INT16 :
if ( MATCH1 ( signature , INT16 ) )
return g_cclosure_marshal_VOID__INT ;
break ;
case DBUS_TYPE_UINT16 :
if ( MATCH1 ( signature , UINT16 ) )
return g_cclosure_marshal_VOID__UINT ;
break ;
case DBUS_TYPE_INT32 :
if ( MATCH1 ( signature , INT32 ) )
return g_cclosure_marshal_VOID__INT ;
break ;
case DBUS_TYPE_UINT32 :
if ( MATCH1 ( signature , UINT32 ) )
return g_cclosure_marshal_VOID__UINT ;
break ;
case DBUS_TYPE_DOUBLE :
if ( MATCH1 ( signature , DOUBLE ) )
return g_cclosure_marshal_VOID__DOUBLE ;
break ;
case DBUS_TYPE_OBJECT_PATH :
if ( MATCH1 ( signature , OBJECT_PATH ) )
return g_cclosure_marshal_VOID__STRING ;
break ;
case DBUS_TYPE_SIGNATURE :
if ( MATCH1 ( signature , SIGNATURE ) )
return g_cclosure_marshal_VOID__STRING ;
break ;
case DBUS_TYPE_STRING :
if ( MATCH1 ( signature , STRING ) )
return g_cclosure_marshal_VOID__STRING ;
/* This is for NameOwnerChanged */
else if ( MATCH3 ( signature , STRING , STRING , STRING ) )
return _dbus_g_marshal_NONE__STRING_STRING_STRING ;
break ;
}
return NULL ;
}
2003-09-23 23:47:09 +00:00
static void
2005-01-31 23:17:19 +00:00
marshal_dbus_message_to_g_marshaller ( GClosure * closure ,
GValue * return_value ,
guint n_param_values ,
const GValue * param_values ,
gpointer invocation_hint ,
gpointer marshal_data )
2005-01-31 02:55:12 +00:00
{
2005-01-31 23:17:19 +00:00
/* Incoming here we have three params, the instance (Proxy), the
* DBusMessage , the signature . We want to convert that to an
* expanded GValue array , then call an appropriate normal GLib
* marshaller .
*/
2005-01-31 02:55:12 +00:00
# define MAX_SIGNATURE_ARGS 20
2005-01-31 23:17:19 +00:00
GValue expanded [ MAX_SIGNATURE_ARGS ] ;
2005-01-31 02:55:12 +00:00
int arg ;
int i ;
2005-01-31 23:17:19 +00:00
DBusMessageIter iter ;
int dtype ;
GSignalCMarshaller c_marshaller ;
DBusGProxy * proxy ;
DBusMessage * message ;
const char * signature ;
2005-01-31 02:55:12 +00:00
2005-01-31 23:17:19 +00:00
g_assert ( n_param_values = = 3 ) ;
proxy = g_value_get_object ( & param_values [ 0 ] ) ;
message = g_value_get_boxed ( & param_values [ 1 ] ) ;
signature = g_value_get_string ( & param_values [ 2 ] ) ;
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
g_return_if_fail ( message ! = NULL ) ;
g_return_if_fail ( signature ! = NULL ) ;
c_marshaller = lookup_g_marshaller ( proxy , signature ) ;
g_return_if_fail ( c_marshaller ! = NULL ) ;
memset ( & expanded [ 0 ] , 0 , sizeof ( expanded ) ) ;
2005-01-31 02:55:12 +00:00
arg = 0 ;
2005-01-31 23:17:19 +00:00
g_value_init ( & expanded [ arg ] , G_TYPE_FROM_INSTANCE ( proxy ) ) ;
g_value_set_instance ( & expanded [ arg ] , proxy ) ;
2005-01-31 02:55:12 +00:00
+ + arg ;
2005-01-31 23:17:19 +00:00
dbus_message_iter_init ( message , & iter ) ;
while ( ( dtype = dbus_message_iter_get_arg_type ( & iter ) ) ! = DBUS_TYPE_INVALID )
2005-01-31 02:55:12 +00:00
{
2005-01-31 23:17:19 +00:00
if ( arg = = MAX_SIGNATURE_ARGS )
{
g_warning ( " Don't support more than %d signal args \n " , MAX_SIGNATURE_ARGS ) ;
goto out ;
}
2005-01-31 02:55:12 +00:00
2005-01-31 23:17:19 +00:00
if ( ! dbus_gvalue_demarshal ( & iter , & expanded [ arg ] ) )
2005-01-31 02:55:12 +00:00
{
2005-01-31 23:17:19 +00:00
g_warning ( " Unable to convert arg type %d to GValue to emit DBusGProxy signal " , dtype ) ;
goto out ;
2005-01-31 02:55:12 +00:00
}
2005-01-31 23:17:19 +00:00
+ + arg ;
dbus_message_iter_next ( & iter ) ;
}
2005-01-31 02:55:12 +00:00
2005-01-31 23:17:19 +00:00
( * c_marshaller ) ( closure , return_value , arg , & expanded [ 0 ] ,
invocation_hint , marshal_data ) ;
2005-01-31 02:55:12 +00:00
out :
i = 0 ;
while ( i < arg )
{
2005-01-31 23:17:19 +00:00
g_value_unset ( & expanded [ i ] ) ;
2005-01-31 02:55:12 +00:00
+ + i ;
}
}
static void
dbus_g_proxy_emit_remote_signal ( DBusGProxy * proxy ,
DBusMessage * message )
2003-09-23 23:47:09 +00:00
{
const char * interface ;
const char * signal ;
2005-01-31 02:55:12 +00:00
char * name ;
2003-09-23 23:47:09 +00:00
GQuark q ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-09-23 23:47:09 +00:00
interface = dbus_message_get_interface ( message ) ;
signal = dbus_message_get_member ( message ) ;
g_assert ( interface ! = NULL ) ;
g_assert ( signal ! = NULL ) ;
2005-01-31 02:55:12 +00:00
name = create_signal_name ( interface , signal ) ;
2003-09-23 23:47:09 +00:00
/* If the quark isn't preexisting, there's no way there
* are any handlers connected . We don ' t want to create
* extra quarks for every possible signal .
*/
2005-01-31 02:55:12 +00:00
q = g_quark_try_string ( name ) ;
2003-09-23 23:47:09 +00:00
if ( q ! = 0 )
2005-01-31 02:55:12 +00:00
{
const char * signature ;
2003-09-23 23:47:09 +00:00
2005-01-31 02:55:12 +00:00
signature = g_datalist_id_get_data ( & proxy - > signal_signatures , q ) ;
if ( signature = = NULL )
{
2005-02-05 04:15:57 +00:00
#if 0
/* this should not trigger a warning, as you shouldn't have to
* add signals you don ' t care about
*/
2005-01-31 02:55:12 +00:00
g_warning ( " Signal '%s' has not been added to this proxy object \n " ,
name ) ;
2005-02-05 04:15:57 +00:00
# endif
2005-01-31 02:55:12 +00:00
}
else if ( ! dbus_message_has_signature ( message , signature ) )
{
g_warning ( " Signature '%s' expected for signal '%s', actual signature '%s' \n " ,
signature ,
name ,
dbus_message_get_signature ( message ) ) ;
}
else
{
2005-01-31 23:17:19 +00:00
g_signal_emit ( proxy ,
signals [ RECEIVED ] ,
q ,
message ,
signature ) ;
2005-01-31 02:55:12 +00:00
}
}
g_free ( name ) ;
2003-09-23 23:47:09 +00:00
}
2003-08-14 22:49:13 +00:00
/** @} End of DBusGLibInternals */
/** @addtogroup DBusGLib
* @ {
*/
2003-09-23 04:20:06 +00:00
/**
* Standard GObject get_type ( ) function for DBusGProxy .
*
* @ returns type ID for DBusGProxy class
*/
GType
2004-06-20 15:28:15 +00:00
dbus_g_proxy_get_type ( void )
2003-09-23 04:20:06 +00:00
{
static GType object_type = 0 ;
if ( ! object_type )
{
static const GTypeInfo object_info =
{
sizeof ( DBusGProxyClass ) ,
( GBaseInitFunc ) NULL ,
( GBaseFinalizeFunc ) NULL ,
2004-06-20 15:28:15 +00:00
( GClassInitFunc ) dbus_g_proxy_class_init ,
2003-09-23 04:20:06 +00:00
NULL , /* class_finalize */
NULL , /* class_data */
sizeof ( DBusGProxy ) ,
0 , /* n_preallocs */
2004-06-20 15:28:15 +00:00
( GInstanceInitFunc ) dbus_g_proxy_init ,
2003-09-23 04:20:06 +00:00
} ;
object_type = g_type_register_static ( G_TYPE_OBJECT ,
" DBusGProxy " ,
& object_info , 0 ) ;
}
return object_type ;
}
2003-09-23 23:47:09 +00:00
static DBusGProxy *
2004-06-20 15:28:15 +00:00
dbus_g_proxy_new ( DBusGConnection * connection ,
2005-01-18 20:42:15 +00:00
const char * name ,
const char * path_name ,
const char * interface_name )
2003-09-23 23:47:09 +00:00
{
DBusGProxy * proxy ;
g_assert ( connection ! = NULL ) ;
2004-06-20 15:28:15 +00:00
proxy = g_object_new ( DBUS_TYPE_G_PROXY , NULL ) ;
2003-09-23 23:47:09 +00:00
/* These should all be construct-only mandatory properties,
* for now we just don ' t let people use g_object_new ( ) .
*/
2004-06-20 15:28:15 +00:00
proxy - > manager = dbus_g_proxy_manager_get ( DBUS_CONNECTION_FROM_G_CONNECTION ( connection ) ) ;
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
proxy - > name = g_strdup ( name ) ;
2003-09-23 23:47:09 +00:00
proxy - > path = g_strdup ( path_name ) ;
proxy - > interface = g_strdup ( interface_name ) ;
2004-06-20 15:28:15 +00:00
dbus_g_proxy_manager_register ( proxy - > manager , proxy ) ;
2003-09-23 23:47:09 +00:00
return proxy ;
}
2003-08-14 22:49:13 +00:00
/**
2005-01-18 20:42:15 +00:00
* Creates a new proxy for a remote interface exported by a connection
* on a message bus . Method calls and signal connections over this
* proxy will go to the name owner ; the name ' s owner is expected to
* support the given interface name . THE NAME OWNER MAY CHANGE OVER
* TIME , for example between two different method calls , unless the
* name is a unique name . If you need a fixed owner , you need to
* request the current owner and bind a proxy to its unique name
* rather than to the generic name ; see
* dbus_g_proxy_new_for_name_owner ( ) .
2003-08-14 22:49:13 +00:00
*
2005-01-18 20:42:15 +00:00
* A name - associated proxy only makes sense with a message bus , not
* for app - to - app direct dbus connections .
2003-08-14 22:49:13 +00:00
*
2005-01-18 20:42:15 +00:00
* This proxy will only emit the " destroy " signal if the
* # DBusConnection is disconnected , the proxy has no remaining
* references , or the name is a unique name and its owner
* disappears . If a well - known name changes owner , the proxy will
* still be alive .
2003-09-24 02:58:14 +00:00
*
* @ param connection the connection to the remote bus
2005-01-18 20:42:15 +00:00
* @ param name any name on the message bus
* @ param path_name name of the object instance to call methods on
2003-08-14 22:49:13 +00:00
* @ param interface_name name of the interface to call methods on
* @ returns new proxy object
*/
DBusGProxy *
2005-01-18 20:42:15 +00:00
dbus_g_proxy_new_for_name ( DBusGConnection * connection ,
const char * name ,
const char * path_name ,
const char * interface_name )
2003-08-14 22:49:13 +00:00
{
DBusGProxy * proxy ;
g_return_val_if_fail ( connection ! = NULL , NULL ) ;
2005-01-18 20:42:15 +00:00
g_return_val_if_fail ( name ! = NULL , NULL ) ;
2003-09-22 03:11:12 +00:00
g_return_val_if_fail ( path_name ! = NULL , NULL ) ;
2003-08-14 22:49:13 +00:00
g_return_val_if_fail ( interface_name ! = NULL , NULL ) ;
2005-01-18 20:42:15 +00:00
proxy = dbus_g_proxy_new ( connection , name ,
2004-08-10 03:07:01 +00:00
path_name , interface_name ) ;
2003-08-14 22:49:13 +00:00
return proxy ;
}
2003-09-24 02:58:14 +00:00
/**
2005-01-18 20:42:15 +00:00
* Similar to dbus_g_proxy_new_for_name ( ) , but makes a round - trip
* request to the message bus to get the current name owner , then
* binds the proxy to the unique name of the current owner , rather
* than to the well - known name . As a result , the name owner will
* not change over time , and the proxy will emit the " destroy " signal
* when the owner disappears from the message bus .
2003-09-24 02:58:14 +00:00
*
2005-01-18 20:42:15 +00:00
* An example of the difference between dbus_g_proxy_new_for_name ( )
* and dbus_g_proxy_new_for_name_owner ( ) : if you provide the well - known name
* " org.freedesktop.Database " dbus_g_proxy_new_for_name ( ) remains bound
* to that name as it changes owner . dbus_g_proxy_new_for_name_owner ( )
* will fail if the name has no owner . If the name has an owner ,
* dbus_g_proxy_new_for_name_owner ( ) will bind to the unique name
* of that owner rather than the generic name .
2003-09-24 02:58:14 +00:00
*
* @ param connection the connection to the remote bus
2005-01-18 20:42:15 +00:00
* @ param name any name on the message bus
2003-09-24 02:58:14 +00:00
* @ param path_name name of the object inside the service to call methods on
* @ param interface_name name of the interface to call methods on
* @ param error return location for an error
* @ returns new proxy object , or # NULL on error
*/
DBusGProxy *
2005-01-18 20:42:15 +00:00
dbus_g_proxy_new_for_name_owner ( DBusGConnection * connection ,
const char * name ,
const char * path_name ,
const char * interface_name ,
GError * * error )
2003-09-24 02:58:14 +00:00
{
2004-04-15 22:08:05 +00:00
DBusGProxy * proxy ;
DBusMessage * request , * reply ;
DBusError derror ;
2005-01-18 20:42:15 +00:00
const char * unique_name ;
2005-01-15 Havoc Pennington <hp@redhat.com>
* Land the new message args API and type system.
This patch is huge, but the public API change is not
really large. The set of D-BUS types has changed somewhat,
and the arg "getters" are more geared toward language bindings;
they don't make a copy, etc.
There are also some known issues. See these emails for details
on this huge patch:
http://lists.freedesktop.org/archives/dbus/2004-December/001836.html
http://lists.freedesktop.org/archives/dbus/2005-January/001922.html
* dbus/dbus-marshal-*: all the new stuff
* dbus/dbus-message.c: basically rewritten
* dbus/dbus-memory.c (check_guards): with "guards" enabled, init
freed blocks to be all non-nul bytes so using freed memory is less
likely to work right
* dbus/dbus-internals.c (_dbus_test_oom_handling): add
DBUS_FAIL_MALLOC=N environment variable, so you can do
DBUS_FAIL_MALLOC=0 to skip the out-of-memory checking, or
DBUS_FAIL_MALLOC=10 to make it really, really, really slow and
thorough.
* qt/message.cpp: port to the new message args API
(operator<<): use str.utf8() rather than str.unicode()
(pretty sure this is right from the Qt docs?)
* glib/dbus-gvalue.c: port to the new message args API
* bus/dispatch.c, bus/driver.c: port to the new message args API
* dbus/dbus-string.c (_dbus_string_init_const_len): initialize the
"locked" flag to TRUE and align_offset to 0; I guess we never
looked at these anyhow, but seems cleaner.
* dbus/dbus-string.h (_DBUS_STRING_ALLOCATION_PADDING):
move allocation padding macro to this header; use it to implement
(_DBUS_STRING_STATIC): ability to declare a static string.
* dbus/dbus-message.c (_dbus_message_has_type_interface_member):
change to return TRUE if the interface is not set.
* dbus/dbus-string.[hc]: move the D-BUS specific validation stuff
to dbus-marshal-validate.[hc]
* dbus/dbus-marshal-basic.c (_dbus_type_to_string): move here from
dbus-internals.c
* dbus/Makefile.am: cut over from dbus-marshal.[hc]
to dbus-marshal-*.[hc]
* dbus/dbus-object-tree.c (_dbus_decompose_path): move this
function here from dbus-marshal.c
2005-01-15 07:15:38 +00:00
2003-09-24 02:58:14 +00:00
g_return_val_if_fail ( connection ! = NULL , NULL ) ;
2005-01-18 20:42:15 +00:00
g_return_val_if_fail ( name ! = NULL , NULL ) ;
2003-09-24 02:58:14 +00:00
g_return_val_if_fail ( path_name ! = NULL , NULL ) ;
g_return_val_if_fail ( interface_name ! = NULL , NULL ) ;
2004-04-15 22:08:05 +00:00
dbus_error_init ( & derror ) ;
proxy = NULL ;
2005-01-18 20:42:15 +00:00
unique_name = NULL ;
2004-04-15 22:08:05 +00:00
reply = NULL ;
request = dbus_message_new_method_call ( DBUS_SERVICE_ORG_FREEDESKTOP_DBUS ,
DBUS_PATH_ORG_FREEDESKTOP_DBUS ,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS ,
2005-01-18 20:42:15 +00:00
" GetNameOwner " ) ;
2004-04-15 22:08:05 +00:00
if ( request = = NULL )
g_error ( " Out of memory " ) ;
if ( ! dbus_message_append_args ( request ,
2005-01-18 20:42:15 +00:00
DBUS_TYPE_STRING , & name ,
2004-04-15 22:08:05 +00:00
DBUS_TYPE_INVALID ) )
g_error ( " Out of memory " ) ;
2004-06-20 15:28:15 +00:00
reply =
dbus_connection_send_with_reply_and_block ( DBUS_CONNECTION_FROM_G_CONNECTION ( connection ) ,
request ,
2000 , & derror ) ;
2004-04-15 22:08:05 +00:00
if ( reply = = NULL )
goto error ;
if ( dbus_set_error_from_message ( & derror , reply ) )
goto error ;
2003-09-24 02:58:14 +00:00
2004-04-15 22:08:05 +00:00
if ( ! dbus_message_get_args ( reply , & derror ,
2005-01-18 20:42:15 +00:00
DBUS_TYPE_STRING , & unique_name ,
2004-04-15 22:08:05 +00:00
DBUS_TYPE_INVALID ) )
goto error ;
2005-01-18 20:42:15 +00:00
proxy = dbus_g_proxy_new ( connection , unique_name ,
path_name , interface_name ) ;
2004-04-15 22:08:05 +00:00
goto out ;
error :
g_assert ( dbus_error_is_set ( & derror ) ) ;
dbus_set_g_error ( error , & derror ) ;
dbus_error_free ( & derror ) ;
out :
if ( request )
dbus_message_unref ( request ) ;
if ( reply )
dbus_message_unref ( reply ) ;
return proxy ;
2003-09-24 02:58:14 +00:00
}
/**
* Creates a proxy for an object in peer application ( one
* we ' re directly connected to ) . That is , this function is
* intended for use when there ' s no message bus involved ,
* we ' re doing a simple 1 - to - 1 communication between two
* applications .
*
*
* @ param connection the connection to the peer
* @ param path_name name of the object inside the peer to call methods on
* @ param interface_name name of the interface to call methods on
* @ returns new proxy object
*
*/
DBusGProxy *
2004-06-20 15:28:15 +00:00
dbus_g_proxy_new_for_peer ( DBusGConnection * connection ,
2005-01-18 20:42:15 +00:00
const char * path_name ,
const char * interface_name )
2003-09-24 02:58:14 +00:00
{
DBusGProxy * proxy ;
g_return_val_if_fail ( connection ! = NULL , NULL ) ;
g_return_val_if_fail ( path_name ! = NULL , NULL ) ;
g_return_val_if_fail ( interface_name ! = NULL , NULL ) ;
2004-06-20 15:28:15 +00:00
proxy = dbus_g_proxy_new ( connection , NULL ,
2005-01-30 05:18:44 +00:00
path_name , interface_name ) ;
2003-09-24 02:58:14 +00:00
return proxy ;
}
2005-01-30 05:18:44 +00:00
/**
* Gets the bus name a proxy is bound to ( may be # NULL in some cases ) .
* If you created the proxy with dbus_g_proxy_new_for_name ( ) , then
* the name you passed to that will be returned .
* If you created it with dbus_g_proxy_new_for_name_owner ( ) , then the
* unique connection name will be returned . If you created it
* with dbus_g_proxy_new_for_peer ( ) then # NULL will be returned .
*
* @ param proxy the proxy
* @ returns the bus name the proxy sends messages to
*/
const char *
dbus_g_proxy_get_bus_name ( DBusGProxy * proxy )
{
g_return_val_if_fail ( DBUS_IS_G_PROXY ( proxy ) , NULL ) ;
2005-02-05 04:15:57 +00:00
g_return_val_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) , NULL ) ;
2005-01-30 05:18:44 +00:00
return proxy - > name ;
}
2003-08-14 22:49:13 +00:00
/**
* Invokes a method on a remote interface . This function does not
2003-08-16 21:28:47 +00:00
* block ; instead it returns an opaque # DBusPendingCall object that
2003-08-14 22:49:13 +00:00
* 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 .
2003-08-16 21:28:47 +00:00
* To collect the results of the call ( which may be an error ,
2004-06-20 15:28:15 +00:00
* or a reply ) , use dbus_g_proxy_end_call ( ) .
2003-08-14 22:49:13 +00:00
*
2003-09-17 03:52:07 +00:00
* @ todo this particular function shouldn ' t die on out of memory ,
* since you should be able to do a call with large arguments .
*
2003-08-14 22:49:13 +00:00
* @ param proxy a proxy for a remote interface
* @ param method the name of the method to invoke
* @ param first_arg_type type of the first argument
*
* @ returns opaque pending call object
2003-09-17 03:52:07 +00:00
* */
2004-06-20 15:28:15 +00:00
DBusGPendingCall *
dbus_g_proxy_begin_call ( DBusGProxy * proxy ,
2003-08-14 22:49:13 +00:00
const char * method ,
int first_arg_type ,
. . . )
{
2003-09-17 03:52:07 +00:00
DBusPendingCall * pending ;
DBusMessage * message ;
va_list args ;
2004-06-20 15:28:15 +00:00
g_return_val_if_fail ( DBUS_IS_G_PROXY ( proxy ) , NULL ) ;
2005-02-05 04:15:57 +00:00
g_return_val_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) , NULL ) ;
2003-08-16 21:28:47 +00:00
2005-01-18 20:42:15 +00:00
message = dbus_message_new_method_call ( proxy - > name ,
2003-09-17 03:52:07 +00:00
proxy - > path ,
2003-09-21 19:53:56 +00:00
proxy - > interface ,
2003-09-17 03:52:07 +00:00
method ) ;
if ( message = = NULL )
goto oom ;
va_start ( args , first_arg_type ) ;
if ( ! dbus_message_append_args_valist ( message , first_arg_type ,
args ) )
goto oom ;
va_end ( args ) ;
2003-09-22 23:50:52 +00:00
if ( ! dbus_connection_send_with_reply ( proxy - > manager - > connection ,
2003-09-17 03:52:07 +00:00
message ,
& pending ,
- 1 ) )
goto oom ;
2004-06-20 15:28:15 +00:00
return DBUS_G_PENDING_CALL_FROM_PENDING_CALL ( pending ) ;
2003-09-17 03:52:07 +00:00
oom :
/* FIXME we should create a pending call that's
* immediately completed with an error status without
* ever going on the wire .
*/
g_error ( " Out of memory " ) ;
return NULL ;
2003-08-16 21:28:47 +00:00
}
/**
* Collects the results of a method call . The method call was normally
2004-06-20 15:28:15 +00:00
* initiated with dbus_g_proxy_end_call ( ) . This function will block if
2003-08-16 21:28:47 +00:00
* the results haven ' t yet been received ; use
2005-01-30 23:06:32 +00:00
* 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 .
2003-08-16 21:28:47 +00:00
*
* If the call results in an error , the error is set as normal for
* GError and the function returns # FALSE .
*
* Otherwise , the " out " parameters and return value of the
* method are stored in the provided varargs list .
2005-01-30 05:18:44 +00:00
* The list should be terminated with # DBUS_TYPE_INVALID .
2003-08-16 21:28:47 +00:00
*
2003-09-17 03:52:07 +00:00
* This function doesn ' t affect the reference count of the
2005-01-30 23:06:32 +00:00
* # DBusGPendingCall , the caller of dbus_g_proxy_begin_call ( ) still owns
2003-09-17 03:52:07 +00:00
* a reference .
*
2005-01-30 05:18:44 +00:00
* @ todo this should be changed to make a g_malloc ( ) copy of the
* data returned probably ; right now the data vanishes
* when you free the PendingCall which is sort of strange .
*
2003-08-16 21:28:47 +00:00
* @ param proxy a proxy for a remote interface
2004-06-20 15:28:15 +00:00
* @ param pending the pending call from dbus_g_proxy_begin_call ( )
2003-08-16 21:28:47 +00:00
* @ param error return location for an error
* @ param first_arg_type type of first " out " argument
2005-01-30 05:18:44 +00:00
* @ returns # FALSE if an error is set
*/
2003-08-16 21:28:47 +00:00
gboolean
2004-06-20 15:28:15 +00:00
dbus_g_proxy_end_call ( DBusGProxy * proxy ,
2005-01-30 05:18:44 +00:00
DBusGPendingCall * pending ,
GError * * error ,
int first_arg_type ,
. . . )
2003-08-16 21:28:47 +00:00
{
2003-09-17 03:52:07 +00:00
DBusMessage * message ;
va_list args ;
DBusError derror ;
2004-06-20 15:28:15 +00:00
g_return_val_if_fail ( DBUS_IS_G_PROXY ( proxy ) , FALSE ) ;
2005-02-05 04:15:57 +00:00
g_return_val_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) , FALSE ) ;
2003-09-17 03:52:07 +00:00
g_return_val_if_fail ( pending ! = NULL , FALSE ) ;
2003-08-16 21:28:47 +00:00
2004-06-20 15:28:15 +00:00
dbus_pending_call_block ( DBUS_PENDING_CALL_FROM_G_PENDING_CALL ( pending ) ) ;
message = dbus_pending_call_get_reply ( DBUS_PENDING_CALL_FROM_G_PENDING_CALL ( pending ) ) ;
2003-09-17 03:52:07 +00:00
g_assert ( message ! = NULL ) ;
dbus_error_init ( & derror ) ;
2003-10-16 Havoc Pennington <hp@redhat.com>
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess
* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received
* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak
* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.
* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set
* dbus/dbus-internals.c: add pid to assertion failure messages
* dbus/dbus-connection.c: add message type code to the debug spew
* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo
* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead
* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate
* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct
* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)
* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR
* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing
* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused
* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.
2003-10-16 06:34:51 +00:00
switch ( dbus_message_get_type ( message ) )
2003-09-17 03:52:07 +00:00
{
2003-10-16 Havoc Pennington <hp@redhat.com>
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess
* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received
* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak
* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.
* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set
* dbus/dbus-internals.c: add pid to assertion failure messages
* dbus/dbus-connection.c: add message type code to the debug spew
* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo
* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead
* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate
* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct
* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)
* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR
* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing
* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused
* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.
2003-10-16 06:34:51 +00:00
case DBUS_MESSAGE_TYPE_METHOD_RETURN :
va_start ( args , first_arg_type ) ;
if ( ! dbus_message_get_args_valist ( message , & derror , first_arg_type , args ) )
{
va_end ( args ) ;
goto error ;
}
2003-09-17 03:52:07 +00:00
va_end ( args ) ;
2003-10-16 Havoc Pennington <hp@redhat.com>
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess
* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received
* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak
* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.
* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set
* dbus/dbus-internals.c: add pid to assertion failure messages
* dbus/dbus-connection.c: add message type code to the debug spew
* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo
* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead
* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate
* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct
* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)
* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR
* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing
* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused
* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.
2003-10-16 06:34:51 +00:00
return TRUE ;
case DBUS_MESSAGE_TYPE_ERROR :
dbus_set_error_from_message ( & derror , message ) ;
2003-09-17 03:52:07 +00:00
goto error ;
2003-10-16 Havoc Pennington <hp@redhat.com>
* bus/connection.c (bus_pending_reply_expired): either cancel or
execute, not both
(bus_connections_check_reply): use unlink, not remove_link, as we
don't want to free the link; fixes double free mess
* dbus/dbus-pending-call.c (dbus_pending_call_block): fix in case
where no reply was received
* dbus/dbus-connection.c (_dbus_pending_call_complete_and_unlock):
fix a refcount leak
* bus/signals.c (match_rule_matches): add special cases for the
bus driver, so you can match on sender/destination for it.
* dbus/dbus-sysdeps.c (_dbus_abort): print backtrace if
DBUS_PRINT_BACKTRACE is set
* dbus/dbus-internals.c: add pid to assertion failure messages
* dbus/dbus-connection.c: add message type code to the debug spew
* glib/dbus-gproxy.c (gproxy_get_match_rule): match rules want
sender=foo not service=foo
* dbus/dbus-bus.c (dbus_bus_get): if the activation bus is the
session bus but DBUS_SESSION_BUS_ADDRESS isn't set, use
DBUS_ACTIVATION_ADDRESS instead
* bus/activation.c: set DBUS_SESSION_BUS_ADDRESS,
DBUS_SYSTEM_BUS_ADDRESS if appropriate
* bus/bus.c (bus_context_new): handle OOM copying bus type into
context struct
* dbus/dbus-message.c (dbus_message_iter_get_object_path): new function
(dbus_message_iter_get_object_path_array): new function (half
finished, disabled for the moment)
* glib/dbus-gproxy.c (dbus_gproxy_end_call): properly handle
DBUS_MESSAGE_TYPE_ERROR
* tools/dbus-launch.c (babysit): support DBUS_DEBUG_OUTPUT to
avoid redirecting stderr to /dev/null
(babysit): close stdin if not doing the "exit_with_session" thing
* dbus/dbus-sysdeps.c (_dbus_become_daemon): delete some leftover
debug code; change DBUS_DEBUG_OUTPUT to only enable stderr, not
stdout/stdin, so things don't get confused
* bus/system.conf.in: fix to allow replies, I modified .conf
instead of .conf.in again.
2003-10-16 06:34:51 +00:00
default :
dbus_set_error ( & derror , DBUS_ERROR_FAILED ,
" Reply was neither a method return nor an exception " ) ;
goto error ;
}
2003-09-17 03:52:07 +00:00
error :
dbus_set_g_error ( error , & derror ) ;
dbus_error_free ( & derror ) ;
return FALSE ;
2003-08-16 21:28:47 +00:00
}
2003-09-23 23:47:09 +00:00
/**
2004-06-20 15:28:15 +00:00
* Sends a method call message as with dbus_g_proxy_begin_call ( ) , but
2003-09-23 23:47:09 +00:00
* does not ask for a reply or allow you to receive one .
*
* @ 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 first_arg_type type of the first argument
*/
void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_call_no_reply ( DBusGProxy * proxy ,
2003-10-03 03:55:35 +00:00
const char * method ,
int first_arg_type ,
. . . )
2003-09-23 23:47:09 +00:00
{
DBusMessage * message ;
va_list args ;
2004-06-20 15:28:15 +00:00
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-09-23 23:47:09 +00:00
2005-01-18 20:42:15 +00:00
message = dbus_message_new_method_call ( proxy - > name ,
2003-09-23 23:47:09 +00:00
proxy - > path ,
proxy - > interface ,
method ) ;
if ( message = = NULL )
goto oom ;
dbus_message_set_no_reply ( message , TRUE ) ;
va_start ( args , first_arg_type ) ;
if ( ! dbus_message_append_args_valist ( message , first_arg_type ,
args ) )
goto oom ;
va_end ( args ) ;
if ( ! dbus_connection_send ( proxy - > manager - > connection ,
message ,
NULL ) )
goto oom ;
2003-10-21 05:46:52 +00:00
return ;
2003-09-23 23:47:09 +00:00
oom :
g_error ( " Out of memory " ) ;
}
2003-08-16 21:28:47 +00:00
/**
* 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
* when you return to the main loop or block in
* dbus_connection_flush ( ) .
*
* The message is modified to be addressed to the target interface .
2005-01-18 20:42:15 +00:00
* That is , a destination name field or whatever is needed will be
2003-09-17 03:52:07 +00:00
* added to the message . The basic point of this function is to add
* the necessary header fields , otherwise it ' s equivalent to
* dbus_connection_send ( ) .
2003-08-16 21:28:47 +00:00
*
* This function adds a reference to the message , so the caller
* still owns its original reference .
*
* @ param proxy a proxy for a remote interface
* @ param message the message to address and send
2003-09-17 03:52:07 +00:00
* @ param client_serial return location for message ' s serial , or # NULL */
2003-08-16 21:28:47 +00:00
void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_send ( DBusGProxy * proxy ,
2005-01-31 02:55:12 +00:00
DBusMessage * message ,
dbus_uint32_t * client_serial )
2003-08-16 21:28:47 +00:00
{
2004-06-20 15:28:15 +00:00
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-08-14 22:49:13 +00:00
2005-01-18 20:42:15 +00:00
if ( proxy - > name )
2003-08-16 21:28:47 +00:00
{
2005-01-18 20:42:15 +00:00
if ( ! dbus_message_set_destination ( message , proxy - > name ) )
2003-09-17 03:52:07 +00:00
g_error ( " Out of memory " ) ;
2003-08-16 21:28:47 +00:00
}
2003-09-22 03:11:12 +00:00
if ( proxy - > path )
2003-08-16 21:28:47 +00:00
{
2003-09-22 03:11:12 +00:00
if ( ! dbus_message_set_path ( message , proxy - > path ) )
2003-09-17 03:52:07 +00:00
g_error ( " Out of memory " ) ;
2003-08-16 21:28:47 +00:00
}
2003-09-22 03:11:12 +00:00
if ( proxy - > interface )
2003-08-16 21:28:47 +00:00
{
2003-09-22 03:11:12 +00:00
if ( ! dbus_message_set_interface ( message , proxy - > interface ) )
2003-09-17 03:52:07 +00:00
g_error ( " Out of memory " ) ;
2003-08-16 21:28:47 +00:00
}
2003-09-17 03:52:07 +00:00
2003-09-22 23:50:52 +00:00
if ( ! dbus_connection_send ( proxy - > manager - > connection , message , client_serial ) )
2003-08-16 21:28:47 +00:00
g_error ( " Out of memory \n " ) ;
2003-08-14 22:49:13 +00:00
}
2005-01-31 02:55:12 +00:00
/**
* Specifies the signature of a signal , such that it ' s possible to
* connect to the signal on this proxy .
*
* @ param proxy the proxy for a remote interface
* @ param signal_name the name of the signal
* @ param signature D - BUS signature of the signal
*/
void
dbus_g_proxy_add_signal ( DBusGProxy * proxy ,
const char * signal_name ,
const char * signature )
{
2005-01-31 23:17:19 +00:00
GQuark q ;
char * name ;
2005-01-31 02:55:12 +00:00
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2005-01-31 02:55:12 +00:00
g_return_if_fail ( signal_name ! = NULL ) ;
g_return_if_fail ( signature ! = NULL ) ;
2005-01-31 23:17:19 +00:00
# ifndef G_DISABLE_CHECKS
if ( lookup_g_marshaller ( proxy , signature ) = = NULL )
g_warning ( " No marshaller for signature '%s', we need to add API for providing your own " ,
signature ) ;
# endif
name = create_signal_name ( proxy - > interface , signal_name ) ;
q = g_quark_from_string ( name ) ;
g_return_if_fail ( g_datalist_id_get_data ( & proxy - > signal_signatures , q ) = = NULL ) ;
g_datalist_id_set_data_full ( & proxy - > signal_signatures ,
q , g_strdup ( signature ) ,
g_free ) ;
2005-01-31 02:55:12 +00:00
2005-01-31 23:17:19 +00:00
g_free ( name ) ;
2005-01-31 02:55:12 +00:00
}
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
/**
* Connect a signal handler to a proxy for a remote interface . When
* the remote interface emits the specified signal , the proxy will
* emit a corresponding GLib signal .
*
* @ param proxy a proxy for a remote interface
* @ param signal_name the DBus signal name to listen for
* @ param handler the handler to connect
* @ param data data to pass to handler
* @ param free_data_func callback function to destroy data
*/
2003-09-23 05:04:51 +00:00
void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_connect_signal ( DBusGProxy * proxy ,
2005-01-31 02:55:12 +00:00
const char * signal_name ,
GCallback handler ,
void * data ,
GClosureNotify free_data_func )
2003-09-23 05:04:51 +00:00
{
2005-01-31 02:55:12 +00:00
char * name ;
2005-01-31 23:17:19 +00:00
GClosure * closure ;
GQuark q ;
2003-09-23 05:04:51 +00:00
2004-06-20 15:28:15 +00:00
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-09-23 23:47:09 +00:00
g_return_if_fail ( signal_name ! = NULL ) ;
g_return_if_fail ( handler ! = NULL ) ;
2005-01-31 02:55:12 +00:00
name = create_signal_name ( proxy - > interface , signal_name ) ;
2003-09-23 05:04:51 +00:00
2005-02-05 04:15:57 +00:00
q = g_quark_try_string ( name ) ;
2005-01-31 23:17:19 +00:00
# ifndef G_DISABLE_CHECKS
2005-02-05 04:15:57 +00:00
if ( q = = 0 | | g_datalist_id_get_data ( & proxy - > signal_signatures , q ) = = NULL )
2005-01-31 02:55:12 +00:00
{
2005-01-31 23:17:19 +00:00
g_warning ( " Must add the signal '%s' with dbus_g_proxy_add_signal() prior to connecting to it \n " , name ) ;
g_free ( name ) ;
return ;
2005-01-31 02:55:12 +00:00
}
2005-01-31 23:17:19 +00:00
# endif
closure = g_cclosure_new ( G_CALLBACK ( handler ) , data , free_data_func ) ;
g_signal_connect_closure_by_id ( G_OBJECT ( proxy ) ,
signals [ RECEIVED ] ,
q ,
closure , FALSE ) ;
2005-01-31 02:55:12 +00:00
g_free ( name ) ;
2003-09-23 05:04:51 +00:00
}
2004-06-02 Kristian Høgsberg <krh@redhat.com>
* glib/dbus-gproxy.c, glib/dbus-gmain.c, dbus/dbus-string.c,
dbus/dbus-object-tree.c, dbus/dbus-message.c: add comments to
quiet doxygen.
* Doxyfile.in: remove deprecated options.
* dbus/dbus-message-handler.c, dbus/dbus-message-handler.h,
glib/test-thread.h, glib/test-thread-client.c,
glib/test-thread-server.c, glib/test-profile.c,
glib/test-dbus-glib.c: remove these unused files.
2004-06-02 13:13:14 +00:00
/**
* Disconnect all signal handlers from a proxy that match the given
* criteria .
*
* @ param proxy a proxy for a remote interface
* @ param signal_name the DBus signal name to disconnect
* @ param handler the handler to disconnect
* @ param data the data that was registered with handler
*/
2003-09-23 05:04:51 +00:00
void
2004-06-20 15:28:15 +00:00
dbus_g_proxy_disconnect_signal ( DBusGProxy * proxy ,
2005-01-31 02:55:12 +00:00
const char * signal_name ,
GCallback handler ,
void * data )
2003-09-23 05:04:51 +00:00
{
2005-01-31 02:55:12 +00:00
char * name ;
2005-01-31 23:17:19 +00:00
GQuark q ;
2003-09-23 05:04:51 +00:00
2004-06-20 15:28:15 +00:00
g_return_if_fail ( DBUS_IS_G_PROXY ( proxy ) ) ;
2005-02-05 04:15:57 +00:00
g_return_if_fail ( ! DBUS_G_PROXY_DESTROYED ( proxy ) ) ;
2003-09-23 23:47:09 +00:00
g_return_if_fail ( signal_name ! = NULL ) ;
g_return_if_fail ( handler ! = NULL ) ;
2005-01-31 02:55:12 +00:00
name = create_signal_name ( proxy - > interface , signal_name ) ;
2003-09-23 23:47:09 +00:00
2005-02-05 04:15:57 +00:00
q = g_quark_try_string ( name ) ;
2005-01-31 23:17:19 +00:00
if ( q ! = 0 )
2003-09-23 23:47:09 +00:00
{
2005-01-31 02:55:12 +00:00
g_signal_handlers_disconnect_matched ( G_OBJECT ( proxy ) ,
G_SIGNAL_MATCH_DETAIL |
G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA ,
2005-01-31 23:17:19 +00:00
signals [ RECEIVED ] ,
q ,
2005-01-31 02:55:12 +00:00
NULL ,
G_CALLBACK ( handler ) , data ) ;
}
else
{
g_warning ( " Attempt to disconnect from signal '%s' which is not registered \n " ,
name ) ;
2003-09-23 23:47:09 +00:00
}
2005-01-31 02:55:12 +00:00
g_free ( name ) ;
2003-09-23 05:04:51 +00:00
}
2003-08-14 22:49:13 +00:00
/** @} End of DBusGLib public */
# ifdef DBUS_BUILD_TESTS
/**
* @ ingroup DBusGLibInternals
* Unit test for GLib proxy functions
* @ returns # TRUE on success .
*/
2004-06-20 15:28:15 +00:00
gboolean
_dbus_g_proxy_test ( void )
2003-08-14 22:49:13 +00:00
{
2003-09-24 02:58:14 +00:00
2003-08-14 22:49:13 +00:00
return TRUE ;
}
# endif /* DBUS_BUILD_TESTS */