dbus/mono/Handler.cs

248 lines
6 KiB
C#
Raw Normal View History

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
}
2004-05-23 21:33:14 +00:00
internal class Handler : IDisposable
2004-03-23 12:10:32 +00:00
{
private string[] path = null;
private string pathName = null;
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
private bool disposed = false;
2004-03-23 12:10:32 +00:00
internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
IntPtr userData);
internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
IntPtr rawMessage,
IntPtr userData);
[StructLayout (LayoutKind.Sequential)]
private struct DBusObjectPathVTable
{
public DBusObjectPathUnregisterFunction unregisterFunction;
public DBusObjectPathMessageFunction messageFunction;
public IntPtr padding1;
public IntPtr padding2;
public IntPtr padding3;
public IntPtr padding4;
public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
DBusObjectPathMessageFunction messageFunction)
{
this.unregisterFunction = unregisterFunction;
this.messageFunction = messageFunction;
this.padding1 = IntPtr.Zero;
this.padding2 = IntPtr.Zero;
this.padding3 = IntPtr.Zero;
this.padding4 = IntPtr.Zero;
}
}
2004-05-23 21:33:14 +00:00
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposed) {
if (disposing) {
// Clean up managed resources
}
service = null;
// Clean up unmanaged resources
if (Connection != null && Connection.RawConnection != IntPtr.Zero && path != null) {
dbus_connection_unregister_object_path(Connection.RawConnection,
Path);
}
connection = null;
introspector = null;
handledObject = null;
}
disposed = true;
}
2004-03-23 12:10:32 +00:00
~Handler()
{
2004-05-23 21:33:14 +00:00
Dispose(false);
2004-03-23 12:10:32 +00:00
}
public Handler(object handledObject,
2004-03-26 15:25:59 +00:00
string pathName,
Service service)
2004-03-23 12:10:32 +00:00
{
Service = service;
Connection = service.Connection;
HandledObject = handledObject;
// Strip the leading / off if there is one and get the path as an array
pathName = pathName.TrimStart('/');
this.path = pathName.Split('/');
this.pathName = "/" + pathName;
2004-04-03 22:00:40 +00:00
2004-03-23 12:10:32 +00:00
// Create the vTable and register the path
vTable = new DBusObjectPathVTable(new DBusObjectPathUnregisterFunction(Unregister_Called),
new DBusObjectPathMessageFunction(Message_Called));
if (!dbus_connection_register_object_path(Connection.RawConnection,
Path,
ref vTable,
IntPtr.Zero))
throw new OutOfMemoryException();
2004-03-26 15:25:59 +00:00
RegisterSignalHandlers();
}
private void RegisterSignalHandlers()
{
ProxyBuilder proxyBuilder = new ProxyBuilder(Service, HandledObject.GetType(), this.pathName);
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
{
get {
return this.handledObject;
}
2004-03-23 12:10:32 +00:00
set {
this.handledObject = value;
object[] attributes;
// 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);
switch (message.Type) {
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;
case Message.MessageType.MethodCall:
return (int) HandleMethod((MethodCall) message);
}
return (int) Result.NotYetHandled;
}
private Result HandleMethod(MethodCall methodCall)
{
methodCall.Service = service;
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;
}
MethodInfo method = interfaceProxy.GetMethod(methodCall.Key);
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);
// Create the reply and send it
MethodReturn methodReturn = new MethodReturn(methodCall);
methodReturn.Arguments.AppendResults(method, retVal, args);
methodReturn.Send();
return Result.Handled;
}
internal string[] Path
{
get
{
return path;
}
}
public string PathName
{
get
{
return pathName;
}
}
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
[DllImport ("dbus-1")]
private extern static bool dbus_connection_register_object_path (IntPtr rawConnection, string[] path, ref DBusObjectPathVTable vTable, IntPtr userData);
[DllImport ("dbus-1")]
private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection, string[] path);
}
}