dbus/mono ErrorMessage.cs, NONE, 1.1 SignalAttribute.cs, NONE,
1.1 Connection.cs, 1.5, 1.6 Handler.cs, 1.2,
1.3 InterfaceProxy.cs, 1.1, 1.2 Makefile.am, 1.4,
1.5 Message.cs, 1.7, 1.8 ProxyBuilder.cs, 1.4, 1.5 Service.cs,
1.3, 1.4 Signal.cs, 1.1, 1.2
Owen Fraser-Green
ow3n at pdx.freedesktop.org
Fri Mar 26 07:26:01 PST 2004
- Previous message: dbus/mono/DBusType Byte.cs, 1.3, 1.4 Int32.cs, 1.2, 1.3 Int64.cs,
1.2, 1.3 UInt32.cs, 1.2, 1.3 UInt64.cs, 1.2, 1.3
- Next message: dbus ChangeLog,1.463,1.464
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/dbus/dbus/mono
In directory pdx:/tmp/cvs-serv13016
Modified Files:
Connection.cs Handler.cs InterfaceProxy.cs Makefile.am
Message.cs ProxyBuilder.cs Service.cs Signal.cs
Added Files:
ErrorMessage.cs SignalAttribute.cs
Log Message:
Added signal support.
--- NEW FILE: ErrorMessage.cs ---
namespace DBus
{
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
public class ErrorMessage : Message
{
public ErrorMessage() : base(MessageType.Error)
{
}
internal ErrorMessage(IntPtr rawMessage, Service service) : base(rawMessage, service)
{
}
public ErrorMessage(Service service) : base(MessageType.Error, service)
{
}
public new string Name
{
get {
if (this.name == null) {
this.name = Marshal.PtrToStringAnsi(dbus_message_get_error_name(RawMessage));
}
return this.name;
}
set {
if (value != this.name) {
dbus_message_set_error_name(RawMessage, value);
this.name = value;
}
}
}
[DllImport("dbus-1")]
private extern static bool dbus_message_set_error_name(IntPtr rawMessage, string name);
[DllImport("dbus-1")]
private extern static IntPtr dbus_message_get_error_name(IntPtr rawMessage);
}
}
--- NEW FILE: SignalAttribute.cs ---
using System;
namespace DBus
{
[AttributeUsage(AttributeTargets.Event, AllowMultiple=false, Inherited=true)] public class SignalAttribute : Attribute
{
public SignalAttribute()
{
}
}
}
Index: Connection.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Connection.cs,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- a/Connection.cs 23 Mar 2004 12:10:32 -0000 1.5
+++ b/Connection.cs 26 Mar 2004 15:25:59 -0000 1.6
@@ -42,6 +42,11 @@
SetupWithMain();
}
+ public void Flush()
+ {
+ dbus_connection_flush(RawConnection);
+ }
+
public void SetupWithMain()
{
dbus_connection_setup_with_g_main(RawConnection, IntPtr.Zero);
Index: Handler.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Handler.cs,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- a/Handler.cs 23 Mar 2004 18:07:48 -0000 1.2
+++ b/Handler.cs 26 Mar 2004 15:25:59 -0000 1.3
@@ -6,6 +6,13 @@
using System.Reflection;
using System.Collections;
+ internal enum Result
+ {
+ Handled = 0,
+ NotYetHandled = 1,
+ NeedMemory = 2
+ }
+
internal class Handler
{
private string[] path = null;
@@ -15,7 +22,6 @@
private DBusObjectPathVTable vTable;
private Connection connection;
private Service service;
- private DBusHandleMessageFunction filterCalled;
internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
IntPtr userData);
@@ -24,18 +30,6 @@
IntPtr rawMessage,
IntPtr userData);
- internal delegate int DBusHandleMessageFunction(IntPtr rawConnection,
- IntPtr rawMessage,
- IntPtr userData);
-
-
- private enum Result
- {
- Handled = 0,
- NotYetHandled = 1,
- NeedMemory = 2
- }
-
[StructLayout (LayoutKind.Sequential)]
private struct DBusObjectPathVTable
{
@@ -67,8 +61,8 @@
}
public Handler(object handledObject,
- string pathName,
- Service service)
+ string pathName,
+ Service service)
{
Service = service;
Connection = service.Connection;
@@ -88,14 +82,22 @@
ref vTable,
IntPtr.Zero))
throw new OutOfMemoryException();
-
- // Setup the filter function
- this.filterCalled = new DBusHandleMessageFunction(Filter_Called);
- if (!dbus_connection_add_filter(Connection.RawConnection,
- this.filterCalled,
- IntPtr.Zero,
- IntPtr.Zero))
- throw new OutOfMemoryException();
+
+ 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);
+ }
+ }
}
public object HandledObject
@@ -113,21 +115,6 @@
this.introspector = Introspector.GetIntrospector(value.GetType());
}
}
-
- public int Filter_Called(IntPtr rawConnection,
- IntPtr rawMessage,
- IntPtr userData)
- {
- Message message = Message.Wrap(rawMessage, Service);
-
- if (message.Type == Message.MessageType.Signal) {
- Signal signal = (Signal) message;
- } else if (message.Type == Message.MessageType.MethodCall) {
- MethodCall methodCall = (MethodCall) message;
- }
-
- return (int) Result.NotYetHandled;
- }
public void Unregister_Called(IntPtr rawConnection,
IntPtr userData)
@@ -143,7 +130,8 @@
switch (message.Type) {
case Message.MessageType.Signal:
- System.Console.WriteLine("FIXME: Signal called.");
+ // We're not interested in signals here because we're the ones
+ // that generate them!
break;
case Message.MessageType.MethodCall:
return (int) HandleMethod((MethodCall) message);
@@ -216,7 +204,7 @@
{
this.service = value;
}
- }
+ }
[DllImport ("dbus-1")]
private extern static bool dbus_connection_register_object_path (IntPtr rawConnection, string[] path, ref DBusObjectPathVTable vTable, IntPtr userData);
@@ -224,11 +212,5 @@
[DllImport ("dbus-1")]
private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection, string[] path);
- [DllImport ("dbus-1")]
- private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
- DBusHandleMessageFunction filter,
- IntPtr userData,
- IntPtr freeData);
-
}
}
Index: InterfaceProxy.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/InterfaceProxy.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/InterfaceProxy.cs 23 Mar 2004 18:07:48 -0000 1.1
+++ b/InterfaceProxy.cs 26 Mar 2004 15:25:59 -0000 1.2
@@ -8,7 +8,8 @@
{
private static Hashtable interfaceProxies = new Hashtable();
private Hashtable methods = null;
-
+ private Hashtable signals = null;
+
private string interfaceName;
private InterfaceProxy(Type type)
@@ -17,17 +18,34 @@
InterfaceAttribute interfaceAttribute = (InterfaceAttribute) attributes[0];
this.interfaceName = interfaceAttribute.InterfaceName;
AddMethods(type);
+ AddSignals(type);
}
+ // Add all the events with Signal attributes
+ private void AddSignals(Type type)
+ {
+ this.signals = new Hashtable();
+ foreach (EventInfo signal in type.GetEvents(BindingFlags.Public |
+ BindingFlags.Instance |
+ BindingFlags.DeclaredOnly)) {
+ object[] attributes = signal.GetCustomAttributes(typeof(SignalAttribute), false);
+ if (attributes.GetLength(0) > 0) {
+ MethodInfo invoke = signal.EventHandlerType.GetMethod("Invoke");
+ signals.Add(signal.Name + " " + GetSignature(invoke), signal);
+ }
+ }
+ }
+
+ // Add all the methods with Method attributes
private void AddMethods(Type type)
{
this.methods = new Hashtable();
foreach (MethodInfo method in type.GetMethods(BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly)) {
- object[] attributes = method.GetCustomAttributes(typeof(MethodAttribute), true);
+ object[] attributes = method.GetCustomAttributes(typeof(MethodAttribute), false);
if (attributes.GetLength(0) > 0) {
- methods.Add(GetKey(method), method);
+ methods.Add(method.Name + " " + GetSignature(method), method);
}
}
}
@@ -46,16 +64,26 @@
{
return this.Methods.Contains(key);
}
+
+ public bool HasSignal(string key)
+ {
+ return this.Signals.Contains(key);
+ }
+
+ public EventInfo GetSignal(string key)
+ {
+ return (EventInfo) this.Signals[key];
+ }
public MethodInfo GetMethod(string key)
{
return (MethodInfo) this.Methods[key];
}
- private string GetKey(MethodInfo method)
+ public static string GetSignature(MethodInfo method)
{
ParameterInfo[] pars = method.GetParameters();
- string key = method.Name + " ";
+ string key = "";
foreach (ParameterInfo par in pars) {
if (!par.IsOut) {
@@ -73,6 +101,13 @@
return this.methods;
}
}
+
+ public Hashtable Signals
+ {
+ get {
+ return this.signals;
+ }
+ }
public string InterfaceName
{
Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/mono/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/Makefile.am 23 Mar 2004 18:07:48 -0000 1.4
+++ b/Makefile.am 26 Mar 2004 15:25:59 -0000 1.5
@@ -10,6 +10,7 @@
Custom.cs \
DBusException.cs \
Error.cs \
+ ErrorMessage.cs \
Handler.cs \
InterfaceAttribute.cs \
InterfaceProxy.cs \
@@ -22,6 +23,7 @@
Server.cs \
Service.cs \
Signal.cs \
+ SignalAttribute.cs \
DBusType/IDBusType.cs \
DBusType/Array.cs \
DBusType/Boolean.cs \
Index: Message.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Message.cs,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- a/Message.cs 23 Mar 2004 18:07:48 -0000 1.7
+++ b/Message.cs 26 Mar 2004 15:25:59 -0000 1.8
@@ -80,14 +80,23 @@
}
// If it doesn't exist then create a new Message around it
Message message = null;
+ MessageType messageType = (MessageType) dbus_message_get_type(rawMessage);
- switch ((MessageType) dbus_message_get_type(rawMessage)) {
+ switch (messageType) {
case MessageType.Signal:
message = new Signal(rawMessage, service);
break;
case MessageType.MethodCall:
message = new MethodCall(rawMessage, service);
break;
+ case MessageType.MethodReturn:
+ message = new MethodReturn(rawMessage, service);
+ break;
+ case MessageType.Error:
+ message = new ErrorMessage(rawMessage, service);
+ break;
+ default:
+ throw new ApplicationException("Unknown message type to wrap: " + messageType);
}
return message;
@@ -140,6 +149,8 @@
{
if (!dbus_connection_send (Service.Connection.RawConnection, RawMessage, ref serial))
throw new OutOfMemoryException ();
+
+ Service.Connection.Flush();
}
public void Send()
@@ -245,23 +256,19 @@
protected virtual string Name
{
- set
- {
- if (value != this.name)
- {
- dbus_message_set_member (RawMessage, value);
- this.name = value;
- }
+ set {
+ if (value != this.name) {
+ dbus_message_set_member(RawMessage, value);
+ this.name = value;
}
- get
- {
- if (this.name == null) {
- this.name = Marshal.PtrToStringAnsi(dbus_message_get_member(RawMessage));
- }
-
-
- return this.name;
+ }
+ get {
+ if (this.name == null) {
+ this.name = Marshal.PtrToStringAnsi(dbus_message_get_member(RawMessage));
}
+
+ return this.name;
+ }
}
public string Key
@@ -356,7 +363,7 @@
private extern static IntPtr dbus_message_get_interface(IntPtr rawMessage);
[DllImport("dbus-1")]
- private extern static bool dbus_message_set_member (IntPtr rawMessage, string name);
+ private extern static bool dbus_message_set_member(IntPtr rawMessage, string name);
[DllImport("dbus-1")]
private extern static IntPtr dbus_message_get_member(IntPtr rawMessage);
Index: ProxyBuilder.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/ProxyBuilder.cs,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- a/ProxyBuilder.cs 24 Mar 2004 14:42:41 -0000 1.4
+++ b/ProxyBuilder.cs 26 Mar 2004 15:25:59 -0000 1.5
@@ -14,20 +14,27 @@
private string pathName = null;
private Type type = null;
private Introspector introspector = null;
- private static AssemblyBuilder proxyAssembly;
private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name",
new Type[0]);
private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
new Type[0]);
+ private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
+ new Type[] {typeof(Service.SignalCalledHandler)});
+ private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
+ new Type[0]);
private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
new Type[0]);
+ private static MethodInfo Message_KeyMI = typeof(Message).GetMethod("get_Key",
+ new Type[0]);
private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
new Type[0]);
private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
new Type[] {typeof(DBusType.IDBusType)});
private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
new Type[0]);
+ private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
+ new Type[0]);
private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
new Type[0]);
private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
@@ -42,8 +49,19 @@
typeof(string),
typeof(string),
typeof(string)});
+ private static ConstructorInfo Signal_C = typeof(Signal).GetConstructor(new Type[] {typeof(Service),
+ typeof(string),
+ typeof(string),
+ typeof(string)});
+ private static ConstructorInfo Service_SignalCalledHandlerC = typeof(Service.SignalCalledHandler).GetConstructor(new Type[] {typeof(object),
+ typeof(System.IntPtr)});
+ private static MethodInfo String_opEqualityMI = typeof(System.String).GetMethod("op_Equality",
+ new Type[] {typeof(string),
+ typeof(string)});
+ private static MethodInfo MulticastDelegate_opInequalityMI = typeof(System.MulticastDelegate).GetMethod("op_Inequality",
+ new Type[] {typeof(System.MulticastDelegate),
+ typeof(System.MulticastDelegate)});
-
public ProxyBuilder(Service service, Type type, string pathName)
{
@@ -53,6 +71,163 @@
this.introspector = Introspector.GetIntrospector(type);
}
+ private MethodInfo BuildSignalCalled(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
+ {
+ Type[] parTypes = {typeof(Signal)};
+ MethodBuilder methodBuilder = typeB.DefineMethod("Service_SignalCalled",
+ MethodAttributes.Private |
+ MethodAttributes.HideBySig,
+ typeof(void),
+ parTypes);
+
+ ILGenerator generator = methodBuilder.GetILGenerator();
+
+ LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
+ enumeratorL.SetLocalSymInfo("enumerator");
+
+ Label wrongPath = generator.DefineLabel();
+ //generator.EmitWriteLine("if (signal.PathName == pathName) {");
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.EmitCall(OpCodes.Callvirt, Signal_PathNameMI, null);
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldfld, pathF);
+ generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
+ generator.Emit(OpCodes.Brfalse, wrongPath);
+
+ int localOffset = 1;
+
+ foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
+ InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
+ foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
+ EventInfo eventE = (EventInfo) signalEntry.Value;
+ // This is really cheeky since we need to grab the event as a private field.
+ FieldInfo eventF = this.type.GetField(eventE.Name,
+ BindingFlags.NonPublic|
+ BindingFlags.Instance);
+
+ MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
+
+ ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
+ parTypes = new Type[pars.Length];
+ for (int parN = 0; parN < pars.Length; parN++) {
+ parTypes[parN] = pars[parN].ParameterType;
+ LocalBuilder parmL = generator.DeclareLocal(parTypes[parN]);
+ parmL.SetLocalSymInfo(pars[parN].Name);
+ }
+
+ Label skip = generator.DefineLabel();
+ //generator.EmitWriteLine(" if (SelectedIndexChanged != null) {");
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldfld, eventF);
+ generator.Emit(OpCodes.Ldnull);
+ generator.EmitCall(OpCodes.Call, MulticastDelegate_opInequalityMI, null);
+ generator.Emit(OpCodes.Brfalse, skip);
+
+ //generator.EmitWriteLine(" if (signal.Key == 'la i')");
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.EmitCall(OpCodes.Callvirt, Message_KeyMI, null);
+ generator.Emit(OpCodes.Ldstr, eventE.Name + " " + InterfaceProxy.GetSignature(eventHandler_InvokeMI));
+ generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
+ generator.Emit(OpCodes.Brfalse, skip);
+
+ //generator.EmitWriteLine("IEnumerator enumerator = signal.Arguments.GetEnumerator()");
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
+ generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
+ generator.Emit(OpCodes.Stloc_0);
+
+ for (int parN = 0; parN < pars.Length; parN++) {
+ ParameterInfo par = pars[parN];
+ if (!par.IsOut) {
+ EmitSignalIn(generator, par.ParameterType, parN + localOffset, serviceF);
+ }
+ }
+
+ //generator.EmitWriteLine(" SelectedIndexChanged(selectedIndex)");
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldfld, eventF);
+ for (int parN = 0; parN < pars.Length; parN++) {
+ generator.Emit(OpCodes.Ldloc_S, parN + localOffset);
+ }
+
+ generator.EmitCall(OpCodes.Callvirt, eventHandler_InvokeMI, null);
+
+ generator.MarkLabel(skip);
+ //generator.EmitWriteLine(" }");
+
+ localOffset += pars.Length;
+ }
+ }
+
+ generator.MarkLabel(wrongPath);
+ //generator.EmitWriteLine("}");
+
+ //generator.EmitWriteLine("return");
+ generator.Emit(OpCodes.Ret);
+
+ return methodBuilder;
+ }
+
+ private void BuildSignalHandler(EventInfo eventE,
+ InterfaceProxy interfaceProxy,
+ ref TypeBuilder typeB,
+ FieldInfo serviceF,
+ FieldInfo pathF)
+ {
+ MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
+ ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
+ Type[] parTypes = new Type[pars.Length];
+ for (int parN = 0; parN < pars.Length; parN++) {
+ parTypes[parN] = pars[parN].ParameterType;
+ }
+
+ // Generate the code
+ MethodBuilder methodBuilder = typeB.DefineMethod("Proxy_" + eventE.Name,
+ MethodAttributes.Public |
+ MethodAttributes.HideBySig |
+ MethodAttributes.Virtual,
+ typeof(void),
+ parTypes);
+ ILGenerator generator = methodBuilder.GetILGenerator();
+
+ for (int parN = 0; parN < pars.Length; parN++) {
+ methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
+ }
+
+ // Generate the locals
+ LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
+ methodCallL.SetLocalSymInfo("signal");
+ LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
+
+ //generator.EmitWriteLine("Signal signal = new Signal(...)");
+ generator.Emit(OpCodes.Ldsfld, serviceF);
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldfld, pathF);
+ generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
+ generator.Emit(OpCodes.Ldstr, eventE.Name);
+ generator.Emit(OpCodes.Newobj, Signal_C);
+ generator.Emit(OpCodes.Stloc_0);
+
+ //generator.EmitWriteLine("signal.Arguments.InitAppending()");
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
+ generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
+
+ for (int parN = 0; parN < pars.Length; parN++) {
+ ParameterInfo par = pars[parN];
+ if (!par.IsOut) {
+ EmitIn(generator, par.ParameterType, parN, serviceF);
+ }
+ }
+
+ //generator.EmitWriteLine("signal.Send()");
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null);
+
+ //generator.EmitWriteLine("return");
+ generator.Emit(OpCodes.Ret);
+ }
+
private void BuildMethod(MethodInfo method,
InterfaceProxy interfaceProxy,
ref TypeBuilder typeB,
@@ -145,6 +320,28 @@
typeB.DefineMethodOverride(methodBuilder, method);
}
+ private void EmitSignalIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
+ {
+ //generator.EmitWriteLine("enumerator.MoveNext()");
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
+
+ Type outParType = Arguments.MatchType(parType);
+ //generator.EmitWriteLine("int selectedIndex = (int) ((DBusType.IDBusType) enumerator.Current).Get(typeof(int))");
+ generator.Emit(OpCodes.Pop);
+ generator.Emit(OpCodes.Ldloc_0);
+ generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
+ generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
+ generator.Emit(OpCodes.Ldtoken, parType);
+ generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
+ generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
+ // Call the DBusType EmitMarshalOut to make it emit itself
+ object[] pars = new object[] {generator, parType, true};
+ outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
+ generator.Emit(OpCodes.Stloc_S, parN);
+ }
+
+
private void EmitIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
{
Type inParType = Arguments.MatchType(parType);
@@ -191,7 +388,7 @@
}
}
- public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
+ public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI)
{
Type[] pars = {typeof(Service), typeof(string)};
ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
@@ -201,23 +398,102 @@
ILGenerator generator = constructor.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Call, this.introspector.Constructor);
+ //generator.EmitWriteLine("service = myService");
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stsfld, serviceF);
+ //generator.EmitWriteLine("this.pathName = pathName");
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_2);
generator.Emit(OpCodes.Stfld, pathF);
+
+ //generator.EmitWriteLine("myService.SignalCalled += new Service.SignalCalledHandler(Service_SignalCalled)");
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldftn, signalCalledMI);
+ generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
+ generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
+ //generator.EmitWriteLine("return");
+ generator.Emit(OpCodes.Ret);
+ }
+
+ public void BuildSignalConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
+ {
+ Type[] pars = {typeof(Service), typeof(string)};
+ ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName |
+ MethodAttributes.Public,
+ CallingConventions.Standard, pars);
+
+ ILGenerator generator = constructor.GetILGenerator();
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Call, this.introspector.Constructor);
+ //generator.EmitWriteLine("service = myService");
+ generator.Emit(OpCodes.Ldarg_1);
+ generator.Emit(OpCodes.Stsfld, serviceF);
+ //generator.EmitWriteLine("this.pathName = pathName");
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldarg_2);
+ generator.Emit(OpCodes.Stfld, pathF);
+
+ //generator.EmitWriteLine("return");
generator.Emit(OpCodes.Ret);
}
- public object GetProxy()
- {
+ public object GetSignalProxy()
+ {
+ Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
+
+ if (proxyType == null) {
+ // Build the type
+ TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".SignalProxy",
+ TypeAttributes.Public,
+ this.type);
+
+ FieldBuilder serviceF = typeB.DefineField("service",
+ typeof(Service),
+ FieldAttributes.Private |
+ FieldAttributes.Static);
+ FieldBuilder pathF = typeB.DefineField("pathName",
+ typeof(string),
+ FieldAttributes.Private);
+
+ BuildSignalConstructor(ref typeB, serviceF, pathF);
+
+ // Build the signal handlers
+ foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
+ InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
+ foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
+ EventInfo eventE = (EventInfo) signalEntry.Value;
+ BuildSignalHandler(eventE, interfaceProxy, ref typeB, serviceF, pathF);
+ }
+ }
+
+ proxyType = typeB.CreateType();
- Type proxyType = ProxyAssembly.GetType(ProxyName);
+ // Uncomment the following line to produce a DLL of the
+ // constructed assembly which can then be examined using
+ // monodis. Note that in order for this to work you should copy
+ // the client assembly as a dll file so that monodis can pick it
+ // up.
+ //Service.ProxyAssembly.Save("proxy.dll");
+ }
+
+ Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
+ object [] pars = new object[] {Service, pathName};
+
+ ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
+ object instance = constructor.Invoke(pars);
+ return instance;
+ }
+
+
+ public object GetProxy()
+ {
+ Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".Proxy");
if (proxyType == null) {
// Build the type
- TypeBuilder typeB = ServiceModuleBuilder.DefineType(ProxyName, TypeAttributes.Public, this.type);
+ TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".Proxy", TypeAttributes.Public, this.type);
FieldBuilder serviceF = typeB.DefineField("service",
typeof(Service),
@@ -227,7 +503,8 @@
typeof(string),
FieldAttributes.Private);
- BuildConstructor(ref typeB, serviceF, pathF);
+ MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
+ BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI);
// Build the methods
foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
@@ -245,7 +522,7 @@
// monodis. Note that in order for this to work you should copy
// the client assembly as a dll file so that monodis can pick it
// up.
- //ProxyAssembly.Save("proxy.dll");
+ //Service.ProxyAssembly.Save("proxy.dll");
}
Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
@@ -255,43 +532,18 @@
object instance = constructor.Invoke(pars);
return instance;
}
-
- private ModuleBuilder ServiceModuleBuilder
- {
- get {
- if (Service.module == null) {
- Service.module = ProxyAssembly.DefineDynamicModule(Service.Name, "proxy.dll", true);
- }
-
- return Service.module;
- }
- }
-
- private Service Service
+
+ private Service Service
{
get {
return this.service;
}
}
- private string ProxyName
- {
- get {
- return this.introspector.ToString() + ".Proxy";
- }
- }
-
- private AssemblyBuilder ProxyAssembly
+ private string ObjectName
{
get {
- if (proxyAssembly == null){
- AssemblyName assemblyName = new AssemblyName();
- assemblyName.Name = "DBusProxy";
- proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
- AssemblyBuilderAccess.RunAndSave);
- }
-
- return proxyAssembly;
+ return this.introspector.ToString();
}
}
}
Index: Service.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Service.cs,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/Service.cs 24 Mar 2004 13:15:20 -0000 1.3
+++ b/Service.cs 26 Mar 2004 15:25:59 -0000 1.4
@@ -4,6 +4,7 @@
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections;
+ using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
@@ -13,12 +14,20 @@
private string name;
private bool local = false;
private Hashtable registeredHandlers = new Hashtable();
- internal ModuleBuilder module = null;
+ private delegate int DBusHandleMessageFunction(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData);
+ private DBusHandleMessageFunction filterCalled;
+ public delegate void SignalCalledHandler(Signal signal);
+ public event SignalCalledHandler SignalCalled;
+ private static AssemblyBuilder proxyAssembly;
+ private ModuleBuilder module = null;
internal Service(string name, Connection connection)
{
this.name = name;
this.connection = connection;
+ AddFilter();
}
public Service(Connection connection, string name)
@@ -67,9 +76,7 @@
public void RegisterObject(object handledObject,
string pathName)
{
- Handler handler = new Handler(handledObject,
- pathName,
- this);
+ Handler handler = new Handler(handledObject, pathName, this);
registeredHandlers.Add(handledObject, handler);
}
@@ -89,6 +96,38 @@
return proxy;
}
+ private void AddFilter()
+ {
+ // Setup the filter function
+ this.filterCalled = new DBusHandleMessageFunction(Service_FilterCalled);
+ if (!dbus_connection_add_filter(Connection.RawConnection,
+ this.filterCalled,
+ IntPtr.Zero,
+ IntPtr.Zero))
+ throw new OutOfMemoryException();
+
+ // Add a match for signals. FIXME: Can we filter the service?
+ string rule = "type='signal'";
+ dbus_bus_add_match(connection.RawConnection, rule, IntPtr.Zero);
+ }
+
+ private int Service_FilterCalled(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData)
+ {
+ Message message = Message.Wrap(rawMessage, this);
+
+ if (message.Type == Message.MessageType.Signal) {
+ // We're only interested in signals
+ Signal signal = (Signal) message;
+ if (SignalCalled != null) {
+ SignalCalled(signal);
+ }
+ }
+
+ return (int) Result.NotYetHandled;
+ }
+
public string Name
{
get
@@ -110,10 +149,51 @@
}
}
- [DllImport ("dbus-1")]
- private extern static int dbus_bus_acquire_service (IntPtr rawConnection, string serviceName, uint flags, ref Error error);
+ internal AssemblyBuilder ProxyAssembly
+ {
+ get {
+ if (proxyAssembly == null){
+ AssemblyName assemblyName = new AssemblyName();
+ assemblyName.Name = "DBusProxy";
+ proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
+ AssemblyBuilderAccess.RunAndSave);
+ }
+
+ return proxyAssembly;
+ }
+ }
+
+ internal ModuleBuilder Module
+ {
+ get {
+ if (this.module == null) {
+ this.module = ProxyAssembly.DefineDynamicModule(Name, "proxy.dll", true);
+ }
+
+ return this.module;
+ }
+ }
+
+ [DllImport("dbus-1")]
+ private extern static int dbus_bus_acquire_service(IntPtr rawConnection,
+ string serviceName,
+ uint flags, ref Error error);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_bus_service_exists(IntPtr rawConnection,
+ string serviceName,
+ ref Error error);
+
+ [DllImport("dbus-1")]
+ private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
+ DBusHandleMessageFunction filter,
+ IntPtr userData,
+ IntPtr freeData);
+
+ [DllImport("dbus-1")]
+ private extern static void dbus_bus_add_match(IntPtr rawConnection,
+ string rule,
+ IntPtr erro);
- [DllImport ("dbus-1")]
- private extern static bool dbus_bus_service_exists (IntPtr rawConnection, string serviceName, ref Error error);
}
}
Index: Signal.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Signal.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/Signal.cs 23 Mar 2004 12:10:32 -0000 1.1
+++ b/Signal.cs 26 Mar 2004 15:25:59 -0000 1.2
@@ -18,6 +18,23 @@
{
}
+ public Signal(Service service, string pathName, string interfaceName, string name)
+ {
+ this.service = service;
+
+ RawMessage = dbus_message_new_signal(pathName, interfaceName, name);
+
+ if (RawMessage == IntPtr.Zero) {
+ throw new OutOfMemoryException();
+ }
+
+ this.pathName = pathName;
+ this.interfaceName = interfaceName;
+ this.name = name;
+
+ dbus_message_unref(RawMessage);
+ }
+
public new string PathName
{
get
@@ -56,5 +73,7 @@
base.Name = value;
}
}
+ [DllImport("dbus-1")]
+ private extern static IntPtr dbus_message_new_signal(string pathName, string interfaceName, string name);
}
}
- Previous message: dbus/mono/DBusType Byte.cs, 1.3, 1.4 Int32.cs, 1.2, 1.3 Int64.cs,
1.2, 1.3 UInt32.cs, 1.2, 1.3 UInt64.cs, 1.2, 1.3
- Next message: dbus ChangeLog,1.463,1.464
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dbus-commit
mailing list