5
using System.Runtime.InteropServices;
6
using System.Diagnostics;
7
using System.Reflection;
9
using System.Collections;
11
public delegate int DBusHandleMessageFunction (IntPtr rawConnection,
15
internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
18
internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
22
[StructLayout (LayoutKind.Sequential)]
23
internal struct DBusObjectPathVTable
25
public DBusObjectPathUnregisterFunction unregisterFunction;
26
public DBusObjectPathMessageFunction messageFunction;
27
public IntPtr padding1;
28
public IntPtr padding2;
29
public IntPtr padding3;
30
public IntPtr padding4;
32
public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
33
DBusObjectPathMessageFunction messageFunction)
35
this.unregisterFunction = unregisterFunction;
36
this.messageFunction = messageFunction;
37
this.padding1 = IntPtr.Zero;
38
this.padding2 = IntPtr.Zero;
39
this.padding3 = IntPtr.Zero;
40
this.padding4 = IntPtr.Zero;
44
public class Connection : IDisposable
47
/// A pointer to the underlying Connection structure
49
private IntPtr rawConnection;
52
/// The current slot number
54
private static int slot = -1;
56
private int timeout = -1;
58
private ArrayList filters = new ArrayList (); // of DBusHandleMessageFunction
59
private ArrayList matches = new ArrayList (); // of string
60
private Hashtable object_paths = new Hashtable (); // key: string value: DBusObjectPathVTable
62
internal Connection(IntPtr rawConnection)
64
RawConnection = rawConnection;
67
public Connection(string address)
69
// the assignment bumps the refcount
70
Error error = new Error();
72
RawConnection = dbus_connection_open(address, ref error);
73
if (RawConnection != IntPtr.Zero) {
74
dbus_connection_unref(RawConnection);
76
throw new DBusException(error);
85
GC.SuppressFinalize(this);
88
public void Dispose (bool disposing)
90
if (disposing && RawConnection != IntPtr.Zero)
92
dbus_connection_disconnect(rawConnection);
94
RawConnection = IntPtr.Zero; // free the native object
100
dbus_connection_flush(RawConnection);
103
public void SetupWithMain()
105
dbus_connection_setup_with_g_main(RawConnection, IntPtr.Zero);
113
internal static Connection Wrap(IntPtr rawConnection)
116
// Maybe we already have a Connection object associated with
117
// this rawConnection then return it
118
IntPtr rawThis = dbus_connection_get_data (rawConnection, slot);
119
if (rawThis != IntPtr.Zero && ((GCHandle)rawThis).Target == typeof(DBus.Connection)) {
120
return (DBus.Connection) ((GCHandle)rawThis).Target;
124
// If it doesn't exist then create a new connection around it
125
return new Connection(rawConnection);
128
public void AddFilter (DBusHandleMessageFunction func)
130
if (!dbus_connection_add_filter (RawConnection,
134
throw new OutOfMemoryException ();
136
this.filters.Add (func);
139
public void RemoveFilter (DBusHandleMessageFunction func)
141
dbus_connection_remove_filter (RawConnection, func, IntPtr.Zero);
143
this.filters.Remove (func);
146
public void AddMatch (string match_rule)
148
dbus_bus_add_match (RawConnection, match_rule, IntPtr.Zero);
150
this.matches.Add (match_rule);
153
public void RemoveMatch (string match_rule)
155
dbus_bus_remove_match (RawConnection, match_rule, IntPtr.Zero);
157
this.matches.Remove (match_rule);
160
internal void RegisterObjectPath (string path, DBusObjectPathVTable vtable)
162
if (!dbus_connection_register_object_path (RawConnection, path, ref vtable, IntPtr.Zero))
163
throw new OutOfMemoryException ();
165
this.object_paths[path] = vtable;
168
internal void UnregisterObjectPath (string path)
170
dbus_connection_unregister_object_path (RawConnection, path);
172
this.object_paths.Remove (path);
176
public string UniqueName
180
return Marshal.PtrToStringAnsi (dbus_bus_get_unique_name (RawConnection));
192
this.timeout = value;
202
// We need to initialize the slot
203
if (!dbus_connection_allocate_data_slot (ref slot))
204
throw new OutOfMemoryException ();
206
Debug.Assert (slot >= 0);
213
internal IntPtr RawConnection
217
return rawConnection;
221
if (value == rawConnection)
224
if (rawConnection != IntPtr.Zero)
226
// Remove our callbacks from this connection
227
foreach (DBusHandleMessageFunction func in this.filters)
228
dbus_connection_remove_filter (rawConnection, func, IntPtr.Zero);
230
foreach (string match_rule in this.matches)
231
dbus_bus_remove_match (rawConnection, match_rule, IntPtr.Zero);
233
foreach (string path in this.object_paths.Keys)
234
dbus_connection_unregister_object_path (rawConnection, path);
236
// Get the reference to this
237
IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
238
Debug.Assert (rawThis != IntPtr.Zero);
240
// Blank over the reference
241
dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
243
// Free the reference
244
((GCHandle) rawThis).Free();
246
// Unref the connection
247
dbus_connection_unref(rawConnection);
250
this.rawConnection = value;
252
if (rawConnection != IntPtr.Zero)
256
dbus_connection_ref (rawConnection);
258
// We store a weak reference to the C# object on the C object
259
rawThis = GCHandle.Alloc (this, GCHandleType.Normal);
261
dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
263
// Add the callbacks to this new connection
264
foreach (DBusHandleMessageFunction func in this.filters)
265
dbus_connection_add_filter (rawConnection, func, IntPtr.Zero, IntPtr.Zero);
267
foreach (string match_rule in this.matches)
268
dbus_bus_add_match (rawConnection, match_rule, IntPtr.Zero);
270
foreach (string path in this.object_paths.Keys) {
271
DBusObjectPathVTable vtable = (DBusObjectPathVTable) this.object_paths[path];
272
dbus_connection_register_object_path (rawConnection, path, ref vtable, IntPtr.Zero);
277
this.filters.Clear ();
278
this.matches.Clear ();
279
this.object_paths.Clear ();
284
[DllImport("dbus-glib-1")]
285
private extern static void dbus_connection_setup_with_g_main(IntPtr rawConnection,
288
[DllImport ("dbus-1")]
289
private extern static IntPtr dbus_connection_open (string address, ref Error error);
291
[DllImport ("dbus-1")]
292
private extern static void dbus_connection_unref (IntPtr ptr);
294
[DllImport ("dbus-1")]
295
private extern static void dbus_connection_ref (IntPtr ptr);
297
[DllImport ("dbus-1")]
298
private extern static bool dbus_connection_allocate_data_slot (ref int slot);
300
[DllImport ("dbus-1")]
301
private extern static void dbus_connection_free_data_slot (ref int slot);
303
[DllImport ("dbus-1")]
304
private extern static bool dbus_connection_set_data (IntPtr ptr,
307
IntPtr free_data_func);
309
[DllImport ("dbus-1")]
310
private extern static void dbus_connection_flush (IntPtr ptr);
312
[DllImport ("dbus-1")]
313
private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
316
[DllImport ("dbus-1")]
317
private extern static void dbus_connection_disconnect (IntPtr ptr);
319
[DllImport ("dbus-1")]
320
private extern static IntPtr dbus_bus_get_unique_name (IntPtr ptr);
322
[DllImport("dbus-1")]
323
private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
324
DBusHandleMessageFunction filter,
328
[DllImport("dbus-1")]
329
private extern static void dbus_connection_remove_filter(IntPtr rawConnection,
330
DBusHandleMessageFunction filter,
333
[DllImport("dbus-1")]
334
private extern static void dbus_bus_add_match(IntPtr rawConnection,
338
[DllImport("dbus-1")]
339
private extern static void dbus_bus_remove_match(IntPtr rawConnection,
343
[DllImport ("dbus-1")]
344
private extern static bool dbus_connection_register_object_path (IntPtr rawConnection,
346
ref DBusObjectPathVTable vTable,
349
[DllImport ("dbus-1")]
350
private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection,