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

Handler.cs

00001 namespace DBus
00002 {
00003   using System;
00004   using System.Runtime.InteropServices;
00005   using System.Diagnostics;
00006   using System.Reflection;
00007   using System.Collections;
00008 
00009   internal enum Result 
00010   {
00011     Handled = 0,
00012     NotYetHandled = 1,
00013     NeedMemory = 2
00014   }
00015 
00016   internal class Handler
00017   {
00018     private string path = null;
00019     private Introspector introspector = null;
00020     private object handledObject = null;
00021     private DBusObjectPathVTable vTable;
00022     private Connection connection;
00023     private Service service;
00024 
00025     // We need to hold extra references to these callbacks so that they don't
00026     // get garbage collected before they are called back into from unmanaged
00027     // code.
00028     private DBusObjectPathUnregisterFunction unregister_func;
00029     private DBusObjectPathMessageFunction message_func;
00030 
00031     public Handler(object handledObject, 
00032                    string path, 
00033                    Service service)
00034     {
00035       Service = service;
00036       Connection = service.Connection;
00037       HandledObject = handledObject;
00038       this.path = path;
00039       
00040       // Create the vTable and register the path
00041       this.unregister_func = new DBusObjectPathUnregisterFunction (Unregister_Called);
00042       this.message_func = new DBusObjectPathMessageFunction (Message_Called);
00043 
00044       vTable = new DBusObjectPathVTable (this.unregister_func, this.message_func);
00045       Connection.RegisterObjectPath (Path, vTable);
00046       RegisterSignalHandlers();
00047     }
00048 
00049     private void RegisterSignalHandlers()
00050     {
00051       ProxyBuilder proxyBuilder = new ProxyBuilder(Service, HandledObject.GetType(), Path);
00052 
00053       foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
00054         InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
00055         foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
00056           EventInfo eventE = (EventInfo) signalEntry.Value;
00057           Delegate del = Delegate.CreateDelegate(eventE.EventHandlerType, proxyBuilder.GetSignalProxy(), "Proxy_" + eventE.Name);
00058           eventE.AddEventHandler(HandledObject, del);
00059         }
00060       }
00061     }
00062 
00063     public object HandledObject 
00064     {
00065       get {
00066         return this.handledObject;
00067       }
00068       
00069       set {
00070         this.handledObject = value;
00071         
00072         // Register the methods
00073         this.introspector = Introspector.GetIntrospector(value.GetType());        
00074       }
00075     }
00076 
00077     public void Unregister_Called(IntPtr rawConnection, 
00078                                   IntPtr userData)
00079     {
00080       if (service != null) {
00081         service.UnregisterObject(HandledObject);
00082       }
00083 
00084       path = null;
00085     }
00086 
00087     private int Message_Called(IntPtr rawConnection, 
00088                                IntPtr rawMessage, 
00089                                IntPtr userData) 
00090     {
00091       Message message = Message.Wrap(rawMessage, Service);
00092       Result res = Result.NotYetHandled;
00093 
00094       switch (message.Type) {
00095       case Message.MessageType.MethodCall:
00096         res = HandleMethod ((MethodCall) message);
00097         break;
00098 
00099       case Message.MessageType.Signal:
00100         // We're not interested in signals here because we're the ones
00101         // that generate them!
00102         break;
00103       }
00104 
00105       message.Dispose ();
00106 
00107       return (int) res;
00108     }
00109     
00110     private Result HandleMethod(MethodCall methodCall)
00111     {
00112       methodCall.Service = service;
00113       
00114       InterfaceProxy interfaceProxy = this.introspector.GetInterface(methodCall.InterfaceName);
00115       if (interfaceProxy == null || !interfaceProxy.HasMethod(methodCall.Key)) {
00116         // No such interface here.
00117         return Result.NotYetHandled;
00118       }
00119       
00120       MethodInfo method = interfaceProxy.GetMethod(methodCall.Key);
00121       
00122       Message.Push (methodCall);
00123 
00124       // Now call the method. FIXME: Error handling
00125       object [] args = methodCall.Arguments.GetParameters(method);
00126       object retVal = method.Invoke(this.handledObject, args);
00127 
00128       Message.Pop ();
00129 
00130       // Create the reply and send it
00131       MethodReturn methodReturn = new MethodReturn(methodCall);
00132       methodReturn.Arguments.AppendResults(method, retVal, args);
00133       methodReturn.Send();
00134 
00135       return Result.Handled;
00136     }
00137 
00138     internal string Path 
00139     {
00140       get 
00141         {
00142           return path;
00143         }
00144     }
00145 
00146     internal Connection Connection 
00147     {
00148       get
00149         {
00150           return connection;
00151         }
00152       
00153       set 
00154         {
00155           this.connection = value;
00156         }
00157     }
00158 
00159     public Service Service
00160     {
00161       get
00162         {
00163           return service;
00164         }
00165       
00166       set 
00167         {
00168           this.service = value;
00169         }
00170     }
00171   }
00172 }

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