2004-03-23 12:10:32 +00:00
|
|
|
namespace DBus
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Collections;
|
2004-03-26 15:25:59 +00:00
|
|
|
using System.Threading;
|
2004-03-23 12:10:32 +00:00
|
|
|
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();
|
2004-03-26 15:25:59 +00:00
|
|
|
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;
|
2004-03-23 12:10:32 +00:00
|
|
|
|
2005-02-10 23:01:28 +00:00
|
|
|
// Add a match for signals. FIXME: Can we filter the service?
|
|
|
|
|
private const string MatchRule = "type='signal'";
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
internal Service(string name, Connection connection)
|
|
|
|
|
{
|
|
|
|
|
this.name = name;
|
|
|
|
|
this.connection = connection;
|
2004-03-26 15:25:59 +00:00
|
|
|
AddFilter();
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Service(Connection connection, string name)
|
|
|
|
|
{
|
|
|
|
|
Error error = new Error();
|
|
|
|
|
error.Init();
|
|
|
|
|
|
|
|
|
|
// This isn't used for now
|
|
|
|
|
uint flags = 0;
|
|
|
|
|
|
2005-01-25 19:47:13 +00:00
|
|
|
if (dbus_bus_request_name (connection.RawConnection, name, flags, ref error) == -1) {
|
2004-03-23 12:10:32 +00:00
|
|
|
throw new DBusException(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.connection = connection;
|
|
|
|
|
this.name = name;
|
|
|
|
|
this.local = true;
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-10 23:01:28 +00:00
|
|
|
~Service ()
|
|
|
|
|
{
|
|
|
|
|
if (this.filterCalled != null)
|
|
|
|
|
RemoveFilter ();
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-25 19:47:13 +00:00
|
|
|
public static bool HasOwner(Connection connection, string name)
|
2004-03-23 12:10:32 +00:00
|
|
|
{
|
|
|
|
|
Error error = new Error();
|
|
|
|
|
error.Init();
|
|
|
|
|
|
2005-01-25 19:47:13 +00:00
|
|
|
if (dbus_bus_name_has_owner(connection.RawConnection,
|
2004-03-23 12:10:32 +00:00
|
|
|
name,
|
|
|
|
|
ref error)) {
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
if (error.IsSet) {
|
|
|
|
|
throw new DBusException(error);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Service Get(Connection connection, string name)
|
|
|
|
|
{
|
2005-01-25 19:47:13 +00:00
|
|
|
if (HasOwner(connection, name)) {
|
2004-03-23 12:10:32 +00:00
|
|
|
return new Service(name, connection);
|
|
|
|
|
} else {
|
2005-01-25 19:47:13 +00:00
|
|
|
throw new ApplicationException("Name '" + name + "' does not exist.");
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-23 21:33:14 +00:00
|
|
|
public void UnregisterObject(object handledObject)
|
|
|
|
|
{
|
|
|
|
|
Handler handler = (Handler) registeredHandlers[handledObject];
|
|
|
|
|
registeredHandlers.Remove(handledObject);
|
|
|
|
|
handler.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
public void RegisterObject(object handledObject,
|
|
|
|
|
string pathName)
|
|
|
|
|
{
|
2004-03-26 15:25:59 +00:00
|
|
|
Handler handler = new Handler(handledObject, pathName, this);
|
2004-03-23 12:10:32 +00:00
|
|
|
registeredHandlers.Add(handledObject, handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal Handler GetHandler(object handledObject)
|
|
|
|
|
{
|
2004-03-24 13:15:20 +00:00
|
|
|
if (!registeredHandlers.Contains(handledObject)) {
|
|
|
|
|
throw new ArgumentException("No handler registered for object: " + handledObject);
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
return (Handler) registeredHandlers[handledObject];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public object GetObject(Type type, string pathName)
|
|
|
|
|
{
|
|
|
|
|
ProxyBuilder builder = new ProxyBuilder(this, type, pathName);
|
|
|
|
|
object proxy = builder.GetProxy();
|
|
|
|
|
return proxy;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-26 15:25:59 +00:00
|
|
|
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();
|
|
|
|
|
|
2005-02-10 23:01:28 +00:00
|
|
|
dbus_bus_add_match(connection.RawConnection, MatchRule, IntPtr.Zero);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveFilter()
|
|
|
|
|
{
|
|
|
|
|
dbus_connection_remove_filter (Connection.RawConnection,
|
|
|
|
|
this.filterCalled,
|
|
|
|
|
IntPtr.Zero);
|
|
|
|
|
this.filterCalled = null;
|
|
|
|
|
|
|
|
|
|
dbus_bus_remove_match (connection.RawConnection, MatchRule, IntPtr.Zero);
|
2004-03-26 15:25:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
2004-08-31 03:59:14 +00:00
|
|
|
Message.Push (message);
|
2004-03-26 15:25:59 +00:00
|
|
|
SignalCalled(signal);
|
2004-08-31 03:59:14 +00:00
|
|
|
Message.Pop ();
|
2004-03-26 15:25:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (int) Result.NotYetHandled;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
public string Name
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Connection Connection
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.connection = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-26 15:25:59 +00:00
|
|
|
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) {
|
2004-04-03 22:00:40 +00:00
|
|
|
this.module = ProxyAssembly.DefineDynamicModule(Name, Name + ".proxy.dll", true);
|
2004-03-26 15:25:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.module;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DllImport("dbus-1")]
|
2005-01-25 19:47:13 +00:00
|
|
|
private extern static int dbus_bus_request_name(IntPtr rawConnection,
|
|
|
|
|
string serviceName,
|
|
|
|
|
uint flags, ref Error error);
|
2004-03-26 15:25:59 +00:00
|
|
|
|
|
|
|
|
[DllImport("dbus-1")]
|
2005-01-25 19:47:13 +00:00
|
|
|
private extern static bool dbus_bus_name_has_owner(IntPtr rawConnection,
|
2004-03-26 15:25:59 +00:00
|
|
|
string serviceName,
|
|
|
|
|
ref Error error);
|
|
|
|
|
|
|
|
|
|
[DllImport("dbus-1")]
|
|
|
|
|
private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
|
|
|
|
|
DBusHandleMessageFunction filter,
|
|
|
|
|
IntPtr userData,
|
|
|
|
|
IntPtr freeData);
|
|
|
|
|
|
2005-02-10 23:01:28 +00:00
|
|
|
[DllImport("dbus-1")]
|
|
|
|
|
private extern static void dbus_connection_remove_filter(IntPtr rawConnection,
|
|
|
|
|
DBusHandleMessageFunction filter,
|
|
|
|
|
IntPtr userData);
|
|
|
|
|
|
2004-03-26 15:25:59 +00:00
|
|
|
[DllImport("dbus-1")]
|
|
|
|
|
private extern static void dbus_bus_add_match(IntPtr rawConnection,
|
|
|
|
|
string rule,
|
|
|
|
|
IntPtr erro);
|
2004-03-23 12:10:32 +00:00
|
|
|
|
2005-02-10 23:01:28 +00:00
|
|
|
[DllImport("dbus-1")]
|
|
|
|
|
private extern static void dbus_bus_remove_match(IntPtr rawConnection,
|
|
|
|
|
string rule,
|
|
|
|
|
IntPtr erro);
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
}
|