2004-03-23 12:10:32 +00:00
|
|
|
namespace DBus
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
2004-03-26 15:25:59 +00:00
|
|
|
internal enum Result
|
|
|
|
|
{
|
|
|
|
|
Handled = 0,
|
|
|
|
|
NotYetHandled = 1,
|
|
|
|
|
NeedMemory = 2
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-09 04:36:15 +00:00
|
|
|
internal class Handler
|
2004-03-23 12:10:32 +00:00
|
|
|
{
|
2004-06-07 11:40:20 +00:00
|
|
|
private string path = null;
|
2004-03-23 12:10:32 +00:00
|
|
|
private Introspector introspector = null;
|
|
|
|
|
private object handledObject = null;
|
|
|
|
|
private DBusObjectPathVTable vTable;
|
|
|
|
|
private Connection connection;
|
|
|
|
|
private Service service;
|
2004-05-23 21:33:14 +00:00
|
|
|
|
2005-03-09 04:36:15 +00:00
|
|
|
// We need to hold extra references to these callbacks so that they don't
|
|
|
|
|
// get garbage collected before they are called back into from unmanaged
|
|
|
|
|
// code.
|
|
|
|
|
private DBusObjectPathUnregisterFunction unregister_func;
|
|
|
|
|
private DBusObjectPathMessageFunction message_func;
|
2004-03-23 12:10:32 +00:00
|
|
|
|
|
|
|
|
public Handler(object handledObject,
|
2004-06-07 11:40:20 +00:00
|
|
|
string path,
|
2004-03-26 15:25:59 +00:00
|
|
|
Service service)
|
2004-03-23 12:10:32 +00:00
|
|
|
{
|
|
|
|
|
Service = service;
|
|
|
|
|
Connection = service.Connection;
|
|
|
|
|
HandledObject = handledObject;
|
2004-06-07 11:40:20 +00:00
|
|
|
this.path = path;
|
2004-04-03 22:00:40 +00:00
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
// Create the vTable and register the path
|
2005-03-09 04:36:15 +00:00
|
|
|
this.unregister_func = new DBusObjectPathUnregisterFunction (Unregister_Called);
|
|
|
|
|
this.message_func = new DBusObjectPathMessageFunction (Message_Called);
|
2004-03-26 15:25:59 +00:00
|
|
|
|
2005-03-09 04:36:15 +00:00
|
|
|
vTable = new DBusObjectPathVTable (this.unregister_func, this.message_func);
|
|
|
|
|
Connection.RegisterObjectPath (Path, vTable);
|
2004-03-26 15:25:59 +00:00
|
|
|
RegisterSignalHandlers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RegisterSignalHandlers()
|
|
|
|
|
{
|
2004-06-07 11:40:20 +00:00
|
|
|
ProxyBuilder proxyBuilder = new ProxyBuilder(Service, HandledObject.GetType(), Path);
|
2004-03-26 15:25:59 +00:00
|
|
|
|
|
|
|
|
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
|
|
|
|
|
InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
|
|
|
|
|
foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
|
|
|
|
|
EventInfo eventE = (EventInfo) signalEntry.Value;
|
|
|
|
|
Delegate del = Delegate.CreateDelegate(eventE.EventHandlerType, proxyBuilder.GetSignalProxy(), "Proxy_" + eventE.Name);
|
|
|
|
|
eventE.AddEventHandler(HandledObject, del);
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public object HandledObject
|
|
|
|
|
{
|
2004-03-23 18:07:48 +00:00
|
|
|
get {
|
|
|
|
|
return this.handledObject;
|
|
|
|
|
}
|
2004-03-23 12:10:32 +00:00
|
|
|
|
2004-03-23 18:07:48 +00:00
|
|
|
set {
|
|
|
|
|
this.handledObject = value;
|
|
|
|
|
|
|
|
|
|
// Register the methods
|
|
|
|
|
this.introspector = Introspector.GetIntrospector(value.GetType());
|
|
|
|
|
}
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Unregister_Called(IntPtr rawConnection,
|
|
|
|
|
IntPtr userData)
|
|
|
|
|
{
|
2004-05-23 21:33:14 +00:00
|
|
|
if (service != null) {
|
|
|
|
|
service.UnregisterObject(HandledObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
path = null;
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int Message_Called(IntPtr rawConnection,
|
|
|
|
|
IntPtr rawMessage,
|
|
|
|
|
IntPtr userData)
|
|
|
|
|
{
|
|
|
|
|
Message message = Message.Wrap(rawMessage, Service);
|
2005-03-09 04:36:15 +00:00
|
|
|
Result res = Result.NotYetHandled;
|
2004-03-23 12:10:32 +00:00
|
|
|
|
|
|
|
|
switch (message.Type) {
|
2005-03-09 04:36:15 +00:00
|
|
|
case Message.MessageType.MethodCall:
|
|
|
|
|
res = HandleMethod ((MethodCall) message);
|
|
|
|
|
break;
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
case Message.MessageType.Signal:
|
2004-03-26 15:25:59 +00:00
|
|
|
// We're not interested in signals here because we're the ones
|
|
|
|
|
// that generate them!
|
2004-03-23 12:10:32 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-09 04:36:15 +00:00
|
|
|
message.Dispose ();
|
|
|
|
|
|
|
|
|
|
return (int) res;
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Result HandleMethod(MethodCall methodCall)
|
|
|
|
|
{
|
|
|
|
|
methodCall.Service = service;
|
2004-03-23 18:07:48 +00:00
|
|
|
|
|
|
|
|
InterfaceProxy interfaceProxy = this.introspector.GetInterface(methodCall.InterfaceName);
|
|
|
|
|
if (interfaceProxy == null || !interfaceProxy.HasMethod(methodCall.Key)) {
|
|
|
|
|
// No such interface here.
|
2004-03-23 12:10:32 +00:00
|
|
|
return Result.NotYetHandled;
|
|
|
|
|
}
|
2004-03-23 18:07:48 +00:00
|
|
|
|
|
|
|
|
MethodInfo method = interfaceProxy.GetMethod(methodCall.Key);
|
2004-08-31 03:59:14 +00:00
|
|
|
|
|
|
|
|
Message.Push (methodCall);
|
2004-03-23 12:10:32 +00:00
|
|
|
|
|
|
|
|
// Now call the method. FIXME: Error handling
|
|
|
|
|
object [] args = methodCall.Arguments.GetParameters(method);
|
|
|
|
|
object retVal = method.Invoke(this.handledObject, args);
|
|
|
|
|
|
2004-08-31 03:59:14 +00:00
|
|
|
Message.Pop ();
|
|
|
|
|
|
2004-03-23 12:10:32 +00:00
|
|
|
// Create the reply and send it
|
|
|
|
|
MethodReturn methodReturn = new MethodReturn(methodCall);
|
|
|
|
|
methodReturn.Arguments.AppendResults(method, retVal, args);
|
|
|
|
|
methodReturn.Send();
|
|
|
|
|
|
|
|
|
|
return Result.Handled;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-07 11:40:20 +00:00
|
|
|
internal string Path
|
2004-03-23 12:10:32 +00:00
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal Connection Connection
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.connection = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Service Service
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return service;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.service = value;
|
|
|
|
|
}
|
2004-03-26 15:25:59 +00:00
|
|
|
}
|
2004-03-23 12:10:32 +00:00
|
|
|
}
|
|
|
|
|
}
|