diff options
| -rw-r--r-- | gdbus/object.c | 78 | 
1 files changed, 65 insertions, 13 deletions
| diff --git a/gdbus/object.c b/gdbus/object.c index 738a6385..bc3ea5e7 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -46,9 +46,15 @@ struct generic_data {  struct interface_data {  	char *name; -	DBusMethodVTable *methods; -	DBusSignalVTable *signals; -	DBusPropertyVTable *properties; +	GDBusMethodTable *methods; +	GDBusSignalTable *signals; +	GDBusPropertyTable *properties; +	void *user_data; +	GDBusDestroyFunction destroy; + +	DBusMethodVTable *old_methods; +	DBusSignalVTable *old_signals; +	DBusPropertyVTable *old_properties;  };  DBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection, @@ -143,7 +149,7 @@ static void generate_introspection_xml(DBusConnection *conn,  		g_string_append_printf(gstr, "\t<interface name=\"%s\">\n", iface->name); -		for (method = iface->methods; method && method->name; method++) { +		for (method = iface->old_methods; method && method->name; method++) {  			/* debug("%s: adding method %s.%s",  					path, iface->name, method->name); */  			if (!strlen(method->signature) && !strlen(method->reply)) @@ -158,7 +164,7 @@ static void generate_introspection_xml(DBusConnection *conn,  			}  		} -		for (signal = iface->signals; signal && signal->name; signal++) { +		for (signal = iface->old_signals; signal && signal->name; signal++) {  			/* debug("%s: adding signal %s.%s",  					path, iface->name, signal->name); */  			if (!strlen(signal->signature)) @@ -172,7 +178,7 @@ static void generate_introspection_xml(DBusConnection *conn,  			}  		} -		for (property = iface->properties; property && property->name; property++) { +		for (property = iface->old_properties; property && property->name; property++) {  			debug("%s: adding property %s.%s",  					path, iface->name, property->name);  		} @@ -262,7 +268,7 @@ static DBusHandlerResult generic_message(DBusConnection *connection,  	if (!iface)  		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -	for (current = iface->methods; +	for (current = iface->old_methods;  			current->name && current->message_function; current++) {  		if (!dbus_message_is_method_call(message, iface->name,  							current->name)) @@ -379,9 +385,9 @@ dbus_bool_t dbus_connection_register_interface(DBusConnection *connection,  	iface = g_new0(struct interface_data, 1);  	iface->name = g_strdup(name); -	iface->methods = methods; -	iface->signals = signals; -	iface->properties = properties; +	iface->old_methods = methods; +	iface->old_signals = signals; +	iface->old_properties = properties;  	data->interfaces = g_slist_append(data->interfaces, iface); @@ -548,7 +554,7 @@ static gboolean check_signal(DBusConnection *conn, const char *path,  		return FALSE;  	} -	for (sig_data = iface->signals; sig_data && sig_data->name; sig_data++) { +	for (sig_data = iface->old_signals; sig_data && sig_data->name; sig_data++) {  		if (!strcmp(sig_data->name, name)) {  			*args = sig_data->signature;  			break; @@ -667,11 +673,57 @@ gboolean g_dbus_register_interface(DBusConnection *connection,  					void *user_data,  					GDBusDestroyFunction destroy)  { -	return FALSE; +	struct generic_data *data = NULL; +	struct interface_data *iface; + +	if (!dbus_connection_get_object_path_data(connection, path, +						(void *) &data) || !data) +		return FALSE; + +	if (find_interface(data->interfaces, name)) +		return FALSE; + +	iface = g_new0(struct interface_data, 1); + +	iface->name = g_strdup(name); +	iface->methods = methods; +	iface->signals = signals; +	iface->properties = properties; +	iface->user_data = user_data; +	iface->destroy = destroy; + +	data->interfaces = g_slist_append(data->interfaces, iface); + +	g_free(data->introspect); +	data->introspect = NULL; + +	return TRUE;  }  gboolean g_dbus_unregister_interface(DBusConnection *connection,  					const char *path, const char *name)  { -	return FALSE; +	struct generic_data *data = NULL; +	struct interface_data *iface; + +	if (!dbus_connection_get_object_path_data(connection, path, +						(void *) &data) || !data) +		return FALSE; + +	iface = find_interface(data->interfaces, name); +	if (!iface) +		return FALSE; + +	data->interfaces = g_slist_remove(data->interfaces, iface); + +	if (iface->destroy) +		iface->destroy(iface->user_data); + +	g_free(iface->name); +	g_free(iface); + +	g_free(data->introspect); +	data->introspect = NULL; + +	return TRUE;  } | 
