00001 namespace DBus
00002 {
00003 using System;
00004 using System.Runtime.InteropServices;
00005 using System.Diagnostics;
00006 using System.Collections;
00007 using System.Threading;
00008 using System.Reflection;
00009 using System.Reflection.Emit;
00010
00011 public class Service
00012 {
00013 private Connection connection;
00014 private string name;
00015 private bool local = false;
00016 private Hashtable registeredHandlers = new Hashtable();
00017 private DBusHandleMessageFunction filterCalled;
00018 public delegate void SignalCalledHandler(Signal signal);
00019 public event SignalCalledHandler SignalCalled;
00020 private static AssemblyBuilder proxyAssembly;
00021 private ModuleBuilder module = null;
00022
00023
00024 private const string MatchRule = "type='signal'";
00025
00026 internal Service(string name, Connection connection)
00027 {
00028 this.name = name;
00029 this.connection = connection;
00030 AddFilter();
00031 }
00032
00033 public Service(Connection connection, string name)
00034 {
00035 Error error = new Error();
00036 error.Init();
00037
00038
00039 uint flags = 0;
00040
00041 if (dbus_bus_request_name (connection.RawConnection, name, flags, ref error) == -1) {
00042 throw new DBusException(error);
00043 }
00044
00045 this.connection = connection;
00046 this.name = name;
00047 this.local = true;
00048 }
00049
00050 public static bool HasOwner(Connection connection, string name)
00051 {
00052 Error error = new Error();
00053 error.Init();
00054
00055 if (dbus_bus_name_has_owner(connection.RawConnection,
00056 name,
00057 ref error)) {
00058 return true;
00059 } else {
00060 if (error.IsSet) {
00061 throw new DBusException(error);
00062 }
00063 return false;
00064 }
00065 }
00066
00067 public static Service Get(Connection connection, string name)
00068 {
00069 if (HasOwner(connection, name)) {
00070 return new Service(name, connection);
00071 } else {
00072 throw new ApplicationException("Name '" + name + "' does not exist.");
00073 }
00074 }
00075
00076 public void UnregisterObject(object handledObject)
00077 {
00078 registeredHandlers.Remove(handledObject);
00079 }
00080
00081 public void RegisterObject(object handledObject,
00082 string pathName)
00083 {
00084 Handler handler = new Handler(handledObject, pathName, this);
00085 registeredHandlers.Add(handledObject, handler);
00086 }
00087
00088 internal Handler GetHandler(object handledObject)
00089 {
00090 if (!registeredHandlers.Contains(handledObject)) {
00091 throw new ArgumentException("No handler registered for object: " + handledObject);
00092 }
00093
00094 return (Handler) registeredHandlers[handledObject];
00095 }
00096
00097 public object GetObject(Type type, string pathName)
00098 {
00099 ProxyBuilder builder = new ProxyBuilder(this, type, pathName);
00100 object proxy = builder.GetProxy();
00101 return proxy;
00102 }
00103
00104 private void AddFilter()
00105 {
00106
00107 this.filterCalled = new DBusHandleMessageFunction(Service_FilterCalled);
00108 Connection.AddFilter (this.filterCalled);
00109
00110 Connection.AddMatch ("type='signal'");
00111 }
00112
00113 private int Service_FilterCalled(IntPtr rawConnection,
00114 IntPtr rawMessage,
00115 IntPtr userData)
00116 {
00117 Message message = Message.Wrap(rawMessage, this);
00118
00119 if (message.Type == Message.MessageType.Signal) {
00120
00121 Signal signal = (Signal) message;
00122 if (SignalCalled != null) {
00123 Message.Push (message);
00124 SignalCalled(signal);
00125 Message.Pop ();
00126 }
00127 }
00128
00129 message.Dispose ();
00130
00131 return (int) Result.NotYetHandled;
00132 }
00133
00134 public string Name
00135 {
00136 get
00137 {
00138 return this.name;
00139 }
00140 }
00141
00142 public Connection Connection
00143 {
00144 get
00145 {
00146 return connection;
00147 }
00148
00149 set
00150 {
00151 this.connection = value;
00152 }
00153 }
00154
00155 internal AssemblyBuilder ProxyAssembly
00156 {
00157 get {
00158 if (proxyAssembly == null){
00159 AssemblyName assemblyName = new AssemblyName();
00160 assemblyName.Name = "DBusProxy";
00161 proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
00162 AssemblyBuilderAccess.RunAndSave);
00163 }
00164
00165 return proxyAssembly;
00166 }
00167 }
00168
00169 internal ModuleBuilder Module
00170 {
00171 get {
00172 if (this.module == null) {
00173 this.module = ProxyAssembly.DefineDynamicModule(Name, Name + ".proxy.dll", true);
00174 }
00175
00176 return this.module;
00177 }
00178 }
00179
00180 [DllImport("dbus-1")]
00181 private extern static int dbus_bus_request_name(IntPtr rawConnection,
00182 string serviceName,
00183 uint flags, ref Error error);
00184
00185 [DllImport("dbus-1")]
00186 private extern static bool dbus_bus_name_has_owner(IntPtr rawConnection,
00187 string serviceName,
00188 ref Error error);
00189
00190 }
00191 }