5 using System.Runtime.InteropServices;
6 using System.Diagnostics;
7 using System.Collections;
13 /// A pointer to the underlying Message structure
15 private IntPtr rawMessage;
18 /// The current slot number
20 private static int slot = -1;
22 // Keep in sync with C
23 public enum MessageType
32 private Arguments arguments = null;
34 protected Service service = null;
35 protected string pathName = null;
36 protected string interfaceName = null;
37 protected string name = null;
38 private string key= null;
42 // An empty constructor for the sake of sub-classes which know how to construct theirselves.
45 protected Message(IntPtr rawMessage, Service service)
47 RawMessage = rawMessage;
48 this.service = service;
51 protected Message(MessageType messageType)
53 // the assignment bumps the refcount
54 RawMessage = dbus_message_new((int) messageType);
56 if (RawMessage == IntPtr.Zero) {
57 throw new OutOfMemoryException();
60 dbus_message_unref(RawMessage);
63 protected Message(MessageType messageType, Service service) : this(messageType)
65 this.service = service;
70 RawMessage = IntPtr.Zero; // free the native object
73 public static Message Wrap(IntPtr rawMessage, Service service)
76 // If we already have a Message object associated with this rawMessage then return it
77 IntPtr rawThis = dbus_message_get_data(rawMessage, slot);
78 if (rawThis != IntPtr.Zero)
79 return (DBus.Message) ((GCHandle)rawThis).Target;
81 // If it doesn't exist then create a new Message around it
82 Message message = null;
84 switch ((MessageType) dbus_message_get_type(rawMessage)) {
85 case MessageType.Signal:
86 message = new Signal(rawMessage, service);
88 case MessageType.MethodCall:
89 message = new MethodCall(rawMessage, service);
96 internal IntPtr RawMessage
104 if (value == rawMessage)
107 if (rawMessage != IntPtr.Zero)
109 // Get the reference to this
110 IntPtr rawThis = dbus_message_get_data(rawMessage, Slot);
111 Debug.Assert (rawThis != IntPtr.Zero);
113 // Blank over the reference
114 dbus_message_set_data(rawMessage, Slot, IntPtr.Zero, IntPtr.Zero);
116 // Free the reference
117 ((GCHandle) rawThis).Free();
119 // Unref the connection
120 dbus_message_unref(rawMessage);
123 this.rawMessage = value;
125 if (rawMessage != IntPtr.Zero)
129 dbus_message_ref(rawMessage);
131 // We store a weak reference to the C# object on the C object
132 rawThis = GCHandle.Alloc(this, GCHandleType.WeakTrackResurrection);
134 dbus_message_set_data(rawMessage, Slot, (IntPtr) rawThis, IntPtr.Zero);
139 public void Send(ref int serial)
141 if (!dbus_connection_send (Service.Connection.RawConnection, RawMessage, ref serial))
142 throw new OutOfMemoryException ();
151 public void SendWithReply()
153 IntPtr rawPendingCall = IntPtr.Zero;
155 if (!dbus_connection_send_with_reply (Service.Connection.RawConnection, RawMessage, rawPendingCall, Service.Connection.Timeout))
156 throw new OutOfMemoryException();
159 public MethodReturn SendWithReplyAndBlock()
161 Error error = new Error();
164 IntPtr rawMessage = dbus_connection_send_with_reply_and_block(Service.Connection.RawConnection,
166 Service.Connection.Timeout,
169 if (rawMessage != IntPtr.Zero) {
170 MethodReturn methodReturn = new MethodReturn(rawMessage, Service);
173 throw new DBusException(error);
177 public MessageType Type
181 return (MessageType) dbus_message_get_type(RawMessage);
185 public Service Service
189 if (this.service != null && (value.Name != this.service.Name)) {
190 if (!dbus_message_set_destination(RawMessage, value.Name)) {
191 throw new OutOfMemoryException();
195 this.service = value;
203 protected virtual string PathName
207 if (value != this.pathName)
209 if (!dbus_message_set_path(RawMessage, value)) {
210 throw new OutOfMemoryException();
213 this.pathName = value;
218 if (this.pathName == null) {
219 this.pathName = Marshal.PtrToStringAnsi(dbus_message_get_path(RawMessage));
222 return this.pathName;
226 protected virtual string InterfaceName
230 if (value != this.interfaceName)
232 dbus_message_set_interface (RawMessage, value);
233 this.interfaceName = value;
238 if (this.interfaceName == null) {
239 this.interfaceName = Marshal.PtrToStringAnsi(dbus_message_get_interface(RawMessage));
242 return this.interfaceName;
246 protected virtual string Name
250 if (value != this.name)
252 dbus_message_set_member (RawMessage, value);
258 if (this.name == null) {
259 this.name = Marshal.PtrToStringAnsi(dbus_message_get_member(RawMessage));
270 if (this.key == null) {
271 this.key = Name + " " + Arguments;
278 public Arguments Arguments
282 if (this.arguments == null) {
283 this.arguments = new Arguments(this);
286 return this.arguments;
296 // We need to initialize the slot
297 if (!dbus_message_allocate_data_slot (ref slot))
298 throw new OutOfMemoryException ();
300 Debug.Assert (slot >= 0);
307 [DllImport ("dbus-1", EntryPoint="dbus_message_new")]
308 protected extern static IntPtr dbus_message_new (int messageType);
310 [DllImport ("dbus-1", EntryPoint="dbus_message_unref")]
311 protected extern static void dbus_message_unref (IntPtr ptr);
313 [DllImport ("dbus-1", EntryPoint="dbus_message_ref")]
314 protected extern static void dbus_message_ref (IntPtr ptr);
316 [DllImport ("dbus-1", EntryPoint="dbus_message_allocate_data_slot")]
317 protected extern static bool dbus_message_allocate_data_slot (ref int slot);
319 [DllImport ("dbus-1", EntryPoint="dbus_message_free_data_slot")]
320 protected extern static void dbus_message_free_data_slot (ref int slot);
322 [DllImport ("dbus-1", EntryPoint="dbus_message_set_data")]
323 protected extern static bool dbus_message_set_data (IntPtr ptr,
326 IntPtr free_data_func);
328 [DllImport ("dbus-1", EntryPoint="dbus_message_get_data")]
329 protected extern static IntPtr dbus_message_get_data (IntPtr ptr,
332 [DllImport ("dbus-1", EntryPoint="dbus_connection_send")]
333 private extern static bool dbus_connection_send (IntPtr ptr,
335 ref int client_serial);
337 [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply")]
338 private extern static bool dbus_connection_send_with_reply (IntPtr rawConnection, IntPtr rawMessage, IntPtr rawPendingCall, int timeout);
340 [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply_and_block")]
341 private extern static IntPtr dbus_connection_send_with_reply_and_block (IntPtr rawConnection, IntPtr message, int timeout, ref Error error);
343 [DllImport("dbus-1")]
344 private extern static int dbus_message_get_type(IntPtr rawMessage);
346 [DllImport("dbus-1")]
347 private extern static bool dbus_message_set_path(IntPtr rawMessage, string pathName);
349 [DllImport("dbus-1")]
350 private extern static IntPtr dbus_message_get_path(IntPtr rawMessage);
352 [DllImport("dbus-1")]
353 private extern static bool dbus_message_set_interface (IntPtr rawMessage, string interfaceName);
355 [DllImport("dbus-1")]
356 private extern static IntPtr dbus_message_get_interface(IntPtr rawMessage);
358 [DllImport("dbus-1")]
359 private extern static bool dbus_message_set_member (IntPtr rawMessage, string name);
361 [DllImport("dbus-1")]
362 private extern static IntPtr dbus_message_get_member(IntPtr rawMessage);
364 [DllImport("dbus-1")]
365 private extern static bool dbus_message_set_destination(IntPtr rawMessage, string serviceName);
367 [DllImport("dbus-1")]
368 private extern static IntPtr dbus_message_get_destination(IntPtr rawMessage);