2009-03-18 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUICarbon.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2007 Novell, Inc.
21 //
22 // Authors:
23 //      Geoff Norton  <gnorton@novell.com>
24 //
25 //
26
27 using System;
28 using System.Threading;
29 using System.Drawing;
30 using System.ComponentModel;
31 using System.Collections;
32 using System.Diagnostics;
33 using System.Runtime.InteropServices;
34
35 using Carbon = System.Windows.Forms.CarbonInternal;
36
37 /// Carbon Version
38 namespace System.Windows.Forms {
39         internal delegate Rectangle [] HwndDelegate (IntPtr handle);
40
41         internal class XplatUICarbon : XplatUIDriver {
42                 #region Local Variables
43                 // General driver variables
44                 private static XplatUICarbon Instance;
45                 private static int RefCount;
46                 private static bool themes_enabled;
47
48                 // Internal members available to the event handler sub-system
49                 internal static IntPtr FocusWindow;
50                 internal static IntPtr ActiveWindow;
51                 internal static IntPtr ReverseWindow;
52                 internal static IntPtr CaretWindow;
53
54                 internal static Hwnd MouseHwnd;
55
56                 internal static MouseButtons MouseState;
57                 internal static Carbon.Hover Hover;
58
59                 internal static HwndDelegate HwndDelegate = new HwndDelegate (GetClippingRectangles);
60                 // Instance members
61                 internal Point mouse_position;
62
63                 // Event handlers
64                 internal Carbon.ApplicationHandler ApplicationHandler;
65                 internal Carbon.ControlHandler ControlHandler;
66                 internal Carbon.HIObjectHandler HIObjectHandler;
67                 internal Carbon.KeyboardHandler KeyboardHandler;
68                 internal Carbon.MouseHandler MouseHandler;
69                 internal Carbon.WindowHandler WindowHandler;
70                 
71                 // Carbon Specific
72                 internal static GrabStruct Grab;
73                 internal static Carbon.Caret Caret;
74                 private static Carbon.Dnd Dnd;
75                 private static Hashtable WindowMapping;
76                 private static Hashtable HandleMapping;
77                 private static IntPtr FosterParent;
78                 private static IntPtr Subclass;
79                 private static int MenuBarHeight;
80                 internal static ArrayList UtilityWindows;
81
82                 // Message loop
83                 private static Queue MessageQueue;
84                 private static bool GetMessageResult;
85
86                 private static bool ReverseWindowMapped;
87
88                 // Timers
89                 private ArrayList TimerList;
90                 private static bool in_doevents;
91                 
92                 static readonly object instancelock = new object ();
93                 static readonly object queuelock = new object ();
94                 
95                 // Event Handlers
96                 internal override event EventHandler Idle;
97                 #endregion
98                 
99                 #region Constructors
100                 private XplatUICarbon() {
101
102                         RefCount = 0;
103                         TimerList = new ArrayList ();
104                         in_doevents = false;
105                         MessageQueue = new Queue ();
106                         
107                         Initialize ();
108                 }
109
110                 ~XplatUICarbon() {
111                         // FIXME: Clean up the FosterParent here.
112                 }
113                 #endregion
114
115                 #region Singleton specific code
116                 public static XplatUICarbon GetInstance() {
117                         lock (instancelock) {
118                                 if (Instance == null) {
119                                         Instance = new XplatUICarbon ();
120                                 }
121                                 RefCount++;
122                         }
123                         return Instance;
124                 }
125
126                 public int Reference {
127                         get {
128                                 return RefCount;
129                         }
130                 }
131                 #endregion
132                 
133                 #region Internal methods
134                 internal void AddExpose (Hwnd hwnd, bool client, Carbon.HIRect rect) {
135                         AddExpose (hwnd, client, (int) rect.origin.x, (int) rect.origin.y, (int) rect.size.width, (int) rect.size.height);
136                 }
137                 
138                 internal void AddExpose (Hwnd hwnd, bool client, Rectangle rect) {
139                         AddExpose (hwnd, client, (int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height);
140                 }
141
142                 internal void FlushQueue () {
143                         CheckTimers (DateTime.UtcNow);
144                         while (MessageQueue.Count > 0) {
145                                 object queueobj = MessageQueue.Dequeue ();
146                                 if (queueobj is GCHandle) {
147                                         XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
148                                 } else {
149                                         MSG msg = (MSG)queueobj;
150                                         NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
151                                 }
152                         }
153                 }
154
155                 internal static Rectangle [] GetClippingRectangles (IntPtr handle) {
156                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
157
158                         if (hwnd == null)
159                                 return null;
160                         if (hwnd.Handle != handle)
161                                 return new Rectangle [] {hwnd.ClientRect};
162
163                         return (Rectangle []) hwnd.GetClippingRectangles ().ToArray (typeof (Rectangle));
164                 }
165
166                 internal IntPtr GetMousewParam(int Delta) {
167                         int      result = 0;
168
169                         if ((MouseState & MouseButtons.Left) != 0) {
170                                 result |= (int)MsgButtons.MK_LBUTTON;
171                         }
172
173                         if ((MouseState & MouseButtons.Middle) != 0) {
174                                 result |= (int)MsgButtons.MK_MBUTTON;
175                         }
176
177                         if ((MouseState & MouseButtons.Right) != 0) {
178                                 result |= (int)MsgButtons.MK_RBUTTON;
179                         }
180
181                         Keys mods = ModifierKeys;
182                         if ((mods & Keys.Control) != 0) {
183                                 result |= (int)MsgButtons.MK_CONTROL;
184                         }
185
186                         if ((mods & Keys.Shift) != 0) {
187                                 result |= (int)MsgButtons.MK_SHIFT;
188                         }
189
190                         result |= Delta << 16;
191
192                         return (IntPtr)result;
193                 }
194
195                 internal IntPtr HandleToWindow (IntPtr handle) {
196                         if (HandleMapping [handle] != null)
197                                 return (IntPtr) HandleMapping [handle];
198                         return IntPtr.Zero;
199                 }
200
201                 internal void Initialize () {
202                         // Initialize the event handlers        
203                         Carbon.EventHandler.Driver = this;
204                         ApplicationHandler = new Carbon.ApplicationHandler (this);
205                         ControlHandler = new Carbon.ControlHandler (this);
206                         HIObjectHandler = new Carbon.HIObjectHandler (this);
207                         KeyboardHandler = new Carbon.KeyboardHandler (this);
208                         MouseHandler = new Carbon.MouseHandler (this);
209                         WindowHandler = new Carbon.WindowHandler (this);
210                         
211                         // Initilize the mouse controls
212                         Hover.Interval = 500;
213                         Hover.Timer = new Timer ();
214                         Hover.Timer.Enabled = false;
215                         Hover.Timer.Interval = Hover.Interval;
216                         Hover.Timer.Tick += new EventHandler (HoverCallback);
217                         Hover.X = -1;
218                         Hover.Y = -1;
219                         MouseState = MouseButtons.None;
220                         mouse_position = Point.Empty;
221                                 
222                         // Initialize the Caret
223                         Caret.Timer = new Timer ();
224                         Caret.Timer.Interval = 500;
225                         Caret.Timer.Tick += new EventHandler (CaretCallback);
226
227                         // Initialize the D&D
228                         Dnd = new Carbon.Dnd (); 
229                         
230                         // Initialize the Carbon Specific stuff
231                         WindowMapping = new Hashtable ();
232                         HandleMapping = new Hashtable ();
233                         UtilityWindows = new ArrayList ();
234                         
235                         // Initialize the FosterParent
236                         Carbon.Rect rect = new Carbon.Rect ();
237                         SetRect (ref rect, (short)0, (short)0, (short)0, (short)0);
238                         Carbon.ProcessSerialNumber psn = new Carbon.ProcessSerialNumber();
239
240                         GetCurrentProcess( ref psn );
241                         TransformProcessType (ref psn, 1);
242                         SetFrontProcess (ref psn);
243
244                         HIObjectRegisterSubclass (__CFStringMakeConstantString ("com.novell.mwfview"), __CFStringMakeConstantString ("com.apple.hiview"), 0, Carbon.EventHandler.EventHandlerDelegate, (uint)Carbon.EventHandler.HIObjectEvents.Length, Carbon.EventHandler.HIObjectEvents, IntPtr.Zero, ref Subclass);
245
246                         Carbon.EventHandler.InstallApplicationHandler ();
247
248                         CreateNewWindow (Carbon.WindowClass.kDocumentWindowClass, Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCloseBoxAttribute | Carbon.WindowAttributes.kWindowFullZoomAttribute | Carbon.WindowAttributes.kWindowCollapseBoxAttribute | Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute, ref rect, ref FosterParent);
249                         
250                         CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref ReverseWindow);
251                         CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref CaretWindow);
252                         
253                         // Get some values about bar heights
254                         Carbon.Rect structRect = new Carbon.Rect ();
255                         Carbon.Rect contentRect = new Carbon.Rect ();
256                         GetWindowBounds (FosterParent, 32, ref structRect);
257                         GetWindowBounds (FosterParent, 33, ref contentRect);
258                         
259                         MenuBarHeight = GetMBarHeight ();
260                         
261                         // Focus
262                         FocusWindow = IntPtr.Zero;
263                         
264                         // Message loop
265                         GetMessageResult = true;
266                         
267                         ReverseWindowMapped = false;
268                 }
269                 
270                 internal void PerformNCCalc(Hwnd hwnd) {
271                         XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
272                         IntPtr ptr;
273                         Rectangle rect;
274
275                         rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
276
277                         ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
278                         ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
279
280                         ncp.rgrc1.left = rect.Left;
281                         ncp.rgrc1.top = rect.Top;
282                         ncp.rgrc1.right = rect.Right;
283                         ncp.rgrc1.bottom = rect.Bottom;
284
285                         Marshal.StructureToPtr(ncp, ptr, true);
286                         NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
287                         ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
288                         Marshal.FreeHGlobal(ptr);
289
290
291                         rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
292                         hwnd.ClientRect = rect;
293
294                         rect = TranslateClientRectangleToQuartzClientRectangle (hwnd);
295
296                         if (hwnd.visible) {
297                                 Carbon.HIRect r = new Carbon.HIRect (rect.X, rect.Y, rect.Width, rect.Height);
298                                 HIViewSetFrame (hwnd.client_window, ref r);
299                         }
300         
301                         AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
302                 }
303                 
304                 internal void ScreenToClient(IntPtr handle, ref Carbon.QDPoint point) {
305                         int x = (int) point.x;
306                         int y = (int) point.y;
307
308                         ScreenToClient (handle, ref x, ref y);
309
310                         point.x = (short) x;
311                         point.y = (short) y;
312                 }
313                 
314                 internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd) {
315                         return TranslateClientRectangleToQuartzClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
316                 }
317
318                 internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd, Control ctrl) {
319                         /* From XplatUIX11
320                          * If this is a form with no window manager, X is handling all the border and caption painting
321                          * so remove that from the area (since the area we set of the window here is the part of the window 
322                          * we're painting in only)
323                          */
324                         Rectangle rect = hwnd.ClientRect;
325                         Form form = ctrl as Form;
326                         CreateParams cp = null;
327
328                         if (form != null)
329                                 cp = form.GetCreateParams ();
330
331                         if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
332                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
333                                 Rectangle qrect = rect;
334                                 
335                                 qrect.Y -= borders.top;
336                                 qrect.X -= borders.left;
337                                 qrect.Width += borders.left + borders.right;
338                                 qrect.Height += borders.top + borders.bottom;
339                                 
340                                 rect = qrect;
341                         }
342                         
343                         if (rect.Width < 1 || rect.Height < 1) {
344                                 rect.Width = 1;
345                                 rect.Height = 1;
346                                 rect.X = -5;
347                                 rect.Y = -5;
348                         }
349                         
350                         return rect;
351                 }
352
353                 internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp) {
354                         return TranslateWindowSizeToQuartzWindowSize (cp, new Size (cp.Width, cp.Height));
355                 }
356
357                 internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp, Size size) {
358                         /* From XplatUIX11
359                          * If this is a form with no window manager, X is handling all the border and caption painting
360                          * so remove that from the area (since the area we set of the window here is the part of the window 
361                          * we're painting in only)
362                          */
363                         Form form = cp.control as Form;
364                         if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
365                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
366                                 Size qsize = size;
367
368                                 qsize.Width -= borders.left + borders.right;
369                                 qsize.Height -= borders.top + borders.bottom; 
370                                 
371                                 size = qsize;
372                         }
373
374                         if (size.Height == 0)
375                                 size.Height = 1;
376                         if (size.Width == 0)
377                                 size.Width = 1;
378                         return size;
379                 }
380                         
381                 internal static Size TranslateQuartzWindowSizeToWindowSize (CreateParams cp, int width, int height) {
382                         /* From XplatUIX11
383                          * If this is a form with no window manager, X is handling all the border and caption painting
384                          * so remove that from the area (since the area we set of the window here is the part of the window 
385                          * we're painting in only)
386                          */
387                         Size size = new Size (width, height);
388                         Form form = cp.control as Form;
389                         if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
390                                 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
391                                 Size qsize = size;
392
393                                 qsize.Width += borders.left + borders.right;
394                                 qsize.Height += borders.top + borders.bottom;
395                                 
396                                 size = qsize;
397                         }
398
399                         return size;
400                 }
401                 #endregion
402                 
403                 #region Callbacks
404                 private void CaretCallback (object sender, EventArgs e) {
405                         if (Caret.Paused) {
406                                 return;
407                         }
408
409                         if (!Caret.On) {
410                                 ShowCaret ();
411                         } else {
412                                 HideCaret ();
413                         }
414                 }
415                 
416                 private void HoverCallback (object sender, EventArgs e) {
417                         if ((Hover.X == mouse_position.X) && (Hover.Y == mouse_position.Y)) {
418                                 MSG msg = new MSG ();
419                                 msg.hwnd = Hover.Hwnd;
420                                 msg.message = Msg.WM_MOUSEHOVER;
421                                 msg.wParam = GetMousewParam (0);
422                                 msg.lParam = (IntPtr)((ushort)Hover.X << 16 | (ushort)Hover.X);
423                                 MessageQueue.Enqueue (msg);
424                         }
425                 }
426                 #endregion
427                 
428                 #region Private Methods
429                 private Point ConvertScreenPointToClient (IntPtr handle, Point point) {
430                         Point converted_point = new Point ();
431                         Carbon.Rect window_bounds = new Carbon.Rect ();
432                         Carbon.CGPoint native_point = new Carbon.CGPoint ();
433
434                         GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
435                         
436                         native_point.x = (point.X - window_bounds.left);
437                         native_point.y = (point.Y - window_bounds.top);
438
439                         HIViewConvertPoint (ref native_point, IntPtr.Zero, handle);
440
441                         converted_point.X = (int)native_point.x;
442                         converted_point.Y = (int)native_point.y;
443
444                         return converted_point;
445                 }
446                 
447                 private Point ConvertClientPointToScreen (IntPtr handle, Point point) {
448                         Point converted_point = new Point ();
449                         Carbon.Rect window_bounds = new Carbon.Rect ();
450                         Carbon.CGPoint native_point = new Carbon.CGPoint ();
451
452                         GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
453                         
454                         native_point.x = point.X;
455                         native_point.y = point.Y;
456
457                         HIViewConvertPoint (ref native_point, handle, IntPtr.Zero);
458
459                         converted_point.X = (int)(native_point.x + window_bounds.left);
460                         converted_point.Y = (int)(native_point.y + window_bounds.top);
461
462                         return converted_point;
463                 }
464
465                 private double NextTimeout () {
466                         DateTime now = DateTime.UtcNow;
467                         int timeout = 0x7FFFFFF;
468                         lock (TimerList) {
469                                 foreach (Timer timer in TimerList) {
470                                         int next = (int) (timer.Expires - now).TotalMilliseconds;
471                                         if (next < 0)
472                                                 return 0;
473                                         if (next < timeout)
474                                                 timeout = next;
475                                 }
476                         }
477                         if (timeout < Timer.Minimum)
478                                 timeout = Timer.Minimum;
479
480                         return (double)((double)timeout/1000);
481                 }
482                 
483                 private void CheckTimers (DateTime now) {
484                         lock (TimerList) {
485                                 int count = TimerList.Count;
486                                 if (count == 0)
487                                         return;
488                                 for (int i = 0; i < TimerList.Count; i++) {
489                                         Timer timer = (Timer) TimerList [i];
490                                         if (timer.Enabled && timer.Expires <= now) {
491                                                 // Timer ticks:
492                                                 //  - Before MainForm.OnLoad if DoEvents () is called.
493                                                 //  - After MainForm.OnLoad if not.
494                                                 //
495                                                 if (in_doevents ||
496                                                     (Application.MWFThread.Current.Context != null && 
497                                                      Application.MWFThread.Current.Context.MainForm != null && 
498                                                      Application.MWFThread.Current.Context.MainForm.IsLoaded)) {
499                                                         timer.FireTick ();
500                                                         timer.Update (now);
501                                                 }
502                                         }
503                                 }
504                         }
505                 }
506                 
507                 private void WaitForHwndMessage (Hwnd hwnd, Msg message) {
508                         MSG msg = new MSG ();
509
510                         bool done = false;
511                         do {
512                                 if (GetMessage(null, ref msg, IntPtr.Zero, 0, 0)) {
513                                         if ((Msg)msg.message == Msg.WM_QUIT) {
514                                                 PostQuitMessage (0);
515                                                 done = true;
516                                         }
517                                         else {
518                                                 if (msg.hwnd == hwnd.Handle) {
519                                                         if ((Msg)msg.message == message)
520                                                                 break;
521                                                         else if ((Msg)msg.message == Msg.WM_DESTROY)
522                                                                 done = true;
523                                                 }
524
525                                                 TranslateMessage (ref msg);
526                                                 DispatchMessage (ref msg);
527                                         }
528                                 }
529                         } while (!done);
530                 }
531
532                 private void SendParentNotify(IntPtr child, Msg cause, int x, int y) {
533                         Hwnd hwnd;
534                         
535                         if (child == IntPtr.Zero) {
536                                 return;
537                         }
538                         
539                         hwnd = Hwnd.GetObjectFromWindow (child);
540                         
541                         if (hwnd == null) {
542                                 return;
543                         }
544                         
545                         if (hwnd.Handle == IntPtr.Zero) {
546                                 return;
547                         }
548                         
549                         if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
550                                 return;
551                         }
552                         
553                         if (hwnd.Parent == null) {
554                                 return;
555                         }
556                         
557                         if (hwnd.Parent.Handle == IntPtr.Zero) {
558                                 return;
559                         }
560
561                         if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
562                                 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
563                         } else {
564                                 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
565                         }
566                         
567                         SendParentNotify (hwnd.Parent.Handle, cause, x, y);
568                 }
569
570                 private bool StyleSet (int s, WindowStyles ws) {
571                         return (s & (int)ws) == (int)ws;
572                 }
573
574                 private bool ExStyleSet (int ex, WindowExStyles exws) {
575                         return (ex & (int)exws) == (int)exws;
576                 }
577
578                 private void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
579
580                         caption_height = 0;
581                         tool_caption_height = 0;
582                         border_static = false;
583
584                         if (StyleSet (Style, WindowStyles.WS_CHILD)) {
585                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
586                                         border_style = FormBorderStyle.Fixed3D;
587                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
588                                         border_style = FormBorderStyle.Fixed3D;
589                                         border_static = true;
590                                 } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
591                                         border_style = FormBorderStyle.None;
592                                 } else {
593                                         border_style = FormBorderStyle.FixedSingle;
594                                 }
595                                 title_style = TitleStyle.None;
596                                 
597                                 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
598                                         caption_height = 0;
599                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
600                                                 title_style = TitleStyle.Tool;
601                                         } else {
602                                                 title_style = TitleStyle.Normal;
603                                         }
604                                 }
605
606                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
607                                         caption_height = 0;
608
609                                         if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
610                                                 ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
611                                                 border_style = (FormBorderStyle) 0xFFFF;
612                                         } else {
613                                                 border_style = FormBorderStyle.None;
614                                         }
615                                 }
616
617                         } else {
618                                 title_style = TitleStyle.None;
619                                 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
620                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
621                                                 title_style = TitleStyle.Tool;
622                                         } else {
623                                                 title_style = TitleStyle.Normal;
624                                         }
625                                 }
626
627                                 border_style = FormBorderStyle.None;
628
629                                 if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
630                                         if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
631                                                 border_style = FormBorderStyle.SizableToolWindow;
632                                         } else {
633                                                 border_style = FormBorderStyle.Sizable;
634                                         }
635                                 } else {
636                                         if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
637                                                 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
638                                                         border_style = FormBorderStyle.Fixed3D;
639                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
640                                                         border_style = FormBorderStyle.Fixed3D;
641                                                         border_static = true;
642                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
643                                                         border_style = FormBorderStyle.FixedDialog;
644                                                 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
645                                                         border_style = FormBorderStyle.FixedToolWindow;
646                                                 } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
647                                                         border_style = FormBorderStyle.FixedSingle;
648                                                 }
649                                         } else {
650                                                 if (StyleSet (Style, WindowStyles.WS_BORDER)) {
651                                                         border_style = FormBorderStyle.FixedSingle;
652                                                 }
653                                         }
654                                 }
655                         }
656                 }
657                 
658                 private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
659                         DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
660                 }
661                 
662                 private void ShowCaret () {
663                         if (Caret.On)
664                                 return;
665                         Caret.On = true;
666                         ShowWindow (CaretWindow);
667                         Graphics g = Graphics.FromHwnd (HIViewGetRoot (CaretWindow));
668
669                         g.FillRectangle (new SolidBrush (Color.Black), new Rectangle (0, 0, Caret.Width, Caret.Height));
670
671                         g.Dispose ();
672                 }
673
674                 private void HideCaret () {
675                         if (!Caret.On)
676                                 return;
677                         Caret.On = false;
678                         HideWindow (CaretWindow);
679                 }
680                 
681                 private void AccumulateDestroyedHandles (Control c, ArrayList list) {
682                         if (c != null) {
683                                 Control[] controls = c.Controls.GetAllControls ();
684
685                                 if (c.IsHandleCreated && !c.IsDisposed) {
686                                         Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
687
688                                         list.Add (hwnd);
689                                         CleanupCachedWindows (hwnd);
690                                 }
691
692                                 for (int  i = 0; i < controls.Length; i ++) {
693                                         AccumulateDestroyedHandles (controls[i], list);
694                                 }
695                         }
696                         
697                 }
698
699                 private void CleanupCachedWindows (Hwnd hwnd) {
700                         if (ActiveWindow == hwnd.Handle) {
701                                 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
702                                 ActiveWindow = IntPtr.Zero;
703                         }
704
705                         if (FocusWindow == hwnd.Handle) {
706                                 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
707                                 FocusWindow = IntPtr.Zero;
708                         }
709
710                         if (Grab.Hwnd == hwnd.Handle) {
711                                 Grab.Hwnd = IntPtr.Zero;
712                                 Grab.Confined = false;
713                         }
714
715                         DestroyCaret (hwnd.Handle);
716                 }
717
718                 private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
719                         // Don't waste time
720                         if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
721                                 return;
722                         }
723
724                         // Keep the invalid area as small as needed
725                         if ((x + width) > hwnd.width) {
726                                 width = hwnd.width - x;
727                         }
728
729                         if ((y + height) > hwnd.height) {
730                                 height = hwnd.height - y;
731                         }
732
733                         if (client) {
734                                 hwnd.AddInvalidArea(x, y, width, height);
735                                 if (!hwnd.expose_pending && hwnd.visible) {
736                                         MSG msg = new MSG ();
737                                         msg.message = Msg.WM_PAINT;
738                                         msg.hwnd = hwnd.Handle;
739                                         MessageQueue.Enqueue (msg);
740                                         hwnd.expose_pending = true;
741                                 }
742                         } else {
743                                 hwnd.AddNcInvalidArea (x, y, width, height);
744                                 if (!hwnd.nc_expose_pending && hwnd.visible) {
745                                         MSG msg = new MSG ();
746                                         Region rgn = new Region (hwnd.Invalid);
747                                         IntPtr hrgn = rgn.GetHrgn (null); // Graphics object isn't needed
748                                         msg.message = Msg.WM_NCPAINT;
749                                         msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
750                                         msg.refobject = rgn;
751                                         msg.hwnd = hwnd.Handle;
752                                         MessageQueue.Enqueue (msg);
753                                         hwnd.nc_expose_pending = true;
754
755                                 }
756                         }
757                 }
758                 #endregion 
759
760                 #region Public Methods
761                 internal void EnqueueMessage (MSG msg) {
762                         lock (queuelock) {
763                                 MessageQueue.Enqueue (msg);
764                         }
765                 }
766
767                 internal override void RaiseIdle (EventArgs e)
768                 {
769                         if (Idle != null)
770                                 Idle (this, e);
771                 }
772
773                 internal override IntPtr InitializeDriver() {
774                         return IntPtr.Zero;
775                 }
776
777                 internal override void ShutdownDriver(IntPtr token) {
778                 }
779
780                 internal override void EnableThemes() {
781                         themes_enabled = true;
782                 }
783
784                 internal override void Activate(IntPtr handle) {
785                         if (ActiveWindow != IntPtr.Zero) {
786                                 ActivateWindow (HIViewGetWindow (ActiveWindow), false);
787                         }
788                         ActivateWindow (HIViewGetWindow (handle), true);
789                         ActiveWindow = handle;
790                 }
791
792                 internal override void AudibleAlert() {
793                         throw new NotImplementedException();
794                 }
795
796                 internal override void CaretVisible (IntPtr hwnd, bool visible) {
797                         if (Caret.Hwnd == hwnd) {
798                                 if (visible) {
799                                         if (Caret.Visible < 1) {
800                                                 Caret.Visible++;
801                                                 Caret.On = false;
802                                                 if (Caret.Visible == 1) {
803                                                         ShowCaret ();
804                                                         Caret.Timer.Start ();
805                                                 }
806                                         }
807                                 } else {
808                                         Caret.Visible--;
809                                         if (Caret.Visible == 0) {
810                                                 Caret.Timer.Stop ();
811                                                 HideCaret ();
812                                         }
813                                 }
814                         }
815                 }
816                 
817                 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect) {
818                         WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
819                         return true;
820                 }
821
822                 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
823                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
824
825                         Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));
826
827                         x = point.X;
828                         y = point.Y;
829                 }
830                 
831                 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
832                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
833
834                         Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));
835
836                         x = point.X;
837                         y = point.Y;
838                 }
839
840                 internal override int[] ClipboardAvailableFormats(IntPtr handle) {
841                         ArrayList list = new ArrayList ();
842                         DataFormats.Format f = DataFormats.Format.List;
843
844                         while (f != null) {
845                                 list.Add (f.Id);
846                                 f = f.Next;
847                         }
848
849                         return (int [])list.ToArray (typeof (int));
850                 }
851
852                 internal override void ClipboardClose(IntPtr handle) {
853                 }
854
855                 //TODO: Map our internal formats to the right os code where we can
856                 internal override int ClipboardGetID(IntPtr handle, string format) {
857                         return (int)__CFStringMakeConstantString (format);
858                 }
859
860                 internal override IntPtr ClipboardOpen(bool primary_selection) {
861                         if (primary_selection)
862                                 return Carbon.Pasteboard.Primary;
863                         return Carbon.Pasteboard.Application;
864                 }
865
866                 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
867                         return Carbon.Pasteboard.Retrieve (handle, type);
868                 }
869
870                 internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
871                         Carbon.Pasteboard.Store (handle, obj, type);
872                 }
873                 
874                 internal override void CreateCaret (IntPtr hwnd, int width, int height) {
875                         if (Caret.Hwnd != IntPtr.Zero)
876                                 DestroyCaret (Caret.Hwnd);
877
878                         Caret.Hwnd = hwnd;
879                         Caret.Width = width;
880                         Caret.Height = height;
881                         Caret.Visible = 0;
882                         Caret.On = false;
883                 }
884                 
885                 internal override IntPtr CreateWindow(CreateParams cp) {
886                         Hwnd hwnd;
887                         Hwnd parent_hwnd = null;
888                         int X;
889                         int Y;
890                         int Width;
891                         int Height;
892                         IntPtr ParentHandle;
893                         IntPtr WindowHandle;
894                         IntPtr WholeWindow;
895                         IntPtr ClientWindow;
896                         IntPtr WholeWindowTracking;
897                         IntPtr ClientWindowTracking;
898
899                         hwnd = new Hwnd ();
900
901                         X = cp.X;
902                         Y = cp.Y;
903                         Width = cp.Width;
904                         Height = cp.Height;
905                         ParentHandle = IntPtr.Zero;
906                         WindowHandle = IntPtr.Zero;
907                         WholeWindow = IntPtr.Zero;
908                         ClientWindow = IntPtr.Zero;
909                         WholeWindowTracking = IntPtr.Zero;
910                         ClientWindowTracking = IntPtr.Zero;
911
912                         if (Width < 1) Width = 1;       
913                         if (Height < 1) Height = 1;     
914
915                         if (cp.Parent != IntPtr.Zero) {
916                                 parent_hwnd = Hwnd.ObjectFromHandle (cp.Parent);
917                                 ParentHandle = parent_hwnd.client_window;
918                         } else {
919                                 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
920                                         HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
921                                 }
922                         }
923
924                         Point next;
925                         if (cp.control is Form) {
926                                 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
927                                 X = next.X;
928                                 Y = next.Y;
929                         }
930
931                         hwnd.x = X;
932                         hwnd.y = Y;
933                         hwnd.width = Width;
934                         hwnd.height = Height;
935                         hwnd.Parent = Hwnd.ObjectFromHandle (cp.Parent);
936                         hwnd.initial_style = cp.WindowStyle;
937                         hwnd.initial_ex_style = cp.WindowExStyle;
938                         hwnd.visible = false;
939
940                         if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
941                                 hwnd.enabled = false;
942                         }
943
944                         ClientWindow = IntPtr.Zero;
945
946                         Size QWindowSize = TranslateWindowSizeToQuartzWindowSize (cp);
947                         Rectangle QClientRect = TranslateClientRectangleToQuartzClientRectangle (hwnd, cp.control);
948
949                         SetHwndStyles(hwnd, cp);
950 /* FIXME */
951                         if (ParentHandle == IntPtr.Zero) {
952                                 IntPtr WindowView = IntPtr.Zero;
953                                 IntPtr GrowBox = IntPtr.Zero;
954                                 Carbon.WindowClass windowklass = Carbon.WindowClass.kOverlayWindowClass;
955                                 Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
956                                 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
957                                         attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
958                                 }
959                                 if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
960                                         attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
961                                 }
962                                 if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
963                                         attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
964                                 }
965                                 if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
966                                         windowklass = Carbon.WindowClass.kDocumentWindowClass;
967                                 }
968                                 if (hwnd.border_style == FormBorderStyle.FixedToolWindow) {
969                                         windowklass = Carbon.WindowClass.kUtilityWindowClass;
970                                 } else if (hwnd.border_style == FormBorderStyle.SizableToolWindow) {
971                                         attributes |= Carbon.WindowAttributes.kWindowResizableAttribute;
972                                         windowklass = Carbon.WindowClass.kUtilityWindowClass;
973                                 }
974                                 if (windowklass == Carbon.WindowClass.kOverlayWindowClass) {
975                                         attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
976                                 }
977                                 attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;
978
979                                 Carbon.Rect rect = new Carbon.Rect ();
980                                 if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
981                                         SetRect (ref rect, (short)X, (short)(Y), (short)(X + QWindowSize.Width), (short)(Y + QWindowSize.Height));
982                                 } else {
983                                         SetRect (ref rect, (short)X, (short)(Y + MenuBarHeight), (short)(X + QWindowSize.Width), (short)(Y + MenuBarHeight + QWindowSize.Height));
984                                 }
985
986                                 CreateNewWindow (windowklass, attributes, ref rect, ref WindowHandle);
987
988                                 Carbon.EventHandler.InstallWindowHandler (WindowHandle);
989                                 HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref WindowView);
990                                 HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 7), ref GrowBox);
991                                 HIGrowBoxViewSetTransparent (GrowBox, true);
992                                 SetAutomaticControlDragTrackingEnabledForWindow (WindowHandle, true);
993                                 ParentHandle = WindowView;
994                         }
995
996                         HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref WholeWindow);
997                         HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref ClientWindow);
998
999                         Carbon.EventHandler.InstallControlHandler (WholeWindow);
1000                         Carbon.EventHandler.InstallControlHandler (ClientWindow);
1001
1002                         // Enable embedding on controls
1003                         HIViewChangeFeatures (WholeWindow, 1<<1, 0);
1004                         HIViewChangeFeatures (ClientWindow, 1<<1, 0);
1005
1006                         HIViewNewTrackingArea (WholeWindow, IntPtr.Zero, (UInt64)WholeWindow, ref WholeWindowTracking);
1007                         HIViewNewTrackingArea (ClientWindow, IntPtr.Zero, (UInt64)ClientWindow, ref ClientWindowTracking);
1008                         Carbon.HIRect WholeRect;
1009                         if (WindowHandle != IntPtr.Zero) {
1010                                 WholeRect = new Carbon.HIRect (0, 0, QWindowSize.Width, QWindowSize.Height);
1011                         } else {
1012                                 WholeRect = new Carbon.HIRect (X, Y, QWindowSize.Width, QWindowSize.Height);
1013                         }
1014                         Carbon.HIRect ClientRect = new Carbon.HIRect (QClientRect.X, QClientRect.Y, QClientRect.Width, QClientRect.Height);
1015                         HIViewSetFrame (WholeWindow, ref WholeRect);
1016                         HIViewSetFrame (ClientWindow, ref ClientRect);
1017
1018                         HIViewAddSubview (ParentHandle, WholeWindow);
1019                         HIViewAddSubview (WholeWindow, ClientWindow);
1020
1021                         hwnd.WholeWindow = WholeWindow;
1022                         hwnd.ClientWindow = ClientWindow;
1023
1024                         if (WindowHandle != IntPtr.Zero) {
1025                                 WindowMapping [hwnd.Handle] = WindowHandle;
1026                                 HandleMapping [WindowHandle] = hwnd.Handle;
1027                                 if (hwnd.border_style == FormBorderStyle.FixedToolWindow || hwnd.border_style == FormBorderStyle.SizableToolWindow) {
1028                                         UtilityWindows.Add (WindowHandle);
1029                                 }
1030                         }
1031
1032                         // Allow dnd on controls
1033                         Dnd.SetAllowDrop (hwnd, true);
1034
1035                         Text (hwnd.Handle, cp.Caption);
1036                         
1037                         SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
1038                         SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
1039
1040                         if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
1041                                 if (WindowHandle != IntPtr.Zero) {
1042                                         if (Control.FromHandle(hwnd.Handle) is Form) {
1043                                                 Form f = Control.FromHandle(hwnd.Handle) as Form;
1044                                                 if (f.WindowState == FormWindowState.Normal) {
1045                                                         SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1046                                                 }
1047                                         }
1048                                         ShowWindow (WindowHandle);
1049                                         WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1050                                 }
1051                                 HIViewSetVisible (WholeWindow, true);
1052                                 HIViewSetVisible (ClientWindow, true);
1053                                 hwnd.visible = true;
1054                                 if (!(Control.FromHandle(hwnd.Handle) is Form)) {
1055                                         SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1056                                 }
1057                         }
1058
1059                         if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
1060                                 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
1061                         } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
1062                                 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
1063                         }
1064
1065                         return hwnd.Handle;
1066                 }
1067
1068                 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
1069                         CreateParams create_params = new CreateParams();
1070
1071                         create_params.Caption = "";
1072                         create_params.X = X;
1073                         create_params.Y = Y;
1074                         create_params.Width = Width;
1075                         create_params.Height = Height;
1076
1077                         create_params.ClassName=XplatUI.DefaultClassName;
1078                         create_params.ClassStyle = 0;
1079                         create_params.ExStyle=0;
1080                         create_params.Parent=IntPtr.Zero;
1081                         create_params.Param=0;
1082
1083                         return CreateWindow(create_params);
1084                 }
1085
1086                 internal override Bitmap DefineStdCursorBitmap (StdCursor id) {
1087                         return Carbon.Cursor.DefineStdCursorBitmap (id);
1088                 }
1089
1090                 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
1091                         return Carbon.Cursor.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
1092                 }
1093                 
1094                 internal override IntPtr DefineStdCursor (StdCursor id) {
1095                         return Carbon.Cursor.DefineStdCursor (id);
1096                 }
1097                 
1098                 internal override IntPtr DefWndProc(ref Message msg) {
1099                         Hwnd hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
1100                         switch ((Msg)msg.Msg) {
1101                                 case Msg.WM_QUIT: {
1102                                         if (WindowMapping [hwnd.Handle] != null)
1103
1104                                                 Exit ();
1105                                         break;
1106                                 }
1107                                 case Msg.WM_PAINT: {
1108                                         hwnd.expose_pending = false;
1109                                         break;
1110                                 }
1111                                 case Msg.WM_NCPAINT: {
1112                                         hwnd.nc_expose_pending = false;
1113                                         break;
1114                                 }  
1115                                 case Msg.WM_NCCALCSIZE: {
1116                                         if (msg.WParam == (IntPtr)1) {
1117                                                 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
1118                                                 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
1119
1120                                                 // Add all the stuff X is supposed to draw.
1121                                                 Control ctrl = Control.FromHandle (hwnd.Handle);
1122                                                 if (ctrl != null) {
1123                                                         Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
1124
1125                                                         ncp.rgrc1.top += rect.top;
1126                                                         ncp.rgrc1.bottom -= rect.bottom;
1127                                                         ncp.rgrc1.left += rect.left;
1128                                                         ncp.rgrc1.right -= rect.right;
1129
1130                                                         Marshal.StructureToPtr (ncp, msg.LParam, true);
1131                                                 }
1132                                         }
1133                                         break;
1134                                 }
1135                                 case Msg.WM_SETCURSOR: {
1136                                         // Pass to parent window first
1137                                         while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
1138                                                 hwnd = hwnd.parent;
1139                                                 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
1140                                         }
1141
1142                                         if (msg.Result == IntPtr.Zero) {
1143                                                 IntPtr handle;
1144
1145                                                 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
1146                                                         case HitTest.HTBOTTOM:          handle = Cursors.SizeNS.handle; break;
1147                                                         case HitTest.HTBORDER:          handle = Cursors.SizeNS.handle; break;
1148                                                         case HitTest.HTBOTTOMLEFT:      handle = Cursors.SizeNESW.handle; break;
1149                                                         case HitTest.HTBOTTOMRIGHT:     handle = Cursors.SizeNWSE.handle; break;
1150                                                         case HitTest.HTERROR:           if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
1151                                                                                                 //FIXME: AudibleAlert();
1152                                                                                         }
1153                                                                                         handle = Cursors.Default.handle;
1154                                                                                         break;
1155
1156                                                         case HitTest.HTHELP:            handle = Cursors.Help.handle; break;
1157                                                         case HitTest.HTLEFT:            handle = Cursors.SizeWE.handle; break;
1158                                                         case HitTest.HTRIGHT:           handle = Cursors.SizeWE.handle; break;
1159                                                         case HitTest.HTTOP:             handle = Cursors.SizeNS.handle; break;
1160                                                         case HitTest.HTTOPLEFT:         handle = Cursors.SizeNWSE.handle; break;
1161                                                         case HitTest.HTTOPRIGHT:        handle = Cursors.SizeNESW.handle; break;
1162
1163                                                         #if SameAsDefault
1164                                                         case HitTest.HTGROWBOX:
1165                                                         case HitTest.HTSIZE:
1166                                                         case HitTest.HTZOOM:
1167                                                         case HitTest.HTVSCROLL:
1168                                                         case HitTest.HTSYSMENU:
1169                                                         case HitTest.HTREDUCE:
1170                                                         case HitTest.HTNOWHERE:
1171                                                         case HitTest.HTMAXBUTTON:
1172                                                         case HitTest.HTMINBUTTON:
1173                                                         case HitTest.HTMENU:
1174                                                         case HitTest.HSCROLL:
1175                                                         case HitTest.HTBOTTOM:
1176                                                         case HitTest.HTCAPTION:
1177                                                         case HitTest.HTCLIENT:
1178                                                         case HitTest.HTCLOSE:
1179                                                         #endif
1180                                                         default: handle = Cursors.Default.handle; break;
1181                                                 }
1182                                                 SetCursor(msg.HWnd, handle);
1183                                         }
1184                                         return (IntPtr)1;
1185                                 }
1186                         }
1187                         return IntPtr.Zero;
1188                 }
1189
1190                 internal override void DestroyCaret (IntPtr hwnd) {
1191                         if (Caret.Hwnd == hwnd) {
1192                                 if (Caret.Visible == 1) {
1193                                         Caret.Timer.Stop ();
1194                                         HideCaret ();
1195                                 }
1196                                 Caret.Hwnd = IntPtr.Zero;
1197                                 Caret.Visible = 0;
1198                                 Caret.On = false;
1199                         }
1200                 }
1201                 
1202                 [MonoTODO]
1203                 internal override void DestroyCursor(IntPtr cursor) {
1204                         throw new NotImplementedException ();
1205                 }
1206         
1207                 internal override void DestroyWindow(IntPtr handle) {
1208                         Hwnd    hwnd;
1209
1210                         hwnd = Hwnd.ObjectFromHandle(handle);
1211
1212                         if (hwnd == null) {
1213                                 return;
1214                         }
1215
1216                         SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
1217                                 
1218                         CleanupCachedWindows (hwnd);
1219
1220                         ArrayList windows = new ArrayList ();
1221
1222                         AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
1223
1224
1225                         foreach (Hwnd h in windows) {
1226                                 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
1227                                 h.zombie = true;
1228                         }
1229
1230                         // TODO: This is crashing swf-messageboxes
1231                         /*
1232                         if (false && hwnd.whole_window != IntPtr.Zero)
1233                                 CFRelease (hwnd.whole_window);
1234                         if (false && hwnd.client_window != IntPtr.Zero)
1235                                 CFRelease (hwnd.client_window);
1236                         */
1237
1238                         if (WindowMapping [hwnd.Handle] != null) { 
1239                                 DisposeWindow ((IntPtr)(WindowMapping [hwnd.Handle]));
1240                                 WindowMapping.Remove (hwnd.Handle);
1241                         }
1242                 }
1243
1244                 internal override IntPtr DispatchMessage(ref MSG msg) {
1245                         return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1246                 }
1247                 
1248                 internal override void DoEvents() {
1249                         MSG     msg = new MSG ();
1250
1251                         in_doevents = true;
1252                         while (PeekMessage (null, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1253                                 TranslateMessage (ref msg);
1254                                 DispatchMessage (ref msg);
1255                         }
1256                         in_doevents = false;
1257
1258                 }
1259
1260                 internal override void EnableWindow(IntPtr handle, bool Enable) {
1261                         //Like X11 we need not do anything here
1262                 }
1263
1264                 internal override void EndLoop(Thread thread) {
1265                 }
1266
1267                 internal void Exit () {
1268                         GetMessageResult = false;
1269                 }
1270                 
1271                 internal override IntPtr GetActive() {
1272                         return ActiveWindow;
1273                 }
1274
1275                 internal override Region GetClipRegion(IntPtr hwnd) {
1276                         return null;
1277                 }
1278
1279                 [MonoTODO]
1280                 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
1281                         width = 12;
1282                         height = 12;
1283                         hotspot_x = 0;
1284                         hotspot_y = 0;
1285                 }
1286                 
1287                 internal override void GetDisplaySize(out Size size) {
1288                         Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
1289                         size = new Size ((int)bounds.size.width, (int)bounds.size.height);
1290                 }
1291
1292                 internal override IntPtr GetParent(IntPtr handle) {
1293                         Hwnd    hwnd;
1294
1295                         hwnd = Hwnd.ObjectFromHandle(handle);
1296                         if (hwnd != null && hwnd.Parent != null) {
1297                                 return hwnd.Parent.Handle;
1298                         }
1299                         return IntPtr.Zero;
1300                 }
1301
1302                 internal override IntPtr GetPreviousWindow(IntPtr handle) {
1303                         return HIViewGetPreviousView(handle);
1304                 }
1305                 
1306                 internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
1307                         Carbon.QDPoint pt = new Carbon.QDPoint ();
1308                         GetGlobalMouse (ref pt);
1309                         x = pt.x;
1310                         y = pt.y;
1311                 }
1312
1313                 internal override IntPtr GetFocus() {
1314                         return FocusWindow;
1315                 }
1316
1317                 
1318                 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
1319                         FontFamily ff = font.FontFamily;
1320                         ascent = ff.GetCellAscent (font.Style);
1321                         descent = ff.GetCellDescent (font.Style);
1322                         return true;
1323                 }
1324                 
1325                 internal override Point GetMenuOrigin(IntPtr handle) {
1326                         Hwnd hwnd;
1327
1328                         hwnd = Hwnd.ObjectFromHandle(handle);
1329
1330                         if (hwnd != null) {
1331                                 return hwnd.MenuOrigin;
1332                         }
1333                         return Point.Empty;
1334                 }
1335
1336                 internal override bool GetMessage(object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
1337                         IntPtr evtRef = IntPtr.Zero;
1338                         IntPtr target = GetEventDispatcherTarget();
1339                         CheckTimers (DateTime.UtcNow);
1340                         ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
1341                         if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1342                                 SendEventToEventTarget (evtRef, target);
1343                                 ReleaseEvent (evtRef);
1344                         }
1345                         
1346                         lock (queuelock) {
1347                                 loop:
1348
1349                                 if (MessageQueue.Count <= 0) {
1350                                         if (Idle != null) 
1351                                                 Idle (this, EventArgs.Empty);
1352                                         else if (TimerList.Count == 0) {
1353                                                 ReceiveNextEvent (0, IntPtr.Zero, 0.15, true, ref evtRef);
1354                                                 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1355                                                         SendEventToEventTarget (evtRef, target);
1356                                                         ReleaseEvent (evtRef);
1357                                                 }
1358                                         } else {
1359                                                 ReceiveNextEvent (0, IntPtr.Zero, NextTimeout (), true, ref evtRef);
1360                                                 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1361                                                         SendEventToEventTarget (evtRef, target);
1362                                                         ReleaseEvent (evtRef);
1363                                                 }
1364                                         }
1365                                         msg.hwnd = IntPtr.Zero;
1366                                         msg.message = Msg.WM_ENTERIDLE;
1367                                         return GetMessageResult;
1368                                 }
1369                                 object queueobj = MessageQueue.Dequeue ();
1370                                 if (queueobj is GCHandle) {
1371                                         XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
1372                                         goto loop;
1373                                 } else {
1374                                         msg = (MSG)queueobj;
1375                                 }
1376                         }
1377                         return GetMessageResult;
1378                 }
1379                 
1380                 [MonoTODO]
1381                 internal override bool GetText(IntPtr handle, out string text) {
1382                         throw new NotImplementedException ();
1383                 }
1384                 
1385                 internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
1386                         Hwnd            hwnd;
1387
1388                         hwnd = Hwnd.ObjectFromHandle(handle);
1389
1390                         if (hwnd != null) {
1391                                 x = hwnd.x;
1392                                 y = hwnd.y;
1393                                 width = hwnd.width;
1394                                 height = hwnd.height;
1395
1396                                 PerformNCCalc(hwnd);
1397
1398                                 client_width = hwnd.ClientRect.Width;
1399                                 client_height = hwnd.ClientRect.Height;
1400
1401                                 return;
1402                         }
1403
1404                         // Should we throw an exception or fail silently?
1405                         // throw new ArgumentException("Called with an invalid window handle", "handle");
1406
1407                         x = 0;
1408                         y = 0;
1409                         width = 0;
1410                         height = 0;
1411                         client_width = 0;
1412                         client_height = 0;
1413                 }
1414                 
1415                 internal override FormWindowState GetWindowState(IntPtr hwnd) {
1416                         IntPtr window = HIViewGetWindow (hwnd);
1417
1418                         if (IsWindowCollapsed (window))
1419                                 return FormWindowState.Minimized;
1420                         if (IsWindowInStandardState (window, IntPtr.Zero, IntPtr.Zero))
1421                                 return FormWindowState.Maximized;
1422
1423                         return FormWindowState.Normal;
1424                 }
1425                 
1426                 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
1427                         handle = Grab.Hwnd;
1428                         GrabConfined = Grab.Confined;
1429                         GrabArea = Grab.Area;
1430                 }
1431                 
1432                 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
1433                         Grab.Hwnd = handle;
1434                         Grab.Confined = confine_to_handle != IntPtr.Zero;
1435                         /* FIXME: Set the Grab.Area */
1436                 }
1437                 
1438                 internal override void UngrabWindow(IntPtr hwnd) {
1439                         bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
1440
1441                         Grab.Hwnd = IntPtr.Zero;
1442                         Grab.Confined = false;
1443
1444                         if (was_grabbed) {
1445                                 // lparam should be the handle to the window gaining the mouse capture,
1446                                 // but we dont have that information like X11.
1447                                 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
1448                                 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
1449                         }
1450                 }
1451                 
1452                 internal override void HandleException(Exception e) {
1453                         StackTrace st = new StackTrace(e);
1454                         Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
1455                         Console.WriteLine("{0}{1}", e.Message, st.ToString());
1456                 }
1457                 
1458                 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear) {
1459                         Hwnd hwnd;
1460
1461                         hwnd = Hwnd.ObjectFromHandle(handle);
1462
1463                         if (clear) {
1464                                 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
1465                         } else {
1466                                 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
1467                         } 
1468                 }
1469
1470                 internal override void InvalidateNC (IntPtr handle)
1471                 {
1472                         Hwnd hwnd;
1473
1474                         hwnd = Hwnd.ObjectFromHandle(handle);
1475
1476                         AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height); 
1477                 }
1478                 
1479                 internal override bool IsEnabled(IntPtr handle) {
1480                         return Hwnd.ObjectFromHandle(handle).Enabled;
1481                 }
1482                 
1483                 internal override bool IsVisible(IntPtr handle) {
1484                         return Hwnd.ObjectFromHandle(handle).visible;
1485                 }
1486                 
1487                 internal override void KillTimer(Timer timer) {
1488                         lock (TimerList) {
1489                                 TimerList.Remove(timer);
1490                         }
1491                 }
1492
1493
1494                 internal override void OverrideCursor(IntPtr cursor) {
1495                 }
1496
1497                 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client) {
1498                         PaintEventArgs  paint_event;
1499                         Hwnd            hwnd;
1500                         Hwnd            paint_hwnd; 
1501                         
1502                         hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
1503                         if (msg.HWnd == handle) {
1504                                 paint_hwnd = hwnd;
1505                         } else {
1506                                 paint_hwnd = Hwnd.ObjectFromHandle (handle);
1507                         }
1508                         
1509                         if (Caret.Visible == 1) {
1510                                 Caret.Paused = true;
1511                                 HideCaret();
1512                         }
1513
1514                         Graphics dc;
1515
1516                         if (client) {
1517                                 dc = Graphics.FromHwnd (paint_hwnd.client_window);
1518
1519                                 Region clip_region = new Region ();
1520                                 clip_region.MakeEmpty();
1521
1522                                 foreach (Rectangle r in hwnd.ClipRectangles) {
1523                                         clip_region.Union (r);
1524                                 }
1525
1526                                 if (hwnd.UserClip != null) {
1527                                         clip_region.Intersect(hwnd.UserClip);
1528                                 }
1529
1530                                 // FIXME: Clip region is hosed
1531                                 dc.Clip = clip_region;
1532                                 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
1533                                 hwnd.expose_pending = false;
1534                                 hwnd.ClearInvalidArea();
1535
1536                                 hwnd.drawing_stack.Push (paint_event);
1537                                 hwnd.drawing_stack.Push (dc);
1538                         } else {
1539                                 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
1540
1541                                 if (!hwnd.nc_invalid.IsEmpty) {
1542                                         // FIXME: Clip region is hosed
1543                                         dc.SetClip (hwnd.nc_invalid);
1544                                         paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
1545                                 } else {
1546                                         paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
1547                                 }
1548                                 hwnd.nc_expose_pending = false;
1549                                 hwnd.ClearNcInvalidArea ();
1550
1551                                 hwnd.drawing_stack.Push (paint_event);
1552                                 hwnd.drawing_stack.Push (dc);
1553                         }
1554
1555                         return paint_event;
1556                 }
1557                 
1558                 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client) {
1559                         Hwnd    hwnd;
1560
1561                         hwnd = Hwnd.ObjectFromHandle(handle);
1562
1563                         // FIXME: Pop is causing invalid stack ops sometimes; race condition?
1564                         try {
1565                                 Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
1566                                 dc.Flush ();
1567                                 dc.Dispose ();
1568                         
1569                                 PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
1570                                 pe.SetGraphics (null);
1571                                 pe.Dispose ();  
1572                         } catch {}
1573
1574                         if (Caret.Visible == 1) {
1575                                 ShowCaret();
1576                                 Caret.Paused = false;
1577                         }
1578                 }
1579                 
1580                 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
1581                         IntPtr evtRef = IntPtr.Zero;
1582                         IntPtr target = GetEventDispatcherTarget();
1583                         CheckTimers (DateTime.UtcNow);
1584                         ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
1585                         if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1586                                 SendEventToEventTarget (evtRef, target);
1587                                 ReleaseEvent (evtRef);
1588                         }
1589                         
1590                         lock (queuelock) {
1591                                 if (MessageQueue.Count <= 0) {
1592                                         return false;
1593                                 } else {
1594                                         object queueobj;
1595                                         if (flags == (uint)PeekMessageFlags.PM_REMOVE)
1596                                                 queueobj = MessageQueue.Dequeue ();
1597                                         else
1598                                                 queueobj = MessageQueue.Peek ();
1599
1600                                         if (queueobj is GCHandle) {
1601                                                 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
1602                                                 return false;
1603                                         }
1604                                         msg = (MSG)queueobj;
1605                                         return true;
1606                                 }
1607                         }
1608                 }
1609
1610                 internal override bool PostMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
1611                         MSG msg = new MSG();
1612                         msg.hwnd = hwnd;
1613                         msg.message = message;
1614                         msg.wParam = wParam;
1615                         msg.lParam = lParam;
1616                         MessageQueue.Enqueue (msg);
1617                         return true;
1618                 }
1619
1620                 internal override void PostQuitMessage(int exitCode) {
1621                         PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
1622                 }
1623
1624                 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave) {
1625                 }
1626
1627                 internal override void RequestNCRecalc(IntPtr handle) {
1628                         Hwnd hwnd;
1629
1630                         hwnd = Hwnd.ObjectFromHandle(handle);
1631
1632                         if (hwnd == null) {
1633                                 return;
1634                         }
1635
1636                         PerformNCCalc(hwnd);
1637                         SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1638                         InvalidateNC(handle);
1639                 }
1640
1641                 [MonoTODO]              
1642                 internal override void ResetMouseHover(IntPtr handle) {
1643                         throw new NotImplementedException();
1644                 }
1645
1646                 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
1647                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1648
1649                         Point point = ConvertScreenPointToClient (hwnd.ClientWindow, new Point (x, y));
1650
1651                         x = point.X;
1652                         y = point.Y;
1653                 }
1654
1655                 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
1656                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1657
1658                         Point point = ConvertScreenPointToClient (hwnd.WholeWindow, new Point (x, y));
1659
1660                         x = point.X;
1661                         y = point.Y;
1662                 }
1663
1664                 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool clear) {
1665                         /*
1666                          * This used to use a HIViewScrollRect but this causes issues with the fact that we dont coalesce
1667                          * updates properly with our short-circuiting of the window manager.  For now we'll do a less
1668                          * efficient invalidation of the entire handle which appears to fix the problem
1669                          * see bug #381084
1670                          */
1671                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1672                         Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
1673                 }
1674                 
1675                 
1676                 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool clear) {
1677                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1678                         Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
1679                 }
1680                 
1681                 [MonoTODO]
1682                 internal override void SendAsyncMethod (AsyncMethodData method) {
1683                         // Fake async
1684                         MessageQueue.Enqueue (GCHandle.Alloc (method));
1685                 }
1686
1687                 [MonoTODO]
1688                 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
1689                         return NativeWindow.WndProc(hwnd, message, wParam, lParam);
1690                 }
1691                 
1692                 internal override int SendInput(IntPtr hwnd, Queue keys) {
1693                         return 0;
1694                 }
1695
1696
1697                 internal override void SetCaretPos (IntPtr hwnd, int x, int y) {
1698                         if (hwnd != IntPtr.Zero && hwnd == Caret.Hwnd) {
1699                                 Caret.X = x;
1700                                 Caret.Y = y;
1701                                 ClientToScreen (hwnd, ref x, ref y);
1702                                 SizeWindow (new Rectangle (x, y, Caret.Width, Caret.Height), CaretWindow);
1703                                 Caret.Timer.Stop ();
1704                                 HideCaret ();
1705                                 if (Caret.Visible == 1) {
1706                                         ShowCaret ();
1707                                         Caret.Timer.Start ();
1708                                 }
1709                         }
1710                 }
1711
1712                 internal override void SetClipRegion(IntPtr hwnd, Region region) {
1713                         throw new NotImplementedException();
1714                 }
1715                 
1716                 internal override void SetCursor(IntPtr window, IntPtr cursor) {
1717                         Hwnd hwnd = Hwnd.ObjectFromHandle (window);
1718
1719                         hwnd.Cursor = cursor;
1720                 }
1721                 
1722                 internal override void SetCursorPos(IntPtr handle, int x, int y) {
1723                         CGDisplayMoveCursorToPoint (CGMainDisplayID (), new Carbon.CGPoint (x, y));
1724                 }
1725                 
1726                 internal override void SetFocus(IntPtr handle) {
1727                         if (FocusWindow != IntPtr.Zero) {
1728                                 PostMessage(FocusWindow, Msg.WM_KILLFOCUS, handle, IntPtr.Zero);
1729                         }
1730                         PostMessage(handle, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
1731                         FocusWindow = handle;
1732                 }
1733
1734                 internal override void SetIcon(IntPtr handle, Icon icon) {
1735                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1736
1737                         // FIXME: we need to map the icon for active window switches
1738                         if (WindowMapping [hwnd.Handle] != null) {
1739                                 if (icon == null) { 
1740                                         RestoreApplicationDockTileImage ();
1741                                 } else {
1742                                         Bitmap          bitmap;
1743                                         int             size;
1744                                         IntPtr[]        data;
1745                                         int             index;
1746         
1747                                         bitmap = new Bitmap (128, 128);
1748                                         using (Graphics g = Graphics.FromImage (bitmap)) {
1749                                                 g.DrawImage (icon.ToBitmap (), 0, 0, 128, 128);
1750                                         }
1751                                         index = 0;
1752                                         size = bitmap.Width * bitmap.Height;
1753                                         data = new IntPtr[size];
1754         
1755                                         for (int y = 0; y < bitmap.Height; y++) {
1756                                                 for (int x = 0; x < bitmap.Width; x++) {
1757                                                         int pixel = bitmap.GetPixel (x, y).ToArgb ();
1758                                                         if (BitConverter.IsLittleEndian) {
1759                                                                 byte a = (byte) ((pixel >> 24) & 0xFF);
1760                                                                 byte r = (byte) ((pixel >> 16) & 0xFF);
1761                                                                 byte g = (byte) ((pixel >> 8) & 0xFF);
1762                                                                 byte b = (byte) (pixel & 0xFF);
1763                                                                 data[index++] = (IntPtr)(a + (r << 8) + (g << 16) + (b << 24));
1764                                                         } else {
1765                                                                 data[index++] = (IntPtr)pixel;
1766                                                         }
1767                                                 }
1768                                         }
1769
1770                                         IntPtr provider = CGDataProviderCreateWithData (IntPtr.Zero, data, size*4, IntPtr.Zero);
1771                                         IntPtr image = CGImageCreate (128, 128, 8, 32, 4*128, CGColorSpaceCreateDeviceRGB (), 4, provider, IntPtr.Zero, 0, 0);
1772                                         SetApplicationDockTileImage (image);
1773                                 }
1774                         }
1775                 }
1776
1777                 
1778                 internal override void SetModal(IntPtr handle, bool Modal) {
1779                         IntPtr hWnd = HIViewGetWindow (Hwnd.ObjectFromHandle (handle).WholeWindow);
1780                         if (Modal)
1781                                 BeginAppModalStateForWindow (hWnd);
1782                         else
1783                                 EndAppModalStateForWindow (hWnd);
1784                         return;
1785                 }
1786
1787                 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
1788                         IntPtr ParentHandle = IntPtr.Zero;
1789                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1790                         
1791                         hwnd.Parent = Hwnd.ObjectFromHandle (parent);
1792                         if (HIViewGetSuperview (hwnd.whole_window) != IntPtr.Zero) {
1793                                 HIViewRemoveFromSuperview (hwnd.whole_window);
1794                         }
1795                         if (hwnd.parent == null)
1796                                 HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
1797                         HIViewAddSubview (hwnd.parent == null ? ParentHandle : hwnd.Parent.client_window, hwnd.whole_window);
1798                         HIViewPlaceInSuperviewAt (hwnd.whole_window, hwnd.X, hwnd.Y);
1799                         HIViewAddSubview (hwnd.whole_window, hwnd.client_window);
1800                         HIViewPlaceInSuperviewAt (hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y);
1801                         
1802                         return IntPtr.Zero;
1803                 }
1804                 
1805                 internal override void SetTimer (Timer timer) {
1806                         lock (TimerList) {
1807                                 TimerList.Add (timer);
1808                         }
1809                 }
1810                 
1811                 internal override bool SetTopmost(IntPtr hWnd, bool Enabled) {
1812                         HIViewSetZOrder (hWnd, 1, IntPtr.Zero);
1813                         return true;
1814                 }
1815                 
1816                 internal override bool SetOwner(IntPtr hWnd, IntPtr hWndOwner) {
1817                         // TODO: Set window owner. 
1818                         return true;
1819                 }
1820                 
1821                 internal override bool SetVisible(IntPtr handle, bool visible, bool activate) {
1822                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1823                         object window = WindowMapping [hwnd.Handle];
1824                         if (window != null)
1825                                 if (visible)
1826                                         ShowWindow ((IntPtr)window);
1827                                 else
1828                                         HideWindow ((IntPtr)window);
1829                         
1830                         if (visible)
1831                                 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1832                                         
1833                         HIViewSetVisible (hwnd.whole_window, visible);
1834                         HIViewSetVisible (hwnd.client_window, visible);
1835
1836                         hwnd.visible = visible;
1837                         hwnd.Mapped = true;
1838                         return true;
1839                 }
1840                 
1841                 internal override void SetAllowDrop (IntPtr handle, bool value) {
1842                         // Like X11 we allow drop on al windows and filter in our handler
1843                 }
1844
1845                 internal override DragDropEffects StartDrag (IntPtr handle, object data, DragDropEffects allowed_effects) {
1846                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1847                         
1848                         if (hwnd == null)
1849                                 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
1850
1851                         return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
1852                 }
1853
1854                 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
1855                         Form form = Control.FromHandle (handle) as Form;
1856                         if (form != null && form.window_manager == null && (border_style == FormBorderStyle.FixedToolWindow ||
1857                                 border_style == FormBorderStyle.SizableToolWindow)) {
1858                                 form.window_manager = new ToolWindowManager (form);
1859                         }
1860
1861                         RequestNCRecalc(handle);
1862                 }
1863
1864                 internal override void SetMenu(IntPtr handle, Menu menu) {
1865                         Hwnd    hwnd;
1866
1867                         hwnd = Hwnd.ObjectFromHandle(handle);
1868                         hwnd.menu = menu;
1869
1870                         RequestNCRecalc(handle);
1871                 }
1872                 
1873                 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
1874                 }
1875
1876                 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
1877                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1878
1879                         if (hwnd == null) {
1880                                 return;
1881                         }
1882
1883                         // Win32 automatically changes negative width/height to 0.
1884                         if (width < 0)
1885                                 width = 0;
1886                         if (height < 0)
1887                                 height = 0;
1888                                 
1889                         // X requires a sanity check for width & height; otherwise it dies
1890                         if (hwnd.zero_sized && width > 0 && height > 0) {
1891                                 if (hwnd.visible) {
1892                                         HIViewSetVisible(hwnd.WholeWindow, true);
1893                                 }
1894                                 hwnd.zero_sized = false;
1895                         }
1896
1897                         if ((width < 1) || (height < 1)) {
1898                                 hwnd.zero_sized = true;
1899                                 HIViewSetVisible(hwnd.WholeWindow, false);
1900                         }
1901
1902                         // Save a server roundtrip (and prevent a feedback loop)
1903                         if ((hwnd.x == x) && (hwnd.y == y) && (hwnd.width == width) && (hwnd.height == height)) {
1904                                 return;
1905                         }
1906
1907                         if (!hwnd.zero_sized) {
1908                                 hwnd.x = x;
1909                                 hwnd.y = y;
1910                                 hwnd.width = width;
1911                                 hwnd.height = height;
1912                                 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1913
1914                                 Control ctrl = Control.FromHandle (handle);
1915                                 CreateParams cp = ctrl.GetCreateParams ();
1916                                 Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (cp, new Size (width, height));
1917                                 Carbon.Rect rect = new Carbon.Rect ();
1918
1919                                 if (WindowMapping [hwnd.Handle] != null) {
1920                                         if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
1921                                                 SetRect (ref rect, (short)x, (short)y, (short)(x+TranslatedSize.Width), (short)(y+TranslatedSize.Height));
1922                                         } else {
1923                                                 SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
1924                                         }
1925                                         SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
1926                                         Carbon.HIRect frame_rect = new Carbon.HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
1927                                         HIViewSetFrame (hwnd.whole_window, ref frame_rect);
1928                                         SetCaretPos (Caret.Hwnd, Caret.X, Caret.Y);
1929                                 } else {
1930                                         Carbon.HIRect frame_rect = new Carbon.HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
1931                                         HIViewSetFrame (hwnd.whole_window, ref frame_rect);
1932                                 }
1933                                 PerformNCCalc(hwnd);
1934                         }
1935
1936                         hwnd.x = x;
1937                         hwnd.y = y;
1938                         hwnd.width = width;
1939                         hwnd.height = height;
1940                 }
1941                 
1942                 internal override void SetWindowState(IntPtr handle, FormWindowState state) {
1943                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1944                         IntPtr window = HIViewGetWindow (handle);
1945
1946                         switch (state) {
1947                                 case FormWindowState.Minimized: {
1948                                         CollapseWindow (window, true);
1949                                         break;
1950                                 }
1951                                 case FormWindowState.Normal: {
1952                                         ZoomWindow (window, 7, false);
1953                                         break;
1954                                 }
1955                                 case FormWindowState.Maximized: {
1956                                         Form form = Control.FromHandle (hwnd.Handle) as Form;
1957                                         if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
1958                                                 Carbon.Rect rect = new Carbon.Rect ();
1959                                                 Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
1960                                                 SetRect (ref rect, (short)0, (short)0, (short)bounds.size.width, (short)bounds.size.height);
1961                                                 SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
1962                                                 HIViewSetFrame (hwnd.whole_window, ref bounds);
1963                                         } else {
1964                                                 ZoomWindow (window, 8, false);
1965                                         }
1966                                         break;
1967                                 }
1968                         }
1969                 }
1970                 
1971                 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
1972                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1973                         SetHwndStyles(hwnd, cp);
1974                         
1975                         if (WindowMapping [hwnd.Handle] != null) {
1976                                 Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
1977                                 if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) { 
1978                                         attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
1979                                 }
1980                                 if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
1981                                         attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
1982                                 }
1983                                 if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
1984                                         attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
1985                                 }
1986                                 if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
1987                                         attributes = Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute;
1988                                 }
1989                                 attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;
1990
1991                                 Carbon.WindowAttributes outAttributes = Carbon.WindowAttributes.kWindowNoAttributes;
1992                                 GetWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], ref outAttributes);
1993                                 ChangeWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], attributes, outAttributes);
1994                         }
1995                 }
1996
1997                 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
1998                 }
1999
2000                 internal override double GetWindowTransparency(IntPtr handle)
2001                 {
2002                         return 1.0;
2003                 }
2004
2005                 internal override TransparencySupport SupportsTransparency() {
2006                         return TransparencySupport.None;
2007                 }
2008                 
2009                 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool Top, bool Bottom) {
2010                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
2011                         
2012                         if (Top) {
2013                                 HIViewSetZOrder (hwnd.whole_window, 2, IntPtr.Zero);
2014                                 return true;
2015                         } else if (!Bottom) {
2016                                 Hwnd after_hwnd = Hwnd.ObjectFromHandle (after_handle);
2017                                 HIViewSetZOrder (hwnd.whole_window, 2, (after_handle == IntPtr.Zero ? IntPtr.Zero : after_hwnd.whole_window));
2018                         } else {
2019                                 HIViewSetZOrder (hwnd.whole_window, 1, IntPtr.Zero);
2020                                 return true;
2021                         }
2022                         return false;
2023                 }
2024
2025                 internal override void ShowCursor(bool show) {
2026                         if (show)
2027                                 CGDisplayShowCursor (CGMainDisplayID ());
2028                         else
2029                                 CGDisplayHideCursor (CGMainDisplayID ());
2030                 }
2031
2032                 internal override object StartLoop(Thread thread) {
2033                         return new object ();
2034                 }
2035                 
2036                 [MonoTODO]
2037                 internal override bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {
2038                         throw new NotImplementedException();
2039                 }
2040
2041                 [MonoTODO]
2042                 internal override bool SystrayChange(IntPtr hwnd, string tip, Icon icon, ref ToolTip tt) {
2043                         throw new NotImplementedException();
2044                 }
2045
2046                 [MonoTODO]
2047                 internal override void SystrayRemove(IntPtr hwnd, ref ToolTip tt) {
2048                         throw new NotImplementedException();
2049                 }
2050
2051 #if NET_2_0
2052                 [MonoTODO]
2053                 internal override void SystrayBalloon(IntPtr hwnd, int timeout, string title, string text, ToolTipIcon icon)
2054                 {
2055                         throw new NotImplementedException ();
2056                 }
2057 #endif
2058                 
2059                 internal override bool Text(IntPtr handle, string text) {
2060                         Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
2061                         if (WindowMapping [hwnd.Handle] != null) {
2062                                 SetWindowTitleWithCFString ((IntPtr)(WindowMapping [hwnd.Handle]), __CFStringMakeConstantString (text));
2063                         }
2064                         SetControlTitleWithCFString (hwnd.whole_window, __CFStringMakeConstantString (text));
2065                         SetControlTitleWithCFString (hwnd.client_window, __CFStringMakeConstantString (text));
2066                         return true;
2067                 }
2068                 
2069                 internal override void UpdateWindow(IntPtr handle) {
2070                         Hwnd    hwnd;
2071
2072                         hwnd = Hwnd.ObjectFromHandle(handle);
2073
2074                         if (!hwnd.visible || !HIViewIsVisible (handle)) {
2075                                 return;
2076                         }
2077
2078                         SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
2079                 }
2080                 
2081                 internal override bool TranslateMessage(ref MSG msg) {
2082                         return Carbon.EventHandler.TranslateMessage (ref msg);
2083                 }
2084                 
2085                 #region Reversible regions
2086                 /* 
2087                  * Quartz has no concept of XOR drawing due to its compositing nature
2088                  * We fake this by mapping a overlay window on the first draw and mapping it on the second.
2089                  * This has some issues with it because its POSSIBLE for ControlPaint.DrawReversible* to actually
2090                  * reverse two regions at once.  We dont do this in MWF, but this behaviour woudn't work.
2091                  * We could in theory cache the Rectangle/Color combination to handle this behaviour.
2092                  *
2093                  * PROBLEMS: This has some flicker / banding
2094                  */
2095                 internal void SizeWindow (Rectangle rect, IntPtr window) {
2096                         Carbon.Rect qrect = new Carbon.Rect ();
2097
2098                         SetRect (ref qrect, (short)rect.X, (short)rect.Y, (short)(rect.X+rect.Width), (short)(rect.Y+rect.Height));
2099
2100                         SetWindowBounds (window, 33, ref qrect);
2101                 }
2102
2103                 internal override void DrawReversibleLine(Point start, Point end, Color backColor) {
2104 //                      throw new NotImplementedException();
2105                 }
2106
2107                 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) {
2108 //                      throw new NotImplementedException();
2109                 }
2110
2111                 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
2112 //                      throw new NotImplementedException();
2113                 }
2114
2115                 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
2116                         Rectangle size_rect = rect;
2117                         int new_x = 0;
2118                         int new_y = 0;
2119
2120                         if (ReverseWindowMapped) {
2121                                 HideWindow (ReverseWindow);
2122                                 ReverseWindowMapped = false;
2123                         } else {
2124                                 ClientToScreen(handle, ref new_x, ref new_y);
2125
2126                                 size_rect.X += new_x;
2127                                 size_rect.Y += new_y;
2128
2129                                 SizeWindow (size_rect, ReverseWindow);
2130                                 ShowWindow (ReverseWindow);
2131
2132                                 rect.X = 0;
2133                                 rect.Y = 0;
2134                                 rect.Width -= 1;
2135                                 rect.Height -= 1;
2136
2137                                 Graphics g = Graphics.FromHwnd (HIViewGetRoot (ReverseWindow));
2138
2139                                 for (int i = 0; i < line_width; i++) {
2140                                         g.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (Color.Black), rect);
2141                                         rect.X += 1;
2142                                         rect.Y += 1;
2143                                         rect.Width -= 1;
2144                                         rect.Height -= 1;
2145                                 }
2146         
2147                                 g.Flush ();
2148                                 g.Dispose ();
2149                                 
2150                                 ReverseWindowMapped = true;
2151                         }
2152                 }
2153                 #endregion
2154
2155                 internal override SizeF GetAutoScaleSize(Font font) {
2156                         Graphics        g;
2157                         float           width;
2158                         string          magic_string = "The quick brown fox jumped over the lazy dog.";
2159                         double          magic_number = 44.549996948242189;
2160
2161                         g = Graphics.FromImage (new Bitmap (1, 1));
2162
2163                         width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
2164                         return new SizeF(width, font.Height);
2165                 }
2166
2167                 internal override Point MousePosition {
2168                         get {
2169                                 return mouse_position;
2170                         }
2171                 }
2172                 #endregion
2173                 
2174                 #region System information
2175                 internal override int KeyboardSpeed { get{ throw new NotImplementedException(); } } 
2176                 internal override int KeyboardDelay { get{ throw new NotImplementedException(); } } 
2177
2178                 internal override int CaptionHeight {
2179                         get {
2180                                 return 19;
2181                         }
2182                 }
2183
2184                 internal override  Size CursorSize { get{ throw new NotImplementedException(); } }
2185                 internal override  bool DragFullWindows { get{ throw new NotImplementedException(); } }
2186                 internal override  Size DragSize {
2187                         get {
2188                                 return new Size(4, 4);
2189                         }
2190                 }
2191
2192                 internal override  Size FrameBorderSize {
2193                         get {
2194                                 return new Size (2, 2);
2195                         }
2196                 }
2197
2198                 internal override  Size IconSize { get{ throw new NotImplementedException(); } }
2199                 internal override  Size MaxWindowTrackSize { get{ throw new NotImplementedException(); } }
2200                 internal override bool MenuAccessKeysUnderlined {
2201                         get {
2202                                 return false;
2203                         }
2204                 }
2205                 internal override Size MinimizedWindowSpacingSize { get{ throw new NotImplementedException(); } }
2206
2207                 internal override Size MinimumWindowSize {
2208                         get {
2209                                 return new Size(110, 22);
2210                         }
2211                 }
2212
2213                 internal override Keys ModifierKeys {
2214                         get {
2215                                 return KeyboardHandler.ModifierKeys;
2216                         }
2217                 }
2218                 internal override Size SmallIconSize { get{ throw new NotImplementedException(); } }
2219                 internal override int MouseButtonCount { get{ throw new NotImplementedException(); } }
2220                 internal override bool MouseButtonsSwapped { get{ throw new NotImplementedException(); } }
2221                 internal override bool MouseWheelPresent { get{ throw new NotImplementedException(); } }
2222
2223                 internal override MouseButtons MouseButtons {
2224                         get {
2225                                 return MouseState;
2226                         }
2227                 }
2228
2229                 internal override Rectangle VirtualScreen {
2230                         get {
2231                                 return WorkingArea;
2232                         }
2233                 }
2234
2235                 internal override Rectangle WorkingArea { 
2236                         get { 
2237                                 Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
2238                                 return new Rectangle ((int)bounds.origin.x, (int)bounds.origin.y, (int)bounds.size.width, (int)bounds.size.height);
2239                         }
2240                 }
2241                 internal override bool ThemesEnabled {
2242                         get {
2243                                 return XplatUICarbon.themes_enabled;
2244                         }
2245                 }
2246  
2247
2248                 #endregion
2249                 
2250                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2251                 extern static int HIViewConvertPoint (ref Carbon.CGPoint point, IntPtr pView, IntPtr cView);
2252                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2253                 extern static int HIViewChangeFeatures (IntPtr aView, ulong bitsin, ulong bitsout);
2254                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2255                 extern static int HIViewFindByID (IntPtr rootWnd, Carbon.HIViewID id, ref IntPtr outPtr);
2256                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2257                 extern static int HIGrowBoxViewSetTransparent (IntPtr GrowBox, bool transparency);
2258                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2259                 extern static IntPtr HIViewGetRoot (IntPtr hWnd);
2260                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2261                 extern static int HIObjectCreate (IntPtr cfStr, uint what, ref IntPtr hwnd);
2262                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2263                 extern static int HIObjectRegisterSubclass (IntPtr classid, IntPtr superclassid, uint options, Carbon.EventDelegate upp, uint count, Carbon.EventTypeSpec [] list, IntPtr state, ref IntPtr cls);
2264                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2265                 extern static int HIViewPlaceInSuperviewAt (IntPtr view, float x, float y);
2266                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2267                 extern static int HIViewAddSubview (IntPtr parentHnd, IntPtr childHnd);
2268                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2269                 extern static IntPtr HIViewGetPreviousView (IntPtr aView);
2270                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2271                 extern static IntPtr HIViewGetSuperview (IntPtr aView);
2272                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2273                 extern static int HIViewRemoveFromSuperview (IntPtr aView);
2274                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2275                 extern static int HIViewSetVisible (IntPtr vHnd, bool visible);
2276                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2277                 extern static bool HIViewIsVisible (IntPtr vHnd);
2278                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2279                 extern static int HIViewGetBounds (IntPtr vHnd, ref Carbon.HIRect r);
2280                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2281                 extern static int HIViewScrollRect (IntPtr vHnd, ref Carbon.HIRect rect, float x, float y);
2282                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2283                 extern static int HIViewSetZOrder (IntPtr hWnd, int cmd, IntPtr oHnd);
2284                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2285                 extern static int HIViewNewTrackingArea (IntPtr inView, IntPtr inShape, UInt64 inID, ref IntPtr outRef);
2286                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2287                 extern static IntPtr HIViewGetWindow (IntPtr aView);
2288                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2289                 extern static int HIViewSetFrame (IntPtr view_handle, ref Carbon.HIRect bounds);
2290                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2291                 internal extern static int HIViewSetNeedsDisplayInRect (IntPtr view_handle, ref Carbon.HIRect rect, bool needs_display);
2292                 
2293                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2294                 extern static void SetRect (ref Carbon.Rect r, short left, short top, short right, short bottom);
2295                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2296                 static extern int ActivateWindow (IntPtr windowHnd, bool inActivate);
2297                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2298                 static extern bool IsWindowActive (IntPtr windowHnd);
2299                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2300                 static extern int SetAutomaticControlDragTrackingEnabledForWindow (IntPtr window, bool enabled);
2301
2302                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2303                 extern static IntPtr GetEventDispatcherTarget ();
2304                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2305                 extern static int SendEventToEventTarget (IntPtr evt, IntPtr target);
2306                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2307                 extern static int ReleaseEvent (IntPtr evt);
2308                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2309                 extern static int ReceiveNextEvent (uint evtCount, IntPtr evtTypes, double timeout, bool processEvt, ref IntPtr evt);
2310
2311                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2312                 extern static bool IsWindowCollapsed (IntPtr hWnd);
2313                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2314                 extern static bool IsWindowInStandardState (IntPtr hWnd, IntPtr a, IntPtr b);
2315                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2316                 extern static void CollapseWindow (IntPtr hWnd, bool collapse);
2317                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2318                 extern static void ZoomWindow (IntPtr hWnd, short partCode, bool front);
2319                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2320                 extern static int GetWindowAttributes (IntPtr hWnd, ref Carbon.WindowAttributes outAttributes);
2321                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2322                 extern static int ChangeWindowAttributes (IntPtr hWnd, Carbon.WindowAttributes inAttributes, Carbon.WindowAttributes outAttributes);
2323                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2324                 internal extern static int GetGlobalMouse (ref Carbon.QDPoint outData);
2325                 
2326                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2327                 extern static int BeginAppModalStateForWindow (IntPtr window);
2328                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2329                 extern static int EndAppModalStateForWindow (IntPtr window);
2330                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2331                 extern static int CreateNewWindow (Carbon.WindowClass klass, Carbon.WindowAttributes attributes, ref Carbon.Rect r, ref IntPtr window);
2332                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2333                 extern static int DisposeWindow (IntPtr wHnd);
2334                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2335                 internal extern static int ShowWindow (IntPtr wHnd);
2336                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2337                 internal extern static int HideWindow (IntPtr wHnd);
2338                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2339                 internal extern static bool IsWindowVisible (IntPtr wHnd);
2340                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2341                 extern static int SetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);
2342                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2343                 extern static int GetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);
2344
2345                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2346                 extern static int SetControlTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
2347                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2348                 extern static int SetWindowTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
2349                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2350                 internal extern static IntPtr __CFStringMakeConstantString (string cString);
2351                 
2352                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2353                 internal extern static int CFRelease (IntPtr wHnd);
2354                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2355                 extern static short GetMBarHeight ();
2356                 
2357                 #region Cursor imports
2358                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2359                 extern static Carbon.HIRect CGDisplayBounds (IntPtr displayID);
2360                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2361                 extern static IntPtr CGMainDisplayID ();
2362                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2363                 extern static void CGDisplayShowCursor (IntPtr display);
2364                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2365                 extern static void CGDisplayHideCursor (IntPtr display);
2366                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2367                 extern static void CGDisplayMoveCursorToPoint (IntPtr display, Carbon.CGPoint point);
2368                 #endregion
2369
2370                 #region Process imports
2371                 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2372                 extern static int GetCurrentProcess (ref Carbon.ProcessSerialNumber psn);
2373                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2374                 extern static int TransformProcessType (ref Carbon.ProcessSerialNumber psn, uint type);
2375                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2376                 extern static int SetFrontProcess (ref Carbon.ProcessSerialNumber psn);
2377                 #endregion
2378
2379                 #region Dock tile imports
2380                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2381                 extern static IntPtr CGColorSpaceCreateDeviceRGB();
2382                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2383                 extern static IntPtr CGDataProviderCreateWithData (IntPtr info, IntPtr [] data, int size, IntPtr releasefunc);
2384                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2385                 extern static IntPtr CGImageCreate (int width, int height, int bitsPerComponent, int bitsPerPixel, int bytesPerRow, IntPtr colorspace, uint bitmapInfo, IntPtr provider, IntPtr decode, int shouldInterpolate, int intent);
2386                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2387                 extern static void SetApplicationDockTileImage(IntPtr imageRef);
2388                 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2389                 extern static void RestoreApplicationDockTileImage();
2390                 #endregion
2391         }
2392 }