Main Page | Modules | Namespace List | Class Hierarchy | Data Structures | Directories | File List | Namespace Members | 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 
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               // We need to initialize the slot
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               // Remove our callbacks from this connection
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               // Get the reference to this
00237               IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
00238               Debug.Assert (rawThis != IntPtr.Zero);
00239               
00240               // Blank over the reference
00241               dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
00242               
00243               // Free the reference
00244               ((GCHandle) rawThis).Free();
00245               
00246               // Unref the connection
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               // We store a weak reference to the C# object on the C object
00259               rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
00260               
00261               dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
00262 
00263               // Add the callbacks to this new connection
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 }

Generated on Tue Sep 13 01:28:06 2005 for D-BUS by  doxygen 1.4.4