1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
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 DBusHandleMessageFunction filterCalled;
public delegate void SignalCalledHandler(Signal signal);
public event SignalCalledHandler SignalCalled;
private static AssemblyBuilder proxyAssembly;
private ModuleBuilder module = null;
// Add a match for signals. FIXME: Can we filter the service?
private const string MatchRule = "type='signal'";
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)
{
registeredHandlers.Remove(handledObject);
}
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);
Connection.AddFilter (this.filterCalled);
// Add a match for signals. FIXME: Can we filter the service?
Connection.AddMatch ("type='signal'");
}
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 ();
}
}
message.Dispose ();
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);
}
}
|