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
00026
00027
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
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
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
00101
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
00117 return Result.NotYetHandled;
00118 }
00119
00120 MethodInfo method = interfaceProxy.GetMethod(methodCall.Key);
00121
00122 Message.Push (methodCall);
00123
00124
00125 object [] args = methodCall.Arguments.GetParameters(method);
00126 object retVal = method.Invoke(this.handledObject, args);
00127
00128 Message.Pop ();
00129
00130
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 }