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