Main Page | Modules | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

Connection.cs

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 ();      // of DBusHandleMessageFunction
00059     private ArrayList matches = new ArrayList ();      // of string
00060     private Hashtable object_paths = new Hashtable (); // key: string  value: DBusObjectPathVTable
00061 
00062     internal Connection(IntPtr rawConnection)
00063     {
00064       RawConnection = rawConnection;
00065     }
00066     
00067     public Connection(string address)
00068     {
00069       // the assignment bumps the refcount
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; // free the native object
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         // Maybe we already have a Connection object associated with
00117         // this rawConnection then return it
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       // If it doesn't exist then create a new connection around it
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               // We need to initialize the slot
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               // Remove our callbacks from this connection
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               // Get the reference to this
00236               IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
00237               Debug.Assert (rawThis != IntPtr.Zero);
00238               
00239               // Blank over the reference
00240               dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
00241               
00242               // Free the reference
00243               ((GCHandle) rawThis).Free();
00244               
00245               // Unref the connection
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               // We store a weak reference to the C# object on the C object
00258               rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
00259               
00260               dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
00261 
00262               // Add the callbacks to this new connection
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 }

Generated on Tue Mar 22 23:25:48 2005 for D-BUS by  doxygen 1.4.1