~ubuntu-branches/debian/jessie/banshee-community-extensions/jessie

« back to all changes in this revision

Viewing changes to .pc/0001-Use-DBus-instead-of-NDesk.DBus.patch/src/Telepathy/Banshee.Telepathy/NDesk.DBus/BusObject.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-09-20 18:45:46 UTC
  • mfrom: (1.2.9 upstream) (5.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20110920184546-3ahue2qplydc4t0e
Tags: 2.2.0-1
* [4940fab] Imported Upstream version 2.2.0
  + Notable bug fixes:
    - Karaoke: Fix crash when switching to Now Playing
    - Lyrics: Fix crash when switching to Now Playing

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006 Alp Toker <alp@atoker.com>
2
 
// This software is made available under the MIT License
3
 
// See COPYING for details
4
 
 
5
 
using System;
6
 
using System.Reflection;
7
 
using System.Reflection.Emit;
8
 
using System.Collections.Generic;
9
 
 
10
 
namespace NDesk.DBus
11
 
{
12
 
        class BusObject
13
 
        {
14
 
                protected Connection conn;
15
 
                string bus_name;
16
 
                ObjectPath object_path;
17
 
 
18
 
                //protected BusObject ()
19
 
                public BusObject ()
20
 
                {
21
 
                }
22
 
 
23
 
                public BusObject (Connection conn, string bus_name, ObjectPath object_path)
24
 
                {
25
 
                        this.conn = conn;
26
 
                        this.bus_name = bus_name;
27
 
                        this.object_path = object_path;
28
 
                }
29
 
 
30
 
                public Connection Connection
31
 
                {
32
 
                        get {
33
 
                                return conn;
34
 
                        }
35
 
                }
36
 
 
37
 
                public string BusName
38
 
                {
39
 
                        get {
40
 
                                return bus_name;
41
 
                        }
42
 
                }
43
 
 
44
 
                public ObjectPath Path
45
 
                {
46
 
                        get {
47
 
                                return object_path;
48
 
                        }
49
 
                }
50
 
 
51
 
                public void ToggleSignal (string iface, string member, Delegate dlg, bool adding)
52
 
                {
53
 
                        MatchRule rule = new MatchRule ();
54
 
                        rule.MessageType = MessageType.Signal;
55
 
                        rule.Fields.Add (FieldCode.Interface, new MatchTest (iface));
56
 
                        rule.Fields.Add (FieldCode.Member, new MatchTest (member));
57
 
                        rule.Fields.Add (FieldCode.Path, new MatchTest (object_path));
58
 
 
59
 
                        if (adding) {
60
 
                                if (conn.Handlers.ContainsKey (rule))
61
 
                                        conn.Handlers[rule] = Delegate.Combine (conn.Handlers[rule], dlg);
62
 
                                else {
63
 
                                        conn.Handlers[rule] = dlg;
64
 
                                        conn.AddMatch (rule.ToString ());
65
 
                                }
66
 
                        } else {
67
 
                                conn.Handlers[rule] = Delegate.Remove (conn.Handlers[rule], dlg);
68
 
                                if (conn.Handlers[rule] == null) {
69
 
                                        conn.RemoveMatch (rule.ToString ());
70
 
                                        conn.Handlers.Remove (rule);
71
 
                                }
72
 
                        }
73
 
                }
74
 
 
75
 
                public void SendSignal (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
76
 
                {
77
 
                        exception = null;
78
 
 
79
 
                        //TODO: don't ignore retVal, exception etc.
80
 
 
81
 
                        Signature outSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
82
 
 
83
 
                        Signal signal = new Signal (object_path, iface, member);
84
 
                        signal.message.Signature = outSig;
85
 
 
86
 
                        Message signalMsg = signal.message;
87
 
                        signalMsg.Body = writer.ToArray ();
88
 
 
89
 
                        conn.Send (signalMsg);
90
 
                }
91
 
 
92
 
                public object SendMethodCallOld (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
93
 
                {
94
 
                        exception = null;
95
 
 
96
 
                        //TODO: don't ignore retVal, exception etc.
97
 
 
98
 
                        Signature inSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
99
 
 
100
 
                        MethodCall method_call = new MethodCall (object_path, iface, member, bus_name, inSig);
101
 
 
102
 
                        Message callMsg = method_call.message;
103
 
                        callMsg.Body = writer.ToArray ();
104
 
 
105
 
                        //Invoke Code::
106
 
 
107
 
                        //TODO: complete out parameter support
108
 
                        /*
109
 
                        Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
110
 
                        Signature outParmSig = Signature.GetSig (outParmTypes);
111
 
 
112
 
                        if (outParmSig != Signature.Empty)
113
 
                                throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
114
 
                        */
115
 
 
116
 
                        Type[] outTypes = new Type[1];
117
 
                        outTypes[0] = retType;
118
 
 
119
 
                        //we default to always requiring replies for now, even though unnecessary
120
 
                        //this is to make sure errors are handled synchronously
121
 
                        //TODO: don't hard code this
122
 
                        bool needsReply = true;
123
 
 
124
 
                        //if (mi.ReturnType == typeof (void))
125
 
                        //      needsReply = false;
126
 
 
127
 
                        callMsg.ReplyExpected = needsReply;
128
 
                        callMsg.Signature = inSig;
129
 
 
130
 
                        if (!needsReply) {
131
 
                                conn.Send (callMsg);
132
 
                                return null;
133
 
                        }
134
 
 
135
 
#if PROTO_REPLY_SIGNATURE
136
 
                        if (needsReply) {
137
 
                                Signature outSig = Signature.GetSig (outTypes);
138
 
                                callMsg.Header[FieldCode.ReplySignature] = outSig;
139
 
                        }
140
 
#endif
141
 
 
142
 
                        Message retMsg = conn.SendWithReplyAndBlock (callMsg);
143
 
 
144
 
                        object retVal = null;
145
 
 
146
 
                        //handle the reply message
147
 
                        switch (retMsg.Header.MessageType) {
148
 
                                case MessageType.MethodReturn:
149
 
                                object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
150
 
                                if (retVals.Length != 0)
151
 
                                        retVal = retVals[retVals.Length - 1];
152
 
                                break;
153
 
                                case MessageType.Error:
154
 
                                //TODO: typed exceptions
155
 
                                Error error = new Error (retMsg);
156
 
                                string errMsg = String.Empty;
157
 
                                if (retMsg.Signature.Value.StartsWith ("s")) {
158
 
                                        MessageReader reader = new MessageReader (retMsg);
159
 
                                        errMsg = reader.ReadString ();
160
 
                                }
161
 
                                exception = new Exception (error.ErrorName + ": " + errMsg);
162
 
                                break;
163
 
                                default:
164
 
                                throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
165
 
                        }
166
 
 
167
 
                        return retVal;
168
 
                }
169
 
 
170
 
                public MessageReader SendMethodCall (string iface, string member, string inSigStr, MessageWriter writer, Type retType, out Exception exception)
171
 
                {
172
 
                        exception = null;
173
 
 
174
 
                        //TODO: don't ignore retVal, exception etc.
175
 
 
176
 
                        Signature inSig = String.IsNullOrEmpty (inSigStr) ? Signature.Empty : new Signature (inSigStr);
177
 
 
178
 
                        MethodCall method_call = new MethodCall (object_path, iface, member, bus_name, inSig);
179
 
 
180
 
                        Message callMsg = method_call.message;
181
 
                        callMsg.Body = writer.ToArray ();
182
 
 
183
 
                        //Invoke Code::
184
 
 
185
 
                        //TODO: complete out parameter support
186
 
                        /*
187
 
                        Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
188
 
                        Signature outParmSig = Signature.GetSig (outParmTypes);
189
 
 
190
 
                        if (outParmSig != Signature.Empty)
191
 
                                throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
192
 
                        */
193
 
 
194
 
                        Type[] outTypes = new Type[1];
195
 
                        outTypes[0] = retType;
196
 
 
197
 
                        //we default to always requiring replies for now, even though unnecessary
198
 
                        //this is to make sure errors are handled synchronously
199
 
                        //TODO: don't hard code this
200
 
                        bool needsReply = true;
201
 
 
202
 
                        //if (mi.ReturnType == typeof (void))
203
 
                        //      needsReply = false;
204
 
 
205
 
                        callMsg.ReplyExpected = needsReply;
206
 
                        callMsg.Signature = inSig;
207
 
 
208
 
                        if (!needsReply) {
209
 
                                conn.Send (callMsg);
210
 
                                return null;
211
 
                        }
212
 
 
213
 
#if PROTO_REPLY_SIGNATURE
214
 
                        if (needsReply) {
215
 
                                Signature outSig = Signature.GetSig (outTypes);
216
 
                                callMsg.Header[FieldCode.ReplySignature] = outSig;
217
 
                        }
218
 
#endif
219
 
 
220
 
                        Message retMsg = conn.SendWithReplyAndBlock (callMsg);
221
 
 
222
 
                        MessageReader retVal = null;
223
 
 
224
 
                        //handle the reply message
225
 
                        switch (retMsg.Header.MessageType) {
226
 
                                case MessageType.MethodReturn:
227
 
                                        retVal = new MessageReader (retMsg);
228
 
                                break;
229
 
                                case MessageType.Error:
230
 
                                //TODO: typed exceptions
231
 
                                Error error = new Error (retMsg);
232
 
                                string errMsg = String.Empty;
233
 
                                if (retMsg.Signature.Value.StartsWith ("s")) {
234
 
                                        MessageReader reader = new MessageReader (retMsg);
235
 
                                        errMsg = reader.ReadString ();
236
 
                                }
237
 
                                exception = new Exception (error.ErrorName + ": " + errMsg);
238
 
                                break;
239
 
                                default:
240
 
                                throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
241
 
                        }
242
 
 
243
 
                        return retVal;
244
 
                }
245
 
 
246
 
                public void Invoke (MethodBase methodBase, string methodName, object[] inArgs, out object[] outArgs, out object retVal, out Exception exception)
247
 
                {
248
 
                        outArgs = new object[0];
249
 
                        retVal = null;
250
 
                        exception = null;
251
 
 
252
 
                        MethodInfo mi = methodBase as MethodInfo;
253
 
 
254
 
                        if (mi != null && mi.IsSpecialName && (methodName.StartsWith ("add_") || methodName.StartsWith ("remove_"))) {
255
 
                                string[] parts = methodName.Split (new char[]{'_'}, 2);
256
 
                                string ename = parts[1];
257
 
                                Delegate dlg = (Delegate)inArgs[0];
258
 
 
259
 
                                ToggleSignal (Mapper.GetInterfaceName (mi), ename, dlg, parts[0] == "add");
260
 
 
261
 
                                return;
262
 
                        }
263
 
 
264
 
                        Type[] inTypes = Mapper.GetTypes (ArgDirection.In, mi.GetParameters ());
265
 
                        Signature inSig = Signature.GetSig (inTypes);
266
 
 
267
 
                        MethodCall method_call;
268
 
                        Message callMsg;
269
 
 
270
 
                        //build the outbound method call message
271
 
                        {
272
 
                                //this bit is error-prone (no null checking) and will need rewriting when DProxy is replaced
273
 
                                string iface = null;
274
 
                                if (mi != null)
275
 
                                        iface = Mapper.GetInterfaceName (mi);
276
 
 
277
 
                                //map property accessors
278
 
                                //TODO: this needs to be done properly, not with simple String.Replace
279
 
                                //note that IsSpecialName is also for event accessors, but we already handled those and returned
280
 
                                if (mi != null && mi.IsSpecialName) {
281
 
                                        methodName = methodName.Replace ("get_", "Get");
282
 
                                        methodName = methodName.Replace ("set_", "Set");
283
 
                                }
284
 
 
285
 
                                method_call = new MethodCall (object_path, iface, methodName, bus_name, inSig);
286
 
 
287
 
                                callMsg = method_call.message;
288
 
 
289
 
                                if (inArgs != null && inArgs.Length != 0) {
290
 
                                        MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
291
 
                                        writer.connection = conn;
292
 
 
293
 
                                        for (int i = 0 ; i != inTypes.Length ; i++)
294
 
                                                writer.Write (inTypes[i], inArgs[i]);
295
 
 
296
 
                                        callMsg.Body = writer.ToArray ();
297
 
                                }
298
 
                        }
299
 
 
300
 
                        //TODO: complete out parameter support
301
 
                        /*
302
 
                        Type[] outParmTypes = Mapper.GetTypes (ArgDirection.Out, mi.GetParameters ());
303
 
                        Signature outParmSig = Signature.GetSig (outParmTypes);
304
 
 
305
 
                        if (outParmSig != Signature.Empty)
306
 
                                throw new Exception ("Out parameters not yet supported: out_signature='" + outParmSig.Value + "'");
307
 
                        */
308
 
 
309
 
                        Type[] outTypes = new Type[1];
310
 
                        outTypes[0] = mi.ReturnType;
311
 
 
312
 
                        //we default to always requiring replies for now, even though unnecessary
313
 
                        //this is to make sure errors are handled synchronously
314
 
                        //TODO: don't hard code this
315
 
                        bool needsReply = true;
316
 
 
317
 
                        //if (mi.ReturnType == typeof (void))
318
 
                        //      needsReply = false;
319
 
 
320
 
                        callMsg.ReplyExpected = needsReply;
321
 
                        callMsg.Signature = inSig;
322
 
 
323
 
                        if (!needsReply) {
324
 
                                conn.Send (callMsg);
325
 
                                return;
326
 
                        }
327
 
 
328
 
#if PROTO_REPLY_SIGNATURE
329
 
                        if (needsReply) {
330
 
                                Signature outSig = Signature.GetSig (outTypes);
331
 
                                callMsg.Header[FieldCode.ReplySignature] = outSig;
332
 
                        }
333
 
#endif
334
 
 
335
 
                        Message retMsg = conn.SendWithReplyAndBlock (callMsg);
336
 
 
337
 
                        //handle the reply message
338
 
                        switch (retMsg.Header.MessageType) {
339
 
                                case MessageType.MethodReturn:
340
 
                                object[] retVals = MessageHelper.GetDynamicValues (retMsg, outTypes);
341
 
                                if (retVals.Length != 0)
342
 
                                        retVal = retVals[retVals.Length - 1];
343
 
                                break;
344
 
                                case MessageType.Error:
345
 
                                //TODO: typed exceptions
346
 
                                Error error = new Error (retMsg);
347
 
                                string errMsg = String.Empty;
348
 
                                if (retMsg.Signature.Value.StartsWith ("s")) {
349
 
                                        MessageReader reader = new MessageReader (retMsg);
350
 
                                        errMsg = reader.ReadString ();
351
 
                                }
352
 
                                exception = new Exception (error.ErrorName + ": " + errMsg);
353
 
                                break;
354
 
                                default:
355
 
                                throw new Exception ("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error");
356
 
                        }
357
 
 
358
 
                        return;
359
 
                }
360
 
 
361
 
                public static object GetObject (Connection conn, string bus_name, ObjectPath object_path, Type declType)
362
 
                {
363
 
                        Type proxyType = TypeImplementer.Root.GetImplementation (declType);
364
 
 
365
 
                        //BusObject inst = (BusObject)Activator.CreateInstance (proxyType);
366
 
                        object instObj = Activator.CreateInstance (proxyType);
367
 
                        BusObject inst = GetBusObject (instObj);
368
 
                        inst.conn = conn;
369
 
                        inst.bus_name = bus_name;
370
 
                        inst.object_path = object_path;
371
 
 
372
 
                        return instObj;
373
 
                }
374
 
 
375
 
                static Dictionary<object,BusObject> boCache = new Dictionary<object,BusObject>();
376
 
                public static BusObject GetBusObject (object instObj)
377
 
                {
378
 
                        if (instObj is BusObject)
379
 
                                return (BusObject)instObj;
380
 
 
381
 
                        BusObject inst;
382
 
                        if (boCache.TryGetValue (instObj, out inst))
383
 
                                return inst;
384
 
 
385
 
                        inst = new BusObject ();
386
 
                        boCache[instObj] = inst;
387
 
 
388
 
                        return inst;
389
 
                }
390
 
 
391
 
                public Delegate GetHookupDelegate (EventInfo ei)
392
 
                {
393
 
                        DynamicMethod hookupMethod = TypeImplementer.GetHookupMethod (ei);
394
 
                        Delegate d = hookupMethod.CreateDelegate (ei.EventHandlerType, this);
395
 
                        return d;
396
 
                }
397
 
        }
398
 
}