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 public string BaseService
00176 {
00177 get
00178 {
00179 return Marshal.PtrToStringAnsi (dbus_bus_get_base_service (RawConnection));
00180 }
00181 }
00182
00183 public int Timeout
00184 {
00185 get
00186 {
00187 return this.timeout;
00188 }
00189 set
00190 {
00191 this.timeout = value;
00192 }
00193 }
00194
00195 private int Slot
00196 {
00197 get
00198 {
00199 if (slot == -1)
00200 {
00201
00202 if (!dbus_connection_allocate_data_slot (ref slot))
00203 throw new OutOfMemoryException ();
00204
00205 Debug.Assert (slot >= 0);
00206 }
00207
00208 return slot;
00209 }
00210 }
00211
00212 internal IntPtr RawConnection
00213 {
00214 get
00215 {
00216 return rawConnection;
00217 }
00218 set
00219 {
00220 if (value == rawConnection)
00221 return;
00222
00223 if (rawConnection != IntPtr.Zero)
00224 {
00225
00226 foreach (DBusHandleMessageFunction func in this.filters)
00227 dbus_connection_remove_filter (rawConnection, func, IntPtr.Zero);
00228
00229 foreach (string match_rule in this.matches)
00230 dbus_bus_remove_match (rawConnection, match_rule, IntPtr.Zero);
00231
00232 foreach (string path in this.object_paths.Keys)
00233 dbus_connection_unregister_object_path (rawConnection, path);
00234
00235
00236 IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
00237 Debug.Assert (rawThis != IntPtr.Zero);
00238
00239
00240 dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
00241
00242
00243 ((GCHandle) rawThis).Free();
00244
00245
00246 dbus_connection_unref(rawConnection);
00247 }
00248
00249 this.rawConnection = value;
00250
00251 if (rawConnection != IntPtr.Zero)
00252 {
00253 GCHandle rawThis;
00254
00255 dbus_connection_ref (rawConnection);
00256
00257
00258 rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
00259
00260 dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
00261
00262
00263 foreach (DBusHandleMessageFunction func in this.filters)
00264 dbus_connection_add_filter (rawConnection, func, IntPtr.Zero, IntPtr.Zero);
00265
00266 foreach (string match_rule in this.matches)
00267 dbus_bus_add_match (rawConnection, match_rule, IntPtr.Zero);
00268
00269 foreach (string path in this.object_paths.Keys) {
00270 DBusObjectPathVTable vtable = (DBusObjectPathVTable) this.object_paths[path];
00271 dbus_connection_register_object_path (rawConnection, path, ref vtable, IntPtr.Zero);
00272 }
00273 }
00274 else
00275 {
00276 this.filters.Clear ();
00277 this.matches.Clear ();
00278 this.object_paths.Clear ();
00279 }
00280 }
00281 }
00282
00283 [DllImport("dbus-glib-1")]
00284 private extern static void dbus_connection_setup_with_g_main(IntPtr rawConnection,
00285 IntPtr rawContext);
00286
00287 [DllImport ("dbus-1")]
00288 private extern static IntPtr dbus_connection_open (string address, ref Error error);
00289
00290 [DllImport ("dbus-1")]
00291 private extern static void dbus_connection_unref (IntPtr ptr);
00292
00293 [DllImport ("dbus-1")]
00294 private extern static void dbus_connection_ref (IntPtr ptr);
00295
00296 [DllImport ("dbus-1")]
00297 private extern static bool dbus_connection_allocate_data_slot (ref int slot);
00298
00299 [DllImport ("dbus-1")]
00300 private extern static void dbus_connection_free_data_slot (ref int slot);
00301
00302 [DllImport ("dbus-1")]
00303 private extern static bool dbus_connection_set_data (IntPtr ptr,
00304 int slot,
00305 IntPtr data,
00306 IntPtr free_data_func);
00307
00308 [DllImport ("dbus-1")]
00309 private extern static void dbus_connection_flush (IntPtr ptr);
00310
00311 [DllImport ("dbus-1")]
00312 private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
00313 int slot);
00314
00315 [DllImport ("dbus-1")]
00316 private extern static void dbus_connection_disconnect (IntPtr ptr);
00317
00318 [DllImport ("dbus-1")]
00319 private extern static IntPtr dbus_bus_get_base_service (IntPtr ptr);
00320
00321 [DllImport("dbus-1")]
00322 private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
00323 DBusHandleMessageFunction filter,
00324 IntPtr userData,
00325 IntPtr freeData);
00326
00327 [DllImport("dbus-1")]
00328 private extern static void dbus_connection_remove_filter(IntPtr rawConnection,
00329 DBusHandleMessageFunction filter,
00330 IntPtr userData);
00331
00332 [DllImport("dbus-1")]
00333 private extern static void dbus_bus_add_match(IntPtr rawConnection,
00334 string rule,
00335 IntPtr erro);
00336
00337 [DllImport("dbus-1")]
00338 private extern static void dbus_bus_remove_match(IntPtr rawConnection,
00339 string rule,
00340 IntPtr erro);
00341
00342 [DllImport ("dbus-1")]
00343 private extern static bool dbus_connection_register_object_path (IntPtr rawConnection,
00344 string path,
00345 ref DBusObjectPathVTable vTable,
00346 IntPtr userData);
00347
00348 [DllImport ("dbus-1")]
00349 private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection,
00350 string path);
00351
00352 }
00353 }