* qt/Makfile.am:
[platform/upstream/dbus.git] / mono / Service.cs
1 namespace DBus
2 {
3   using System;
4   using System.Runtime.InteropServices;
5   using System.Diagnostics;
6   using System.Collections;
7   using System.Threading;
8   using System.Reflection;
9   using System.Reflection.Emit;
10   
11   public class Service
12   {
13     private Connection connection;
14     private string name;
15     private bool local = false;
16     private Hashtable registeredHandlers = new Hashtable();
17     private DBusHandleMessageFunction filterCalled;
18     public delegate void SignalCalledHandler(Signal signal);
19     public event SignalCalledHandler SignalCalled;
20     private static AssemblyBuilder proxyAssembly;
21     private ModuleBuilder module = null;
22
23     // Add a match for signals. FIXME: Can we filter the service?
24     private const string MatchRule = "type='signal'";
25
26     internal Service(string name, Connection connection)
27     {
28       this.name = name;
29       this.connection = connection;
30       AddFilter();
31     }
32
33     public Service(Connection connection, string name)
34     {
35       Error error = new Error();
36       error.Init();
37       
38       // This isn't used for now
39       uint flags = 0;
40
41       if (dbus_bus_request_name (connection.RawConnection, name, flags, ref error) == -1) {
42         throw new DBusException(error);
43       }
44
45       this.connection = connection;
46       this.name = name;
47       this.local = true;
48     }
49
50     public static bool HasOwner(Connection connection, string name)
51     {
52       Error error = new Error();
53       error.Init();
54       
55       if (dbus_bus_name_has_owner(connection.RawConnection, 
56                                   name, 
57                                   ref error)) {
58         return true;
59       } else {
60         if (error.IsSet) {
61           throw new DBusException(error);
62         }
63         return false;
64       }
65     }
66
67     public static Service Get(Connection connection, string name)
68     {
69       if (HasOwner(connection, name)) {
70         return new Service(name, connection);
71       } else {
72         throw new ApplicationException("Name '" + name + "' does not exist.");
73       }
74     }
75
76     public void UnregisterObject(object handledObject) 
77     {
78       registeredHandlers.Remove(handledObject);
79     }
80
81     public void RegisterObject(object handledObject, 
82                                string pathName) 
83     {
84       Handler handler = new Handler(handledObject, pathName, this);
85       registeredHandlers.Add(handledObject, handler);
86     }
87
88     internal Handler GetHandler(object handledObject) 
89     {
90       if (!registeredHandlers.Contains(handledObject)) {
91         throw new ArgumentException("No handler registered for object: " + handledObject);
92       }
93       
94       return (Handler) registeredHandlers[handledObject];
95     }
96
97     public object GetObject(Type type, string pathName)
98     {
99       ProxyBuilder builder = new ProxyBuilder(this, type, pathName);
100       object proxy = builder.GetProxy();
101       return proxy;
102     }
103
104     private void AddFilter() 
105     {
106       // Setup the filter function
107       this.filterCalled = new DBusHandleMessageFunction(Service_FilterCalled);
108       Connection.AddFilter (this.filterCalled);
109       // Add a match for signals. FIXME: Can we filter the service?
110       Connection.AddMatch ("type='signal'");
111     }
112
113     private int Service_FilterCalled(IntPtr rawConnection,
114                                     IntPtr rawMessage,
115                                     IntPtr userData) 
116     {
117       Message message = Message.Wrap(rawMessage, this);
118       
119       if (message.Type == Message.MessageType.Signal) {
120         // We're only interested in signals
121         Signal signal = (Signal) message;
122         if (SignalCalled != null) {
123           Message.Push (message);
124           SignalCalled(signal);
125           Message.Pop ();
126         }
127       }
128       
129       message.Dispose ();
130
131       return (int) Result.NotYetHandled;
132     }
133
134     public string Name
135     {
136       get
137         {
138           return this.name;
139         }
140     }
141
142     public Connection Connection 
143     {
144       get
145         {
146           return connection;
147         }
148       
149       set 
150         {
151           this.connection = value;
152         }
153     }
154
155     internal AssemblyBuilder ProxyAssembly
156     {
157       get {
158         if (proxyAssembly == null){
159           AssemblyName assemblyName = new AssemblyName();
160           assemblyName.Name = "DBusProxy";
161           proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, 
162                                                                    AssemblyBuilderAccess.RunAndSave);
163         }
164         
165         return proxyAssembly;
166       }
167     }
168
169     internal ModuleBuilder Module
170     {
171       get {
172         if (this.module == null) {
173           this.module = ProxyAssembly.DefineDynamicModule(Name, Name + ".proxy.dll", true);
174         }
175         
176         return this.module;
177       }
178     }
179
180     [DllImport("dbus-1")]
181     private extern static int dbus_bus_request_name(IntPtr rawConnection, 
182                                                     string serviceName, 
183                                                     uint flags, ref Error error);
184
185     [DllImport("dbus-1")]
186     private extern static bool dbus_bus_name_has_owner(IntPtr rawConnection, 
187                                                        string serviceName, 
188                                                        ref Error error);    
189
190   }
191 }