00001 namespace DBus
00002 {
00003
00004 using System;
00005 using System.Runtime.InteropServices;
00006 using System.Diagnostics;
00007 using System.Reflection;
00008 using System.IO;
00009 using System.Collections;
00010
00011 public delegate int DBusHandleMessageFunction (IntPtr rawConnection,
00012 IntPtr rawMessage,
00013 IntPtr userData);
00014
00015 internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
00016 IntPtr userData);
00017
00018 internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
00019 IntPtr rawMessage,
00020 IntPtr userData);
00021
00022 [StructLayout (LayoutKind.Sequential)]
00023 internal struct DBusObjectPathVTable
00024 {
00025 public DBusObjectPathUnregisterFunction unregisterFunction;
00026 public DBusObjectPathMessageFunction messageFunction;
00027 public IntPtr padding1;
00028 public IntPtr padding2;
00029 public IntPtr padding3;
00030 public IntPtr padding4;
00031
00032 public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
00033 DBusObjectPathMessageFunction messageFunction)
00034 {
00035 this.unregisterFunction = unregisterFunction;
00036 this.messageFunction = messageFunction;
00037 this.padding1 = IntPtr.Zero;
00038 this.padding2 = IntPtr.Zero;
00039 this.padding3 = IntPtr.Zero;
00040 this.padding4 = IntPtr.Zero;
00041 }
00042 }
00043
00044 public class Connection : IDisposable
00045 {
00049 private IntPtr rawConnection;
00050
00054 private static int slot = -1;
00055
00056 private int timeout = -1;
00057
00058 private ArrayList filters = new ArrayList ();
00059 private ArrayList matches = new ArrayList ();
00060 private Hashtable object_paths = new Hashtable ();
00061
00062 internal Connection(IntPtr rawConnection)
00063 {
00064 RawConnection = rawConnection;
00065 }
00066
00067 public Connection(string address)
00068 {
00069
00070 Error error = new Error();
00071 error.Init();
00072 RawConnection = dbus_connection_open(address, ref error);
00073 if (RawConnection != IntPtr.Zero) {
00074 dbus_connection_unref(RawConnection);
00075 } else {
00076 throw new DBusException(error);
00077 }
00078
00079 SetupWithMain();
00080 }
00081
00082 public void Dispose()
00083 {
00084 Dispose(true);
00085 GC.SuppressFinalize(this);
00086 }
00087
00088 public void Dispose (bool disposing)
00089 {
00090 if (disposing && RawConnection != IntPtr.Zero)
00091 {
00092 dbus_connection_disconnect(rawConnection);
00093
00094 RawConnection = IntPtr.Zero;
00095 }
00096 }
00097
00098 public void Flush()
00099 {
00100 dbus_connection_flush(RawConnection);
00101 }
00102
00103 public void SetupWithMain()
00104 {
00105 dbus_connection_setup_with_g_main(RawConnection, IntPtr.Zero);
00106 }
00107
00108 ~Connection ()
00109 {
00110 Dispose (false);
00111 }
00112
00113 internal static Connection Wrap(IntPtr rawConnection)
00114 {
00115 if (slot > -1) {
00116
00117
00118 IntPtr rawThis = dbus_connection_get_data (rawConnection, slot);
00119 if (rawThis != IntPtr.Zero) {
00120 return (DBus.Connection) ((GCHandle)rawThis).Target;
00121 }
00122 }
00123
00124
00125 return new Connection(rawConnection);
00126 }
00127
00128 public void AddFilter (DBusHandleMessageFunction func)
00129 {
00130 if (!dbus_connection_add_filter (RawConnection,
00131 func,
00132 IntPtr.Zero,
00133 IntPtr.Zero))
00134 throw new OutOfMemoryException ();
00135
00136 this.filters.Add (func);
00137 }
00138
00139 public void RemoveFilter (DBusHandleMessageFunction func)
00140 {
00141 dbus_connection_remove_filter (RawConnection, func, IntPtr.Zero);
00142
00143 this.filters.Remove (func);
00144 }
00145
00146 public void AddMatch (string match_rule)
00147 {
00148 dbus_bus_add_match (RawConnection, match_rule, IntPtr.Zero);
00149
00150 this.matches.Add (match_rule);
00151 }
00152
00153 public void RemoveMatch (string match_rule)
00154 {
00155 dbus_bus_remove_match (RawConnection, match_rule, IntPtr.Zero);
00156
00157 this.matches.Remove (match_rule);
00158 }
00159
00160 internal void RegisterObjectPath (string path, DBusObjectPathVTable vtable)
00161 {
00162 if (!dbus_connection_register_object_path (RawConnection, path, ref vtable, IntPtr.Zero))
00163 throw new OutOfMemoryException ();
00164
00165 this.object_paths[path] = vtable;
00166 }
00167
00168 internal void UnregisterObjectPath (string path)
00169 {
00170 dbus_connection_unregister_object_path (RawConnection, path);
00171
00172 this.object_paths.Remove (path);
00173 }
00174
00175
00176 public string UniqueName
00177 {
00178 get
00179 {
00180 return Marshal.PtrToStringAnsi (dbus_bus_get_unique_name (RawConnection));
00181 }
00182 }
00183
00184 public int Timeout
00185 {
00186 get
00187 {
00188 return this.timeout;
00189 }
00190 set
00191 {
00192 this.timeout = value;
00193 }
00194 }
00195
00196 private int Slot
00197 {
00198 get
00199 {
00200 if (slot == -1)
00201 {
00202
00203 if (!dbus_connection_allocate_data_slot (ref slot))
00204 throw new OutOfMemoryException ();
00205
00206 Debug.Assert (slot >= 0);
00207 }
00208
00209 return slot;
00210 }
00211 }
00212
00213 internal IntPtr RawConnection
00214 {
00215 get
00216 {
00217 return rawConnection;
00218 }
00219 set
00220 {
00221 if (value == rawConnection)
00222 return;
00223
00224 if (rawConnection != IntPtr.Zero)
00225 {
00226
00227 foreach (DBusHandleMessageFunction func in this.filters)
00228 dbus_connection_remove_filter (rawConnection, func, IntPtr.Zero);
00229
00230 foreach (string match_rule in this.matches)
00231 dbus_bus_remove_match (rawConnection, match_rule, IntPtr.Zero);
00232
00233 foreach (string path in this.object_paths.Keys)
00234 dbus_connection_unregister_object_path (rawConnection, path);
00235
00236
00237 IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
00238 Debug.Assert (rawThis != IntPtr.Zero);
00239
00240
00241 dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
00242
00243
00244 ((GCHandle) rawThis).Free();
00245
00246
00247 dbus_connection_unref(rawConnection);
00248 }
00249
00250 this.rawConnection = value;
00251
00252 if (rawConnection != IntPtr.Zero)
00253 {
00254 GCHandle rawThis;
00255
00256 dbus_connection_ref (rawConnection);
00257
00258
00259 rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
00260
00261 dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
00262
00263
00264 foreach (DBusHandleMessageFunction func in this.filters)
00265 dbus_connection_add_filter (rawConnection, func, IntPtr.Zero, IntPtr.Zero);
00266
00267 foreach (string match_rule in this.matches)
00268 dbus_bus_add_match (rawConnection, match_rule, IntPtr.Zero);
00269
00270 foreach (string path in this.object_paths.Keys) {
00271 DBusObjectPathVTable vtable = (DBusObjectPathVTable) this.object_paths[path];
00272 dbus_connection_register_object_path (rawConnection, path, ref vtable, IntPtr.Zero);
00273 }
00274 }
00275 else
00276 {
00277 this.filters.Clear ();
00278 this.matches.Clear ();
00279 this.object_paths.Clear ();
00280 }
00281 }
00282 }
00283
00284 [DllImport("dbus-glib-1")]
00285 private extern static void dbus_connection_setup_with_g_main(IntPtr rawConnection,
00286 IntPtr rawContext);
00287
00288 [DllImport ("dbus-1")]
00289 private extern static IntPtr dbus_connection_open (string address, ref Error error);
00290
00291 [DllImport ("dbus-1")]
00292 private extern static void dbus_connection_unref (IntPtr ptr);
00293
00294 [DllImport ("dbus-1")]
00295 private extern static void dbus_connection_ref (IntPtr ptr);
00296
00297 [DllImport ("dbus-1")]
00298 private extern static bool dbus_connection_allocate_data_slot (ref int slot);
00299
00300 [DllImport ("dbus-1")]
00301 private extern static void dbus_connection_free_data_slot (ref int slot);
00302
00303 [DllImport ("dbus-1")]
00304 private extern static bool dbus_connection_set_data (IntPtr ptr,
00305 int slot,
00306 IntPtr data,
00307 IntPtr free_data_func);
00308
00309 [DllImport ("dbus-1")]
00310 private extern static void dbus_connection_flush (IntPtr ptr);
00311
00312 [DllImport ("dbus-1")]
00313 private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
00314 int slot);
00315
00316 [DllImport ("dbus-1")]
00317 private extern static void dbus_connection_disconnect (IntPtr ptr);
00318
00319 [DllImport ("dbus-1")]
00320 private extern static IntPtr dbus_bus_get_unique_name (IntPtr ptr);
00321
00322 [DllImport("dbus-1")]
00323 private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
00324 DBusHandleMessageFunction filter,
00325 IntPtr userData,
00326 IntPtr freeData);
00327
00328 [DllImport("dbus-1")]
00329 private extern static void dbus_connection_remove_filter(IntPtr rawConnection,
00330 DBusHandleMessageFunction filter,
00331 IntPtr userData);
00332
00333 [DllImport("dbus-1")]
00334 private extern static void dbus_bus_add_match(IntPtr rawConnection,
00335 string rule,
00336 IntPtr erro);
00337
00338 [DllImport("dbus-1")]
00339 private extern static void dbus_bus_remove_match(IntPtr rawConnection,
00340 string rule,
00341 IntPtr erro);
00342
00343 [DllImport ("dbus-1")]
00344 private extern static bool dbus_connection_register_object_path (IntPtr rawConnection,
00345 string path,
00346 ref DBusObjectPathVTable vTable,
00347 IntPtr userData);
00348
00349 [DllImport ("dbus-1")]
00350 private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection,
00351 string path);
00352
00353 }
00354 }