fix typo
[mcs.git] / class / System.Drawing / System.Drawing / carbonFunctions.cs
blob64a1452eed21513214b8efdbb9b469fd830962ea
1 //
2 // System.Drawing.carbonFunctions.cs
3 //
4 // Authors:
5 // Geoff Norton (gnorton@customerdna.com>
6 //
7 // Copyright (C) 2007 Novell, Inc. (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #undef DEBUG_CLIPPING
30 using System.Collections;
31 using System.Reflection;
32 using System.Runtime.InteropServices;
33 using System.Security;
35 namespace System.Drawing {
37 [SuppressUnmanagedCodeSecurity]
38 #if NET_2_0
39 internal static class Carbon {
40 #else
41 internal sealed class Carbon {
42 #endif
43 internal static Hashtable contextReference = new Hashtable ();
44 internal static object lockobj = new object ();
46 internal static Delegate hwnd_delegate;
48 #if DEBUG_CLIPPING
49 internal static float red = 1.0f;
50 internal static float green = 0.0f;
51 internal static float blue = 0.0f;
52 internal static int debug_threshold = 1;
53 #endif
55 static Carbon () {
56 foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) {
57 if (String.Equals (asm.GetName ().Name, "System.Windows.Forms")) {
58 Type driver_type = asm.GetType ("System.Windows.Forms.XplatUICarbon");
59 if (driver_type != null) {
60 hwnd_delegate = (Delegate) driver_type.GetField ("HwndDelegate", BindingFlags.NonPublic | BindingFlags.Static).GetValue (null);
66 internal static CarbonContext GetCGContextForView (IntPtr handle) {
67 IntPtr context = IntPtr.Zero;
68 IntPtr port = IntPtr.Zero;
69 IntPtr window = IntPtr.Zero;
71 window = GetControlOwner (handle);
73 if (handle == IntPtr.Zero || window == IntPtr.Zero) {
74 // FIXME: Can we actually get a CGContextRef for the desktop? this makes context IntPtr.Zero
75 port = GetQDGlobalsThePort ();
76 CreateCGContextForPort (port, ref context);
78 Rect desktop_bounds = CGDisplayBounds (CGMainDisplayID ());
80 return new CarbonContext (port, context, (int)desktop_bounds.size.width, (int)desktop_bounds.size.height);
83 QDRect window_bounds = new QDRect ();
84 Rect view_bounds = new Rect ();
86 port = GetWindowPort (window);
88 context = GetContext (port);
90 GetWindowBounds (window, 32, ref window_bounds);
92 HIViewGetBounds (handle, ref view_bounds);
94 HIViewConvertRect (ref view_bounds, handle, IntPtr.Zero);
96 if (view_bounds.size.height < 0) view_bounds.size.height = 0;
97 if (view_bounds.size.width < 0) view_bounds.size.width = 0;
99 CGContextTranslateCTM (context, view_bounds.origin.x, (window_bounds.bottom - window_bounds.top) - (view_bounds.origin.y + view_bounds.size.height));
101 // Create the original rect path and clip to it
102 Rect rc_clip = new Rect (0, 0, view_bounds.size.width, view_bounds.size.height);
104 CGContextSaveGState (context);
106 Rectangle [] clip_rectangles = (Rectangle []) hwnd_delegate.DynamicInvoke (new object [] {handle});
107 if (clip_rectangles != null && clip_rectangles.Length > 0) {
108 int length = clip_rectangles.Length;
110 CGContextBeginPath (context);
111 CGContextAddRect (context, rc_clip);
113 for (int i = 0; i < length; i++) {
114 CGContextAddRect (context, new Rect (clip_rectangles [i].X, view_bounds.size.height - clip_rectangles [i].Y - clip_rectangles [i].Height, clip_rectangles [i].Width, clip_rectangles [i].Height));
116 CGContextClosePath (context);
117 CGContextEOClip (context);
118 #if DEBUG_CLIPPING
119 if (clip_rectangles.Length >= debug_threshold) {
120 CGContextSetRGBFillColor (context, red, green, blue, 0.5f);
121 CGContextFillRect (context, rc_clip);
122 CGContextFlush (context);
123 System.Threading.Thread.Sleep (500);
124 if (red == 1.0f) { red = 0.0f; blue = 1.0f; }
125 else if (blue == 1.0f) { blue = 0.0f; green = 1.0f; }
126 else if (green == 1.0f) { green = 0.0f; red = 1.0f; }
128 #endif
129 } else {
130 CGContextBeginPath (context);
131 CGContextAddRect (context, rc_clip);
132 CGContextClosePath (context);
133 CGContextClip (context);
136 return new CarbonContext (port, context, (int)view_bounds.size.width, (int)view_bounds.size.height);
139 internal static IntPtr GetContext (IntPtr port) {
140 IntPtr context = IntPtr.Zero;
142 lock (lockobj) {
143 #if FALSE
144 if (contextReference [port] != null) {
145 CreateCGContextForPort (port, ref context);
146 } else {
147 QDBeginCGContext (port, ref context);
148 contextReference [port] = context;
150 #else
151 CreateCGContextForPort (port, ref context);
152 #endif
155 return context;
158 internal static void ReleaseContext (IntPtr port, IntPtr context) {
159 CGContextRestoreGState (context);
161 lock (lockobj) {
162 #if FALSE
163 if (contextReference [port] != null && context == (IntPtr) contextReference [port]) {
164 QDEndCGContext (port, ref context);
165 contextReference [port] = null;
166 } else {
167 CFRelease (context);
169 #else
170 CFRelease (context);
171 #endif
175 #region Cocoa Methods
176 [DllImport("libobjc.dylib")]
177 public static extern IntPtr objc_getClass(string className);
178 [DllImport("libobjc.dylib")]
179 public static extern IntPtr objc_msgSend(IntPtr basePtr, IntPtr selector, string argument);
180 [DllImport("libobjc.dylib")]
181 public static extern IntPtr objc_msgSend(IntPtr basePtr, IntPtr selector);
182 [DllImport("libobjc.dylib")]
183 public static extern void objc_msgSend_stret(ref Rect arect, IntPtr basePtr, IntPtr selector);
184 [DllImport("libobjc.dylib")]
185 public static extern IntPtr sel_registerName(string selectorName);
186 #endregion
188 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
189 internal static extern IntPtr CGMainDisplayID ();
190 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
191 internal static extern Rect CGDisplayBounds (IntPtr display);
193 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
194 internal static extern int HIViewGetBounds (IntPtr vHnd, ref Rect r);
195 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
196 internal static extern int HIViewConvertRect (ref Rect r, IntPtr a, IntPtr b);
198 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
199 internal static extern IntPtr GetControlOwner (IntPtr aView);
201 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
202 internal static extern int GetWindowBounds (IntPtr wHnd, uint reg, ref QDRect rect);
203 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
204 internal static extern IntPtr GetWindowPort (IntPtr hWnd);
205 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
206 internal static extern IntPtr GetQDGlobalsThePort ();
207 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
208 internal static extern void CreateCGContextForPort (IntPtr port, ref IntPtr context);
209 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
210 internal static extern void CFRelease (IntPtr context);
211 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
212 internal static extern void QDBeginCGContext (IntPtr port, ref IntPtr context);
213 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
214 internal static extern void QDEndCGContext (IntPtr port, ref IntPtr context);
215 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
216 internal static extern int CGContextClipToRect (IntPtr context, Rect clip);
217 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
218 internal static extern int CGContextClipToRects (IntPtr context, Rect [] clip_rects, int count);
219 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
220 internal static extern void CGContextTranslateCTM (IntPtr context, float tx, float ty);
221 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
222 internal static extern void CGContextScaleCTM (IntPtr context, float x, float y);
223 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
224 internal static extern void CGContextFlush (IntPtr context);
225 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
226 internal static extern void CGContextSynchronize (IntPtr context);
227 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
228 internal static extern IntPtr CGPathCreateMutable ();
229 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
230 internal static extern void CGPathAddRects (IntPtr path, IntPtr _void, Rect [] rects, int count);
231 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
232 internal static extern void CGPathAddRect (IntPtr path, IntPtr _void, Rect rect);
233 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
234 internal static extern void CGContextAddRects (IntPtr context, Rect [] rects, int count);
235 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
236 internal static extern void CGContextAddRect (IntPtr context, Rect rect);
237 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
238 internal static extern void CGContextBeginPath (IntPtr context);
239 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
240 internal static extern void CGContextClosePath (IntPtr context);
241 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
242 internal static extern void CGContextAddPath (IntPtr context, IntPtr path);
243 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
244 internal static extern void CGContextClip (IntPtr context);
245 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
246 internal static extern void CGContextEOClip (IntPtr context);
247 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
248 internal static extern void CGContextEOFillPath (IntPtr context);
249 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
250 internal static extern void CGContextSaveGState (IntPtr context);
251 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
252 internal static extern void CGContextRestoreGState (IntPtr context);
254 #if DEBUG_CLIPPING
255 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
256 internal static extern void CGContextSetRGBFillColor (IntPtr context, float red, float green, float blue, float alpha);
257 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
258 internal static extern void CGContextFillRect (IntPtr context, Rect rect);
259 #endif
262 internal struct CGSize {
263 public float width;
264 public float height;
267 internal struct CGPoint {
268 public float x;
269 public float y;
272 internal struct Rect {
273 public Rect (float x, float y, float width, float height) {
274 this.origin.x = x;
275 this.origin.y = y;
276 this.size.width = width;
277 this.size.height = height;
280 public CGPoint origin;
281 public CGSize size;
284 internal struct QDRect
286 public short top;
287 public short left;
288 public short bottom;
289 public short right;
292 internal struct CarbonContext
294 public IntPtr port;
295 public IntPtr ctx;
296 public int width;
297 public int height;
299 public CarbonContext (IntPtr port, IntPtr ctx, int width, int height)
301 this.port = port;
302 this.ctx = ctx;
303 this.width = width;
304 this.height = height;