~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/MacPlatform/MacInterop/AppleEvent.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// AppleEvent.cs
 
3
//  
 
4
// Author:
 
5
//       Michael Hutchinson <mhutchinson@novell.com>
 
6
// 
 
7
// Copyright (c) 2010 Novell, Inc.
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
using System;
 
27
using System.Runtime.InteropServices;
 
28
using System.Collections.Generic;
 
29
 
 
30
namespace MonoDevelop.MacInterop
 
31
{
 
32
        internal static class AppleEvent
 
33
        {
 
34
                const string AELib = Carbon.CarbonLib;
 
35
                
 
36
                //FIXME: is "int" correct for size?
 
37
                [DllImport (AELib)]
 
38
                static extern AEDescStatus AECreateDesc (OSType typeCode, IntPtr dataPtr, int dataSize, out AEDesc desc);
 
39
                
 
40
                [DllImport (AELib)]
 
41
                static extern AEDescStatus AECreateDesc (OSType typeCode, byte[] data, int dataSize, out AEDesc desc);
 
42
                                
 
43
                [DllImport (AELib)]
 
44
                static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
 
45
                                                        out CarbonEventParameterType actualType, IntPtr buffer, int bufferSize, out int actualSize);
 
46
                
 
47
                [DllImport (AELib)]
 
48
                static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
 
49
                                                        uint zero, IntPtr buffer, int bufferSize, int zero2);
 
50
                
 
51
                [DllImport (AELib)]
 
52
                static extern AEDescStatus AECountItems (ref AEDesc descList, out int count); //return an OSErr
 
53
                
 
54
                [DllImport (AELib)]
 
55
                static extern AEDescStatus AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType, uint keyword,
 
56
                                                        uint zero, out IntPtr outPtr, int bufferSize, int zero2);
 
57
                
 
58
                [DllImport (AELib)]
 
59
                public static extern AEDescStatus AEDisposeDesc (ref AEDesc desc);
 
60
                
 
61
                [DllImport (AELib)]
 
62
                public static extern AEDescStatus AESizeOfNthItem  (ref AEDesc descList, int index, ref OSType type, out int size);
 
63
                
 
64
                [DllImport (AELib)]
 
65
                static extern AEDescStatus AEGetDescData (ref AEDesc desc, IntPtr ptr, int maximumSize);
 
66
                
 
67
                [DllImport (AELib)]
 
68
                static extern int AEGetDescDataSize (ref AEDesc desc);
 
69
                
 
70
                [DllImport (AELib)]
 
71
                static extern AEDescStatus AECoerceDesc (ref AEDesc theAEDesc, DescType toType, ref AEDesc result);
 
72
                
 
73
                public static void AECreateDesc (OSType typeCode, byte[] data, out AEDesc result)
 
74
                {
 
75
                        CheckReturn (AECreateDesc (typeCode, data, data.Length, out result));
 
76
                }
 
77
                
 
78
                public static void AECreateDescUtf8 (string value, out AEDesc result)
 
79
                {
 
80
                        var type = (OSType)(int)CarbonEventParameterType.UnicodeText;
 
81
                        var bytes = System.Text.Encoding.UTF8.GetBytes (value);
 
82
                        CheckReturn (AECreateDesc (type, bytes, bytes.Length, out result));
 
83
                }
 
84
                
 
85
                public static void AECreateDescAscii (string value, out AEDesc result)
 
86
                {
 
87
                        var type = (OSType)(int)CarbonEventParameterType.Char;
 
88
                        var bytes = System.Text.Encoding.ASCII.GetBytes (value);
 
89
                        CheckReturn (AECreateDesc (type, bytes, bytes.Length, out result));
 
90
                }
 
91
                
 
92
                public static void AECreateDescNull (out AEDesc desc)
 
93
                {
 
94
                        CheckReturn (AECreateDesc ((OSType)0, IntPtr.Zero, 0, out desc));
 
95
                }
 
96
                
 
97
                public static int AECountItems (ref AEDesc descList)
 
98
                {
 
99
                        int count;
 
100
                        CheckReturn (AECountItems (ref descList, out count));
 
101
                        return count;
 
102
                }
 
103
 
 
104
                public static T AEGetNthPtr<T> (ref AEDesc descList, int index, OSType desiredType) where T : struct
 
105
                {
 
106
                        int len = Marshal.SizeOf (typeof (T));
 
107
                        IntPtr bufferPtr = Marshal.AllocHGlobal (len);
 
108
                        try {
 
109
                                CheckReturn (AEGetNthPtr (ref descList, index, desiredType, 0, 0, bufferPtr, len, 0));
 
110
                                T val = (T)Marshal.PtrToStructure (bufferPtr, typeof (T));
 
111
                                return val;
 
112
                        } finally{ 
 
113
                                Marshal.FreeHGlobal (bufferPtr);
 
114
                        }
 
115
                }
 
116
                
 
117
                public static IntPtr AEGetNthPtr (ref AEDesc descList, int index, OSType desiredType)
 
118
                {
 
119
                        IntPtr ret;
 
120
                        CheckReturn (AEGetNthPtr (ref descList, index, desiredType, 0, 0, out ret, 4, 0));
 
121
                        return ret;
 
122
                }
 
123
                
 
124
                //FIXME: this might not work in some encodings. need to test more.
 
125
                static string GetUtf8StringFromAEPtr (ref AEDesc descList, int index)
 
126
                {
 
127
                        int size;
 
128
                        var type = (OSType)(int)CarbonEventParameterType.UnicodeText;
 
129
                        if (AESizeOfNthItem (ref descList, index, ref type, out size) == AEDescStatus.Ok) {
 
130
                                IntPtr buffer = Marshal.AllocHGlobal (size);
 
131
                                try {
 
132
                                        if (AEGetNthPtr (ref descList, index, type, 0, 0, buffer, size, 0) == AEDescStatus.Ok)
 
133
                                                return Marshal.PtrToStringAuto (buffer, size);
 
134
                                } finally {
 
135
                                        Marshal.FreeHGlobal (buffer);
 
136
                                }
 
137
                        }
 
138
                        return null;
 
139
                }
 
140
                
 
141
                public static string GetStringFromAEDesc (ref AEDesc desc)
 
142
                {
 
143
                        int size = AEGetDescDataSize (ref desc);
 
144
                        if (size > 0) {
 
145
                                IntPtr buffer = Marshal.AllocHGlobal (size);
 
146
                                try {
 
147
                                        if (AEGetDescData (ref desc, buffer, size) == AEDescStatus.Ok)
 
148
                                                return Marshal.PtrToStringAuto (buffer, size);
 
149
                                } finally {
 
150
                                        Marshal.FreeHGlobal (buffer);
 
151
                                }
 
152
                        }
 
153
                        return null;
 
154
                }
 
155
                
 
156
                public static IList<string> GetUtf8StringListFromAEDesc (ref AEDesc list, bool skipEmpty)
 
157
                {
 
158
                        long count = AppleEvent.AECountItems (ref list);
 
159
                        var items = new List<string> ();
 
160
                        for (int i = 1; i <= count; i++) {
 
161
                                string str = AppleEvent.GetUtf8StringFromAEPtr (ref list, i);
 
162
                                if (!string.IsNullOrEmpty (str))
 
163
                                        items.Add (str);
 
164
                        }
 
165
                        return items;
 
166
                }
 
167
                
 
168
                public static T[] GetListFromAEDesc<T,TRef> (ref AEDesc list, AEDescValueSelector<TRef,T> sel, OSType type)
 
169
                        where TRef : struct
 
170
                {
 
171
                        long count = AppleEvent.AECountItems (ref list);
 
172
                        T[] arr = new T[count];
 
173
                        for (int i = 1; i <= count; i++) {
 
174
                                TRef r = AppleEvent.AEGetNthPtr<TRef> (ref list, i, type);
 
175
                                arr [i - 1] = sel (ref r);
 
176
                        }
 
177
                        return arr;
 
178
                }
 
179
                
 
180
                static void CheckReturn (AEDescStatus status)
 
181
                {
 
182
                        if (status != AEDescStatus.Ok)
 
183
                        throw new Exception ("Failed with code " + status.ToString ());
 
184
                }
 
185
        }
 
186
        
 
187
        public delegate T AEDescValueSelector<TRef,T> (ref TRef desc);
 
188
        
 
189
        [StructLayout(LayoutKind.Sequential, Pack = 2)]
 
190
        public struct AEDesc
 
191
        {
 
192
                public uint descriptorType;
 
193
                public IntPtr dataHandle;
 
194
        }
 
195
        
 
196
        public enum AEDescStatus
 
197
        {
 
198
                Ok = 0,
 
199
                MemoryFull = -108,
 
200
                CoercionFail = -1700,
 
201
                DescRecordNotFound = -1701,
 
202
                WrongDataType = -1703,
 
203
                NotAEDesc = -1704,
 
204
                ReplyNotArrived = -1718,
 
205
        }
 
206
        
 
207
        public enum AESendMode {
 
208
                NoReply = 0x00000001,
 
209
                QueueReply = 0x00000002,
 
210
                WaitReply = 0x00000003,
 
211
                DontReconnect = 0x00000080,
 
212
                WantReceipt = 0x00000200,
 
213
                NeverInteract = 0x00000010,
 
214
                CanInteract = 0x00000020,
 
215
                AlwaysInteract = 0x00000030,
 
216
                CanSwitchLayer = 0x00000040,
 
217
                DontRecord = 0x00001000,
 
218
                DontExecute = 0x00002000,
 
219
                ProcessNonReplyEvents = 0x00008000,
 
220
        }
 
221
 
 
222
        struct DescType
 
223
        {
 
224
                public OSType Value;
 
225
        }
 
226
}
 
 
b'\\ No newline at end of file'