dbus/mono/Service.cs
Joe Shaw b0002eb697 2005-01-25 Joe Shaw <joeshaw@novell.com>
* Land the mono binding changes to conform to the new APIs.

	* mono/Makefile.am: Remove Custom.cs, DBusType/Custom.cs,
	DBusType/Dict.cs, and DBusType/Nil.cs from the build.

	* mono/Arguments.cs (GetCodeAsString): Added.  Returns the dbus
	type code as a string.
	(InitAppending): Rename dbus_message_append_iter_init() to
	dbus_message_iter_init_append().

	* mono/BusDriver.cs: Rename ServiceEventHandler to
	NameOwnerChangedHandler.  Rename GetServiceOwner to GetOwner.
	Rename ServiceOwnerChanged to NameOwnerChanged.

	* mono/Connection.cs: Rename BaseService to UniqueName, and the
	underlying C call.

	* mono/Custom.cs: Removed.  The CUSTOM type has been removed.

	* mono/Service.cs: Rename Exists to HasOwner, internally rename
	dbus_bus_acquire_service() to dbus_bus_request_name().

	* mono/DBusType/Array.cs (ctor): Use Type.GetElementType() instead
	of Type.UnderlyingSystemType to get the correct element type for
	the array.
	(ctor): Update code for new APIs: use dbus_message_iter_recurse(),
	dbus_message_get_{element|arg}_type() instead of
	dbus_message_iter_init_array_iterator().
	(Append): Replace dbus_message_iter_append_array() with
	dbus_message_iter_open_container() and
	dbus_message_iter_close_container().

	* mono/DBusType/Custom.cs, mono/DBusType/Nil.cs: Removed.  These
	types have been removed.

	* mono/DBusType/*.cs: Replace calls of
	dbus_message_iter_get_[type]() to dbus_message_iter_get_basic(),
	but specify the type in the DllImport extern declaration.  Ditto
	for dbus_message_iter_append_[type]() ->
	dbus_message_iter_append_basic().

	* mono/example/BusListener.cs: Update for ServiceEventHandler ->
	NameOwnerChangedHandler.
2005-01-25 19:47:13 +00:00

208 lines
5.2 KiB
C#

namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
public class Service
{
private Connection connection;
private string name;
private bool local = false;
private Hashtable registeredHandlers = new Hashtable();
private delegate int DBusHandleMessageFunction(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData);
private DBusHandleMessageFunction filterCalled;
public delegate void SignalCalledHandler(Signal signal);
public event SignalCalledHandler SignalCalled;
private static AssemblyBuilder proxyAssembly;
private ModuleBuilder module = null;
internal Service(string name, Connection connection)
{
this.name = name;
this.connection = connection;
AddFilter();
}
public Service(Connection connection, string name)
{
Error error = new Error();
error.Init();
// This isn't used for now
uint flags = 0;
if (dbus_bus_request_name (connection.RawConnection, name, flags, ref error) == -1) {
throw new DBusException(error);
}
this.connection = connection;
this.name = name;
this.local = true;
}
public static bool HasOwner(Connection connection, string name)
{
Error error = new Error();
error.Init();
if (dbus_bus_name_has_owner(connection.RawConnection,
name,
ref error)) {
return true;
} else {
if (error.IsSet) {
throw new DBusException(error);
}
return false;
}
}
public static Service Get(Connection connection, string name)
{
if (HasOwner(connection, name)) {
return new Service(name, connection);
} else {
throw new ApplicationException("Name '" + name + "' does not exist.");
}
}
public void UnregisterObject(object handledObject)
{
Handler handler = (Handler) registeredHandlers[handledObject];
registeredHandlers.Remove(handledObject);
handler.Dispose();
}
public void RegisterObject(object handledObject,
string pathName)
{
Handler handler = new Handler(handledObject, pathName, this);
registeredHandlers.Add(handledObject, handler);
}
internal Handler GetHandler(object handledObject)
{
if (!registeredHandlers.Contains(handledObject)) {
throw new ArgumentException("No handler registered for object: " + handledObject);
}
return (Handler) registeredHandlers[handledObject];
}
public object GetObject(Type type, string pathName)
{
ProxyBuilder builder = new ProxyBuilder(this, type, pathName);
object proxy = builder.GetProxy();
return proxy;
}
private void AddFilter()
{
// Setup the filter function
this.filterCalled = new DBusHandleMessageFunction(Service_FilterCalled);
if (!dbus_connection_add_filter(Connection.RawConnection,
this.filterCalled,
IntPtr.Zero,
IntPtr.Zero))
throw new OutOfMemoryException();
// Add a match for signals. FIXME: Can we filter the service?
string rule = "type='signal'";
dbus_bus_add_match(connection.RawConnection, rule, IntPtr.Zero);
}
private int Service_FilterCalled(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData)
{
Message message = Message.Wrap(rawMessage, this);
if (message.Type == Message.MessageType.Signal) {
// We're only interested in signals
Signal signal = (Signal) message;
if (SignalCalled != null) {
Message.Push (message);
SignalCalled(signal);
Message.Pop ();
}
}
return (int) Result.NotYetHandled;
}
public string Name
{
get
{
return this.name;
}
}
public Connection Connection
{
get
{
return connection;
}
set
{
this.connection = value;
}
}
internal AssemblyBuilder ProxyAssembly
{
get {
if (proxyAssembly == null){
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "DBusProxy";
proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave);
}
return proxyAssembly;
}
}
internal ModuleBuilder Module
{
get {
if (this.module == null) {
this.module = ProxyAssembly.DefineDynamicModule(Name, Name + ".proxy.dll", true);
}
return this.module;
}
}
[DllImport("dbus-1")]
private extern static int dbus_bus_request_name(IntPtr rawConnection,
string serviceName,
uint flags, ref Error error);
[DllImport("dbus-1")]
private extern static bool dbus_bus_name_has_owner(IntPtr rawConnection,
string serviceName,
ref Error error);
[DllImport("dbus-1")]
private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
DBusHandleMessageFunction filter,
IntPtr userData,
IntPtr freeData);
[DllImport("dbus-1")]
private extern static void dbus_bus_add_match(IntPtr rawConnection,
string rule,
IntPtr erro);
}
}