XplatUICarbon.cs :  » 2.6.4-mono-.net-core » System.Windows.Forms » System » Windows » Forms » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Windows.Forms 
System.Windows.Forms » System » Windows » Forms » XplatUICarbon.cs
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2004-2007 Novell, Inc.
//
// Authors:
//  Geoff Norton  <gnorton@novell.com>
//
//

using System;
using System.Threading;
using System.Drawing;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;

using CarbonSystem.Windows.Forms.CarbonInternal;

/// Carbon Version
namespace System.Windows.Forms{
  internal delegate Rectangle [] HwndDelegate (IntPtr handle);

  internal class XplatUICarbon : XplatUIDriver {
    #region Local Variables
    // General driver variables
    private static XplatUICarbon Instance;
    private static int RefCount;
    private static bool themes_enabled;

    // Internal members available to the event handler sub-system
    internal static IntPtr FocusWindow;
    internal static IntPtr ActiveWindow;
    internal static IntPtr ReverseWindow;
    internal static IntPtr CaretWindow;

    internal static Hwnd MouseHwnd;

    internal static MouseButtons MouseState;
    internal static Carbon.Hover Hover;

    internal static HwndDelegate HwndDelegate = new HwndDelegate (GetClippingRectangles);
    // Instance members
    internal Point mouse_position;

    // Event handlers
    internal Carbon.ApplicationHandler ApplicationHandler;
    internal Carbon.ControlHandler ControlHandler;
    internal Carbon.HIObjectHandler HIObjectHandler;
    internal Carbon.KeyboardHandler KeyboardHandler;
    internal Carbon.MouseHandler MouseHandler;
    internal Carbon.WindowHandler WindowHandler;
    
    // Carbon Specific
    internal static GrabStruct Grab;
    internal static Carbon.Caret Caret;
    private static Carbon.Dnd Dnd;
    private static Hashtable WindowMapping;
    private static Hashtable HandleMapping;
    private static IntPtr FosterParent;
    private static IntPtr Subclass;
    private static int MenuBarHeight;
    internal static ArrayList UtilityWindows;

    // Message loop
    private static Queue MessageQueue;
    private static bool GetMessageResult;

    private static bool ReverseWindowMapped;

    // Timers
    private ArrayList TimerList;
    private static bool in_doevents;
    
    static readonly object instancelock = new object ();
    static readonly object queuelock = new object ();
    
    // Event Handlers
    internal override event EventHandler Idle;
    #endregion
    
    #region Constructors
    private XplatUICarbon() {

      RefCount = 0;
      TimerList = new ArrayList ();
      in_doevents = false;
      MessageQueue = new Queue ();
      
      Initialize ();
    }

    ~XplatUICarbon() {
      // FIXME: Clean up the FosterParent here.
    }
    #endregion

    #region Singleton specific code
    public static XplatUICarbon GetInstance() {
      lock (instancelock) {
        if (Instance == null) {
          Instance = new XplatUICarbon ();
        }
        RefCount++;
      }
      return Instance;
    }

    public int Reference {
      get {
        return RefCount;
      }
    }
    #endregion
    
    #region Internal methods
    internal void AddExpose (Hwnd hwnd, bool client, Carbon.HIRect rect) {
      AddExpose (hwnd, client, (int) rect.origin.x, (int) rect.origin.y, (int) rect.size.width, (int) rect.size.height);
    }
    
    internal void AddExpose (Hwnd hwnd, bool client, Rectangle rect) {
      AddExpose (hwnd, client, (int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height);
    }

    internal void FlushQueue () {
      CheckTimers (DateTime.UtcNow);
      lock (queuelock) {
        while (MessageQueue.Count > 0) {
          object queueobj = MessageQueue.Dequeue ();
          if (queueobj is GCHandle) {
            XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
          } else {
            MSG msg = (MSG)queueobj;
            NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
          }
        }
      }
    }

    internal static Rectangle [] GetClippingRectangles (IntPtr handle) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      if (hwnd == null)
        return null;
       if (hwnd.Handle != handle)
        return new Rectangle [] {hwnd.ClientRect};

      return (Rectangle []) hwnd.GetClippingRectangles ().ToArray (typeof (Rectangle));
    }

    internal IntPtr GetMousewParam(int Delta) {
      int   result = 0;

      if ((MouseState & MouseButtons.Left) != 0) {
        result |= (int)MsgButtons.MK_LBUTTON;
      }

      if ((MouseState & MouseButtons.Middle) != 0) {
        result |= (int)MsgButtons.MK_MBUTTON;
      }

      if ((MouseState & MouseButtons.Right) != 0) {
        result |= (int)MsgButtons.MK_RBUTTON;
      }

      Keys mods = ModifierKeys;
      if ((mods & Keys.Control) != 0) {
        result |= (int)MsgButtons.MK_CONTROL;
      }

      if ((mods & Keys.Shift) != 0) {
        result |= (int)MsgButtons.MK_SHIFT;
      }

      result |= Delta << 16;

      return (IntPtr)result;
    }

    internal IntPtr HandleToWindow (IntPtr handle) {
      if (HandleMapping [handle] != null)
        return (IntPtr) HandleMapping [handle];
      return IntPtr.Zero;
    }

    internal void Initialize () {
      // Initialize the event handlers  
      Carbon.EventHandler.Driver = this;
      ApplicationHandler = new Carbon.ApplicationHandler (this);
      ControlHandler = new Carbon.ControlHandler (this);
      HIObjectHandler = new Carbon.HIObjectHandler (this);
      KeyboardHandler = new Carbon.KeyboardHandler (this);
      MouseHandler = new Carbon.MouseHandler (this);
      WindowHandler = new Carbon.WindowHandler (this);
      
      // Initilize the mouse controls
      Hover.Interval = 500;
      Hover.Timer = new Timer ();
      Hover.Timer.Enabled = false;
      Hover.Timer.Interval = Hover.Interval;
      Hover.Timer.Tick += new EventHandler (HoverCallback);
      Hover.X = -1;
      Hover.Y = -1;
      MouseState = MouseButtons.None;
      mouse_position = Point.Empty;
        
      // Initialize the Caret
      Caret.Timer = new Timer ();
      Caret.Timer.Interval = 500;
      Caret.Timer.Tick += new EventHandler (CaretCallback);

      // Initialize the D&D
      Dnd = new Carbon.Dnd (); 
      
      // Initialize the Carbon Specific stuff
      WindowMapping = new Hashtable ();
      HandleMapping = new Hashtable ();
      UtilityWindows = new ArrayList ();
      
      // Initialize the FosterParent
      Carbon.Rect rect = new Carbon.Rect ();
      SetRect (ref rect, (short)0, (short)0, (short)0, (short)0);
      Carbon.ProcessSerialNumber psn = new Carbon.ProcessSerialNumber();

      GetCurrentProcess( ref psn );
      TransformProcessType (ref psn, 1);
      SetFrontProcess (ref psn);

      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);

      Carbon.EventHandler.InstallApplicationHandler ();

      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);
      
      CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref ReverseWindow);
      CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref CaretWindow);
      
      // Get some values about bar heights
      Carbon.Rect structRect = new Carbon.Rect ();
      Carbon.Rect contentRect = new Carbon.Rect ();
      GetWindowBounds (FosterParent, 32, ref structRect);
      GetWindowBounds (FosterParent, 33, ref contentRect);
      
      MenuBarHeight = GetMBarHeight ();
      
      // Focus
      FocusWindow = IntPtr.Zero;
      
      // Message loop
      GetMessageResult = true;
      
      ReverseWindowMapped = false;
    }
    
    internal void PerformNCCalc(Hwnd hwnd) {
      XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
      IntPtr ptr;
      Rectangle rect;

      rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);

      ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
      ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));

      ncp.rgrc1.left = rect.Left;
      ncp.rgrc1.top = rect.Top;
      ncp.rgrc1.right = rect.Right;
      ncp.rgrc1.bottom = rect.Bottom;

      Marshal.StructureToPtr(ncp, ptr, true);
      NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
      ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
      Marshal.FreeHGlobal(ptr);


      rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
      hwnd.ClientRect = rect;

      rect = TranslateClientRectangleToQuartzClientRectangle (hwnd);

      if (hwnd.visible) {
        Carbon.HIRect r = new Carbon.HIRect (rect.X, rect.Y, rect.Width, rect.Height);
        HIViewSetFrame (hwnd.client_window, ref r);
      }
  
      AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
    }
    
    internal void ScreenToClient(IntPtr handle, ref Carbon.QDPoint point) {
      int x = (int) point.x;
      int y = (int) point.y;

      ScreenToClient (handle, ref x, ref y);

      point.x = (short) x;
      point.y = (short) y;
    }
    
    internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd) {
      return TranslateClientRectangleToQuartzClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
    }

    internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd, Control ctrl) {
      /* From XplatUIX11
       * If this is a form with no window manager, X is handling all the border and caption painting
       * so remove that from the area (since the area we set of the window here is the part of the window 
       * we're painting in only)
       */
      Rectangle rect = hwnd.ClientRect;
      Form form = ctrl as Form;
      CreateParams cp = null;

      if (form != null)
        cp = form.GetCreateParams ();

      if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
        Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
        Rectangle qrect = rect;
        
        qrect.Y -= borders.top;
        qrect.X -= borders.left;
        qrect.Width += borders.left + borders.right;
        qrect.Height += borders.top + borders.bottom;
        
        rect = qrect;
      }
      
      if (rect.Width < 1 || rect.Height < 1) {
        rect.Width = 1;
        rect.Height = 1;
        rect.X = -5;
        rect.Y = -5;
      }
      
      return rect;
    }

    internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp) {
      return TranslateWindowSizeToQuartzWindowSize (cp, new Size (cp.Width, cp.Height));
    }

    internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp, Size size) {
      /* From XplatUIX11
       * If this is a form with no window manager, X is handling all the border and caption painting
       * so remove that from the area (since the area we set of the window here is the part of the window 
       * we're painting in only)
       */
      Form form = cp.control as Form;
      if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
        Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
        Size qsize = size;

        qsize.Width -= borders.left + borders.right;
        qsize.Height -= borders.top + borders.bottom; 
        
        size = qsize;
      }

      if (size.Height == 0)
        size.Height = 1;
      if (size.Width == 0)
        size.Width = 1;
      return size;
    }
      
    internal static Size TranslateQuartzWindowSizeToWindowSize (CreateParams cp, int width, int height) {
      /* From XplatUIX11
       * If this is a form with no window manager, X is handling all the border and caption painting
       * so remove that from the area (since the area we set of the window here is the part of the window 
       * we're painting in only)
       */
      Size size = new Size (width, height);
      Form form = cp.control as Form;
      if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
        Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
        Size qsize = size;

        qsize.Width += borders.left + borders.right;
        qsize.Height += borders.top + borders.bottom;
        
        size = qsize;
      }

      return size;
    }
    #endregion
    
    #region Callbacks
    private void CaretCallback (object sender, EventArgs e) {
      if (Caret.Paused) {
        return;
      }

      if (!Caret.On) {
        ShowCaret ();
      } else {
        HideCaret ();
      }
    }
    
    private void HoverCallback (object sender, EventArgs e) {
      if ((Hover.X == mouse_position.X) && (Hover.Y == mouse_position.Y)) {
        MSG msg = new MSG ();
        msg.hwnd = Hover.Hwnd;
        msg.message = Msg.WM_MOUSEHOVER;
        msg.wParam = GetMousewParam (0);
        msg.lParam = (IntPtr)((ushort)Hover.X << 16 | (ushort)Hover.X);
        EnqueueMessage (msg);
      }
    }
    #endregion
    
    #region Private Methods
    private Point ConvertScreenPointToClient (IntPtr handle, Point point) {
      Point converted_point = new Point ();
      Carbon.Rect window_bounds = new Carbon.Rect ();
      Carbon.CGPoint native_point = new Carbon.CGPoint ();

      GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
      
      native_point.x = (point.X - window_bounds.left);
      native_point.y = (point.Y - window_bounds.top);

      HIViewConvertPoint (ref native_point, IntPtr.Zero, handle);

      converted_point.X = (int)native_point.x;
      converted_point.Y = (int)native_point.y;

      return converted_point;
    }
    
    private Point ConvertClientPointToScreen (IntPtr handle, Point point) {
      Point converted_point = new Point ();
      Carbon.Rect window_bounds = new Carbon.Rect ();
      Carbon.CGPoint native_point = new Carbon.CGPoint ();

      GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
      
      native_point.x = point.X;
      native_point.y = point.Y;

      HIViewConvertPoint (ref native_point, handle, IntPtr.Zero);

      converted_point.X = (int)(native_point.x + window_bounds.left);
      converted_point.Y = (int)(native_point.y + window_bounds.top);

      return converted_point;
    }

    private double NextTimeout () {
      DateTime now = DateTime.UtcNow;
      int timeout = 0x7FFFFFF;
      lock (TimerList) {
        foreach (Timer timer in TimerList) {
          int next = (int) (timer.Expires - now).TotalMilliseconds;
          if (next < 0)
            return 0;
          if (next < timeout)
            timeout = next;
        }
      }
      if (timeout < Timer.Minimum)
        timeout = Timer.Minimum;

      return (double)((double)timeout/1000);
    }
    
    private void CheckTimers (DateTime now) {
      lock (TimerList) {
        int count = TimerList.Count;
        if (count == 0)
          return;
        for (int i = 0; i < TimerList.Count; i++) {
          Timer timer = (Timer) TimerList [i];
          if (timer.Enabled && timer.Expires <= now) {
            // Timer ticks:
            //  - Before MainForm.OnLoad if DoEvents () is called.
            //  - After MainForm.OnLoad if not.
            //
            if (in_doevents ||
                (Application.MWFThread.Current.Context != null && 
                 Application.MWFThread.Current.Context.MainForm != null && 
                 Application.MWFThread.Current.Context.MainForm.IsLoaded)) {
              timer.FireTick ();
              timer.Update (now);
            }
          }
        }
      }
    }
    
    private void WaitForHwndMessage (Hwnd hwnd, Msg message) {
      MSG msg = new MSG ();

      bool done = false;
      do {
        if (GetMessage(null, ref msg, IntPtr.Zero, 0, 0)) {
          if ((Msg)msg.message == Msg.WM_QUIT) {
            PostQuitMessage (0);
            done = true;
          }
          else {
            if (msg.hwnd == hwnd.Handle) {
              if ((Msg)msg.message == message)
                break;
              else if ((Msg)msg.message == Msg.WM_DESTROY)
                done = true;
            }

            TranslateMessage (ref msg);
            DispatchMessage (ref msg);
          }
        }
      } while (!done);
    }

    private void SendParentNotify(IntPtr child, Msg cause, int x, int y) {
      Hwnd hwnd;
      
      if (child == IntPtr.Zero) {
        return;
      }
      
      hwnd = Hwnd.GetObjectFromWindow (child);
      
      if (hwnd == null) {
        return;
      }
      
      if (hwnd.Handle == IntPtr.Zero) {
        return;
      }
      
      if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
        return;
      }
      
      if (hwnd.Parent == null) {
        return;
      }
      
      if (hwnd.Parent.Handle == IntPtr.Zero) {
        return;
      }

      if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
        SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
      } else {
        SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
      }
      
      SendParentNotify (hwnd.Parent.Handle, cause, x, y);
    }

    private bool StyleSet (int s, WindowStyles ws) {
      return (s & (int)ws) == (int)ws;
    }

    private bool ExStyleSet (int ex, WindowExStyles exws) {
      return (ex & (int)exws) == (int)exws;
    }

    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) {

      caption_height = 0;
      tool_caption_height = 0;
      border_static = false;

      if (StyleSet (Style, WindowStyles.WS_CHILD)) {
        if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
          border_style = FormBorderStyle.Fixed3D;
        } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
          border_style = FormBorderStyle.Fixed3D;
          border_static = true;
        } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
          border_style = FormBorderStyle.None;
        } else {
          border_style = FormBorderStyle.FixedSingle;
        }
        title_style = TitleStyle.None;
        
        if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
          caption_height = 0;
          if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
            title_style = TitleStyle.Tool;
          } else {
            title_style = TitleStyle.Normal;
          }
        }

        if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
          caption_height = 0;

          if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
            ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
            border_style = (FormBorderStyle) 0xFFFF;
          } else {
            border_style = FormBorderStyle.None;
          }
        }

      } else {
        title_style = TitleStyle.None;
        if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
          if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
            title_style = TitleStyle.Tool;
          } else {
            title_style = TitleStyle.Normal;
          }
        }

        border_style = FormBorderStyle.None;

        if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
          if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
            border_style = FormBorderStyle.SizableToolWindow;
          } else {
            border_style = FormBorderStyle.Sizable;
          }
        } else {
          if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
            if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
              border_style = FormBorderStyle.Fixed3D;
            } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
              border_style = FormBorderStyle.Fixed3D;
              border_static = true;
            } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
              border_style = FormBorderStyle.FixedDialog;
            } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
              border_style = FormBorderStyle.FixedToolWindow;
            } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
              border_style = FormBorderStyle.FixedSingle;
            }
          } else {
            if (StyleSet (Style, WindowStyles.WS_BORDER)) {
              border_style = FormBorderStyle.FixedSingle;
            }
          }
        }
      }
    }
    
    private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
      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);
    }
    
    private void ShowCaret () {
      if (Caret.On)
        return;
      Caret.On = true;
      ShowWindow (CaretWindow);
      Graphics g = Graphics.FromHwnd (HIViewGetRoot (CaretWindow));

      g.FillRectangle (new SolidBrush (Color.Black), new Rectangle (0, 0, Caret.Width, Caret.Height));

      g.Dispose ();
    }

    private void HideCaret () {
      if (!Caret.On)
        return;
      Caret.On = false;
      HideWindow (CaretWindow);
    }
    
    private void AccumulateDestroyedHandles (Control c, ArrayList list) {
      if (c != null) {
        Control[] controls = c.Controls.GetAllControls ();

        if (c.IsHandleCreated && !c.IsDisposed) {
          Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);

          list.Add (hwnd);
          CleanupCachedWindows (hwnd);
        }

        for (int  i = 0; i < controls.Length; i ++) {
          AccumulateDestroyedHandles (controls[i], list);
        }
      }
      
    }

    private void CleanupCachedWindows (Hwnd hwnd) {
      if (ActiveWindow == hwnd.Handle) {
        SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
        ActiveWindow = IntPtr.Zero;
      }

      if (FocusWindow == hwnd.Handle) {
        SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
        FocusWindow = IntPtr.Zero;
      }

      if (Grab.Hwnd == hwnd.Handle) {
        Grab.Hwnd = IntPtr.Zero;
        Grab.Confined = false;
      }

      DestroyCaret (hwnd.Handle);
    }

    private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
      // Don't waste time
      if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
        return;
      }

      // Keep the invalid area as small as needed
      if ((x + width) > hwnd.width) {
        width = hwnd.width - x;
      }

      if ((y + height) > hwnd.height) {
        height = hwnd.height - y;
      }

      if (client) {
        hwnd.AddInvalidArea(x, y, width, height);
        if (!hwnd.expose_pending && hwnd.visible) {
          MSG msg = new MSG ();
          msg.message = Msg.WM_PAINT;
          msg.hwnd = hwnd.Handle;
          EnqueueMessage (msg);
          hwnd.expose_pending = true;
        }
      } else {
        hwnd.AddNcInvalidArea (x, y, width, height);
        if (!hwnd.nc_expose_pending && hwnd.visible) {
          MSG msg = new MSG ();
          Region rgn = new Region (hwnd.Invalid);
          IntPtr hrgn = rgn.GetHrgn (null); // Graphics object isn't needed
          msg.message = Msg.WM_NCPAINT;
          msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
          msg.refobject = rgn;
          msg.hwnd = hwnd.Handle;
          EnqueueMessage (msg);
          hwnd.nc_expose_pending = true;

        }
      }
    }
    #endregion 

    #region Public Methods
    internal void EnqueueMessage (MSG msg) {
      lock (queuelock) {
        MessageQueue.Enqueue (msg);
      }
    }

    internal override void RaiseIdle (EventArgs e)
    {
      if (Idle != null)
        Idle (this, e);
    }

    internal override IntPtr InitializeDriver() {
      return IntPtr.Zero;
    }

    internal override void ShutdownDriver(IntPtr token) {
    }

    internal override void EnableThemes() {
      themes_enabled = true;
    }

    internal override void Activate(IntPtr handle) {
      if (ActiveWindow != IntPtr.Zero) {
        ActivateWindow (HIViewGetWindow (ActiveWindow), false);
      }
      ActivateWindow (HIViewGetWindow (handle), true);
      ActiveWindow = handle;
    }

    internal override void AudibleAlert(AlertType alert) {
      AlertSoundPlay ();
    }

    internal override void BeginMoveResize (IntPtr handle) {
    }

    internal override void CaretVisible (IntPtr hwnd, bool visible) {
      if (Caret.Hwnd == hwnd) {
        if (visible) {
          if (Caret.Visible < 1) {
            Caret.Visible++;
            Caret.On = false;
            if (Caret.Visible == 1) {
              ShowCaret ();
              Caret.Timer.Start ();
            }
          }
        } else {
          Caret.Visible--;
          if (Caret.Visible == 0) {
            Caret.Timer.Stop ();
            HideCaret ();
          }
        }
      }
    }
    
    internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect) {
      WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
      return true;
    }

    internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));

      x = point.X;
      y = point.Y;
    }
    
    internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));

      x = point.X;
      y = point.Y;
    }

    internal override int[] ClipboardAvailableFormats(IntPtr handle) {
      ArrayList list = new ArrayList ();
      DataFormats.Format f = DataFormats.Format.List;

      while (f != null) {
        list.Add (f.Id);
        f = f.Next;
      }

      return (int [])list.ToArray (typeof (int));
    }

    internal override void ClipboardClose(IntPtr handle) {
    }

    //TODO: Map our internal formats to the right os code where we can
    internal override int ClipboardGetID(IntPtr handle, string format) {
      return (int)__CFStringMakeConstantString (format);
    }

    internal override IntPtr ClipboardOpen(bool primary_selection) {
      if (primary_selection)
        return Carbon.Pasteboard.Primary;
      return Carbon.Pasteboard.Application;
    }

    internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
      return Carbon.Pasteboard.Retrieve (handle, type);
    }

    internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) {
      Carbon.Pasteboard.Store (handle, obj, type);
    }
    
    internal override void CreateCaret (IntPtr hwnd, int width, int height) {
      if (Caret.Hwnd != IntPtr.Zero)
        DestroyCaret (Caret.Hwnd);

      Caret.Hwnd = hwnd;
      Caret.Width = width;
      Caret.Height = height;
      Caret.Visible = 0;
      Caret.On = false;
    }
    
    internal override IntPtr CreateWindow(CreateParams cp) {
      Hwnd hwnd;
      Hwnd parent_hwnd = null;
      int X;
      int Y;
      int Width;
      int Height;
      IntPtr ParentHandle;
      IntPtr WindowHandle;
      IntPtr WholeWindow;
      IntPtr ClientWindow;
      IntPtr WholeWindowTracking;
      IntPtr ClientWindowTracking;

      hwnd = new Hwnd ();

      X = cp.X;
      Y = cp.Y;
      Width = cp.Width;
      Height = cp.Height;
      ParentHandle = IntPtr.Zero;
      WindowHandle = IntPtr.Zero;
      WholeWindow = IntPtr.Zero;
      ClientWindow = IntPtr.Zero;
      WholeWindowTracking = IntPtr.Zero;
      ClientWindowTracking = IntPtr.Zero;

      if (Width < 1) Width = 1;  
      if (Height < 1) Height = 1;  

      if (cp.Parent != IntPtr.Zero) {
        parent_hwnd = Hwnd.ObjectFromHandle (cp.Parent);
        ParentHandle = parent_hwnd.client_window;
      } else {
        if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
          HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
        }
      }

      Point next;
      if (cp.control is Form) {
        next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
        X = next.X;
        Y = next.Y;
      }

      hwnd.x = X;
      hwnd.y = Y;
      hwnd.width = Width;
      hwnd.height = Height;
      hwnd.Parent = Hwnd.ObjectFromHandle (cp.Parent);
      hwnd.initial_style = cp.WindowStyle;
      hwnd.initial_ex_style = cp.WindowExStyle;
      hwnd.visible = false;

      if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
        hwnd.enabled = false;
      }

      ClientWindow = IntPtr.Zero;

      Size QWindowSize = TranslateWindowSizeToQuartzWindowSize (cp);
      Rectangle QClientRect = TranslateClientRectangleToQuartzClientRectangle (hwnd, cp.control);

      SetHwndStyles(hwnd, cp);
/* FIXME */
      if (ParentHandle == IntPtr.Zero) {
        IntPtr WindowView = IntPtr.Zero;
        IntPtr GrowBox = IntPtr.Zero;
        Carbon.WindowClass windowklass = Carbon.WindowClass.kOverlayWindowClass;
        Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
        if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
          attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
        }
        if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
          attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
        }
        if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
          attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
        }
        if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
          windowklass = Carbon.WindowClass.kDocumentWindowClass;
        }
        if (hwnd.border_style == FormBorderStyle.FixedToolWindow) {
          windowklass = Carbon.WindowClass.kUtilityWindowClass;
        } else if (hwnd.border_style == FormBorderStyle.SizableToolWindow) {
          attributes |= Carbon.WindowAttributes.kWindowResizableAttribute;
          windowklass = Carbon.WindowClass.kUtilityWindowClass;
        }
        if (windowklass == Carbon.WindowClass.kOverlayWindowClass) {
          attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
        }
        attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;

        Carbon.Rect rect = new Carbon.Rect ();
        if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
          SetRect (ref rect, (short)X, (short)(Y), (short)(X + QWindowSize.Width), (short)(Y + QWindowSize.Height));
        } else {
          SetRect (ref rect, (short)X, (short)(Y + MenuBarHeight), (short)(X + QWindowSize.Width), (short)(Y + MenuBarHeight + QWindowSize.Height));
        }

        CreateNewWindow (windowklass, attributes, ref rect, ref WindowHandle);

        Carbon.EventHandler.InstallWindowHandler (WindowHandle);
        HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref WindowView);
        HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 7), ref GrowBox);
        HIGrowBoxViewSetTransparent (GrowBox, true);
        SetAutomaticControlDragTrackingEnabledForWindow (WindowHandle, true);
        ParentHandle = WindowView;
      }

      HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref WholeWindow);
      HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref ClientWindow);

      Carbon.EventHandler.InstallControlHandler (WholeWindow);
      Carbon.EventHandler.InstallControlHandler (ClientWindow);

      // Enable embedding on controls
      HIViewChangeFeatures (WholeWindow, 1<<1, 0);
      HIViewChangeFeatures (ClientWindow, 1<<1, 0);

      HIViewNewTrackingArea (WholeWindow, IntPtr.Zero, (UInt64)WholeWindow, ref WholeWindowTracking);
      HIViewNewTrackingArea (ClientWindow, IntPtr.Zero, (UInt64)ClientWindow, ref ClientWindowTracking);
      Carbon.HIRect WholeRect;
      if (WindowHandle != IntPtr.Zero) {
        WholeRect = new Carbon.HIRect (0, 0, QWindowSize.Width, QWindowSize.Height);
      } else {
        WholeRect = new Carbon.HIRect (X, Y, QWindowSize.Width, QWindowSize.Height);
      }
      Carbon.HIRect ClientRect = new Carbon.HIRect (QClientRect.X, QClientRect.Y, QClientRect.Width, QClientRect.Height);
      HIViewSetFrame (WholeWindow, ref WholeRect);
      HIViewSetFrame (ClientWindow, ref ClientRect);

      HIViewAddSubview (ParentHandle, WholeWindow);
      HIViewAddSubview (WholeWindow, ClientWindow);

      hwnd.WholeWindow = WholeWindow;
      hwnd.ClientWindow = ClientWindow;

      if (WindowHandle != IntPtr.Zero) {
        WindowMapping [hwnd.Handle] = WindowHandle;
        HandleMapping [WindowHandle] = hwnd.Handle;
        if (hwnd.border_style == FormBorderStyle.FixedToolWindow || hwnd.border_style == FormBorderStyle.SizableToolWindow) {
          UtilityWindows.Add (WindowHandle);
        }
      }

      // Allow dnd on controls
      Dnd.SetAllowDrop (hwnd, true);

      Text (hwnd.Handle, cp.Caption);
      
      SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
      SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);

      if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
        if (WindowHandle != IntPtr.Zero) {
          if (Control.FromHandle(hwnd.Handle) is Form) {
            Form f = Control.FromHandle(hwnd.Handle) as Form;
            if (f.WindowState == FormWindowState.Normal) {
              SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
            }
          }
          ShowWindow (WindowHandle);
          WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
        }
        HIViewSetVisible (WholeWindow, true);
        HIViewSetVisible (ClientWindow, true);
        hwnd.visible = true;
        if (!(Control.FromHandle(hwnd.Handle) is Form)) {
          SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
        }
      }

      if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
        SetWindowState(hwnd.Handle, FormWindowState.Minimized);
      } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
        SetWindowState(hwnd.Handle, FormWindowState.Maximized);
      }

      return hwnd.Handle;
    }

    internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
      CreateParams create_params = new CreateParams();

      create_params.Caption = "";
      create_params.X = X;
      create_params.Y = Y;
      create_params.Width = Width;
      create_params.Height = Height;

      create_params.ClassName=XplatUI.DefaultClassName;
      create_params.ClassStyle = 0;
      create_params.ExStyle=0;
      create_params.Parent=IntPtr.Zero;
      create_params.Param=0;

      return CreateWindow(create_params);
    }

    internal override Bitmap DefineStdCursorBitmap (StdCursor id) {
      return Carbon.Cursor.DefineStdCursorBitmap (id);
    }

    internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
      return Carbon.Cursor.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
    }
    
    internal override IntPtr DefineStdCursor (StdCursor id) {
      return Carbon.Cursor.DefineStdCursor (id);
    }
    
    internal override IntPtr DefWndProc(ref Message msg) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
      switch ((Msg)msg.Msg) {
        case Msg.WM_IME_COMPOSITION:
          string s = KeyboardHandler.ComposedString;
          foreach (char c in s)
            SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
          break;
        case Msg.WM_IME_CHAR:
          // On Windows API it sends two WM_CHAR messages for each byte, but
          // I wonder if it is worthy to emulate it (also no idea how to 
          // reconstruct those bytes into chars).
          SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
          return IntPtr.Zero;
        case Msg.WM_QUIT: {
          if (WindowMapping [hwnd.Handle] != null)

            Exit ();
          break;
        }
        case Msg.WM_PAINT: {
          hwnd.expose_pending = false;
          break;
        }
        case Msg.WM_NCPAINT: {
          hwnd.nc_expose_pending = false;
          break;
        }  
        case Msg.WM_NCCALCSIZE: {
          if (msg.WParam == (IntPtr)1) {
            XplatUIWin32.NCCALCSIZE_PARAMS ncp;
            ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));

            // Add all the stuff X is supposed to draw.
            Control ctrl = Control.FromHandle (hwnd.Handle);
            if (ctrl != null) {
              Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);

              ncp.rgrc1.top += rect.top;
              ncp.rgrc1.bottom -= rect.bottom;
              ncp.rgrc1.left += rect.left;
              ncp.rgrc1.right -= rect.right;

              Marshal.StructureToPtr (ncp, msg.LParam, true);
            }
          }
          break;
        }
        case Msg.WM_SETCURSOR: {
          // Pass to parent window first
          while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
            hwnd = hwnd.parent;
            msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
          }

          if (msg.Result == IntPtr.Zero) {
            IntPtr handle;

            switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
              case HitTest.HTBOTTOM:    handle = Cursors.SizeNS.handle; break;
              case HitTest.HTBORDER:    handle = Cursors.SizeNS.handle; break;
              case HitTest.HTBOTTOMLEFT:  handle = Cursors.SizeNESW.handle; break;
              case HitTest.HTBOTTOMRIGHT:  handle = Cursors.SizeNWSE.handle; break;
              case HitTest.HTERROR:    if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
                        //FIXME: AudibleAlert();
                      }
                      handle = Cursors.Default.handle;
                      break;

              case HitTest.HTHELP:    handle = Cursors.Help.handle; break;
              case HitTest.HTLEFT:    handle = Cursors.SizeWE.handle; break;
              case HitTest.HTRIGHT:    handle = Cursors.SizeWE.handle; break;
              case HitTest.HTTOP:    handle = Cursors.SizeNS.handle; break;
              case HitTest.HTTOPLEFT:    handle = Cursors.SizeNWSE.handle; break;
              case HitTest.HTTOPRIGHT:  handle = Cursors.SizeNESW.handle; break;

              #if SameAsDefault
              case HitTest.HTGROWBOX:
              case HitTest.HTSIZE:
              case HitTest.HTZOOM:
              case HitTest.HTVSCROLL:
              case HitTest.HTSYSMENU:
              case HitTest.HTREDUCE:
              case HitTest.HTNOWHERE:
              case HitTest.HTMAXBUTTON:
              case HitTest.HTMINBUTTON:
              case HitTest.HTMENU:
              case HitTest.HSCROLL:
              case HitTest.HTBOTTOM:
              case HitTest.HTCAPTION:
              case HitTest.HTCLIENT:
              case HitTest.HTCLOSE:
              #endif
              default: handle = Cursors.Default.handle; break;
            }
            SetCursor(msg.HWnd, handle);
          }
          return (IntPtr)1;
        }
      }
      return IntPtr.Zero;
    }

    internal override void DestroyCaret (IntPtr hwnd) {
      if (Caret.Hwnd == hwnd) {
        if (Caret.Visible == 1) {
          Caret.Timer.Stop ();
          HideCaret ();
        }
        Caret.Hwnd = IntPtr.Zero;
        Caret.Visible = 0;
        Caret.On = false;
      }
    }
    
    [MonoTODO]
    internal override void DestroyCursor(IntPtr cursor) {
      throw new NotImplementedException ();
    }
  
    internal override void DestroyWindow(IntPtr handle) {
      Hwnd  hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (hwnd == null) {
        return;
      }

      SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
        
      CleanupCachedWindows (hwnd);

      ArrayList windows = new ArrayList ();

      AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);


      foreach (Hwnd h in windows) {
        SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
        h.zombie = true;
      }

      // TODO: This is crashing swf-messageboxes
      /*
      if (false && hwnd.whole_window != IntPtr.Zero)
        CFRelease (hwnd.whole_window);
      if (false && hwnd.client_window != IntPtr.Zero)
        CFRelease (hwnd.client_window);
      */

      if (WindowMapping [hwnd.Handle] != null) { 
        DisposeWindow ((IntPtr)(WindowMapping [hwnd.Handle]));
        WindowMapping.Remove (hwnd.Handle);
      }
    }

    internal override IntPtr DispatchMessage(ref MSG msg) {
      return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
    }
    
    internal override void DoEvents() {
                        MSG     msg = new MSG ();

      in_doevents = true;
      while (PeekMessage (null, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
                                TranslateMessage (ref msg);
                                DispatchMessage (ref msg);
                        }
      in_doevents = false;

    }

    internal override void EnableWindow(IntPtr handle, bool Enable) {
      //Like X11 we need not do anything here
    }

    internal override void EndLoop(Thread thread) {
    }

    internal void Exit () {
      GetMessageResult = false;
    }
    
    internal override IntPtr GetActive() {
      return ActiveWindow;
    }

    internal override Region GetClipRegion(IntPtr hwnd) {
      return null;
    }

    [MonoTODO]
    internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
      width = 12;
      height = 12;
      hotspot_x = 0;
      hotspot_y = 0;
    }
    
    internal override void GetDisplaySize(out Size size) {
      Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
      size = new Size ((int)bounds.size.width, (int)bounds.size.height);
    }

    internal override IntPtr GetParent(IntPtr handle) {
      Hwnd  hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);
      if (hwnd != null && hwnd.Parent != null) {
        return hwnd.Parent.Handle;
      }
      return IntPtr.Zero;
    }

    internal override IntPtr GetPreviousWindow(IntPtr handle) {
      return HIViewGetPreviousView(handle);
    }
    
    internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
      Carbon.QDPoint pt = new Carbon.QDPoint ();
      GetGlobalMouse (ref pt);
      x = pt.x;
      y = pt.y;
    }

    internal override IntPtr GetFocus() {
      return FocusWindow;
    }

    
    internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
      FontFamily ff = font.FontFamily;
      ascent = ff.GetCellAscent (font.Style);
      descent = ff.GetCellDescent (font.Style);
      return true;
    }
    
    internal override Point GetMenuOrigin(IntPtr handle) {
      Hwnd hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (hwnd != null) {
        return hwnd.MenuOrigin;
      }
      return Point.Empty;
    }

    internal override bool GetMessage(object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
      IntPtr evtRef = IntPtr.Zero;
      IntPtr target = GetEventDispatcherTarget();
      CheckTimers (DateTime.UtcNow);
      ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
      if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
        SendEventToEventTarget (evtRef, target);
        ReleaseEvent (evtRef);
      }
      
      object queueobj;
      loop:
      lock (queuelock) {

        if (MessageQueue.Count <= 0) {
          if (Idle != null) 
            Idle (this, EventArgs.Empty);
          else if (TimerList.Count == 0) {
            ReceiveNextEvent (0, IntPtr.Zero, 0.15, true, ref evtRef);
            if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
              SendEventToEventTarget (evtRef, target);
              ReleaseEvent (evtRef);
            }
          } else {
            ReceiveNextEvent (0, IntPtr.Zero, NextTimeout (), true, ref evtRef);
            if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
              SendEventToEventTarget (evtRef, target);
              ReleaseEvent (evtRef);
            }
          }
          msg.hwnd = IntPtr.Zero;
          msg.message = Msg.WM_ENTERIDLE;
          return GetMessageResult;
        }
        queueobj = MessageQueue.Dequeue ();
      }
      if (queueobj is GCHandle) {
        XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
        goto loop;
      } else {
        msg = (MSG)queueobj;
      }
      return GetMessageResult;
    }
    
    [MonoTODO]
    internal override bool GetText(IntPtr handle, out string text) {
      throw new NotImplementedException ();
    }
    
    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) {
      Hwnd    hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (hwnd != null) {
        x = hwnd.x;
        y = hwnd.y;
        width = hwnd.width;
        height = hwnd.height;

        PerformNCCalc(hwnd);

        client_width = hwnd.ClientRect.Width;
        client_height = hwnd.ClientRect.Height;

        return;
      }

      // Should we throw an exception or fail silently?
      // throw new ArgumentException("Called with an invalid window handle", "handle");

      x = 0;
      y = 0;
      width = 0;
      height = 0;
      client_width = 0;
      client_height = 0;
    }
    
    internal override FormWindowState GetWindowState(IntPtr hwnd) {
      IntPtr window = HIViewGetWindow (hwnd);

      if (IsWindowCollapsed (window))
        return FormWindowState.Minimized;
      if (IsWindowInStandardState (window, IntPtr.Zero, IntPtr.Zero))
        return FormWindowState.Maximized;

      return FormWindowState.Normal;
    }
    
    internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
      handle = Grab.Hwnd;
      GrabConfined = Grab.Confined;
      GrabArea = Grab.Area;
    }
    
    internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
      Grab.Hwnd = handle;
      Grab.Confined = confine_to_handle != IntPtr.Zero;
      /* FIXME: Set the Grab.Area */
    }
    
    internal override void UngrabWindow(IntPtr hwnd) {
                        bool was_grabbed = Grab.Hwnd != IntPtr.Zero;

                        Grab.Hwnd = IntPtr.Zero;
                        Grab.Confined = false;

                        if (was_grabbed) {
                                // lparam should be the handle to the window gaining the mouse capture,
                                // but we dont have that information like X11.
                                // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
                                SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
                        }
    }
    
    internal override void HandleException(Exception e) {
      StackTrace st = new StackTrace(e);
      Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
      Console.WriteLine("{0}{1}", e.Message, st.ToString());
    }
    
    internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear) {
      Hwnd hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (clear) {
        AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
      } else {
        AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
      } 
    }

    internal override void InvalidateNC (IntPtr handle)
    {
      Hwnd hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height); 
    }
    
    internal override bool IsEnabled(IntPtr handle) {
      return Hwnd.ObjectFromHandle(handle).Enabled;
    }
    
    internal override bool IsVisible(IntPtr handle) {
      return Hwnd.ObjectFromHandle(handle).visible;
    }
    
    internal override void KillTimer(Timer timer) {
      lock (TimerList) {
        TimerList.Remove(timer);
      }
    }


    internal override void OverrideCursor(IntPtr cursor) {
    }

    internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client) {
      PaintEventArgs  paint_event;
      Hwnd    hwnd;
      Hwnd    paint_hwnd; 
      
      hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
      if (msg.HWnd == handle) {
        paint_hwnd = hwnd;
      } else {
        paint_hwnd = Hwnd.ObjectFromHandle (handle);
      }
      
      if (Caret.Visible == 1) {
        Caret.Paused = true;
        HideCaret();
      }

      Graphics dc;

      if (client) {
        dc = Graphics.FromHwnd (paint_hwnd.client_window);

        Region clip_region = new Region ();
        clip_region.MakeEmpty();

        foreach (Rectangle r in hwnd.ClipRectangles) {
          clip_region.Union (r);
        }

        if (hwnd.UserClip != null) {
          clip_region.Intersect(hwnd.UserClip);
        }

        // FIXME: Clip region is hosed
        dc.Clip = clip_region;
        paint_event = new PaintEventArgs(dc, hwnd.Invalid);
        hwnd.expose_pending = false;
        hwnd.ClearInvalidArea();

        hwnd.drawing_stack.Push (paint_event);
        hwnd.drawing_stack.Push (dc);
      } else {
        dc = Graphics.FromHwnd (paint_hwnd.whole_window);

        if (!hwnd.nc_invalid.IsEmpty) {
          // FIXME: Clip region is hosed
          dc.SetClip (hwnd.nc_invalid);
          paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
        } else {
          paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
        }
        hwnd.nc_expose_pending = false;
        hwnd.ClearNcInvalidArea ();

        hwnd.drawing_stack.Push (paint_event);
        hwnd.drawing_stack.Push (dc);
      }

      return paint_event;
    }
    
    internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client) {
      Hwnd  hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      // FIXME: Pop is causing invalid stack ops sometimes; race condition?
      try {
        Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
        dc.Flush ();
        dc.Dispose ();
      
        PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
        pe.SetGraphics (null);
        pe.Dispose ();  
      } catch {}

      if (Caret.Visible == 1) {
        ShowCaret();
        Caret.Paused = false;
      }
    }
    
    internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
      IntPtr evtRef = IntPtr.Zero;
      IntPtr target = GetEventDispatcherTarget();
      CheckTimers (DateTime.UtcNow);
      ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
      if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
        SendEventToEventTarget (evtRef, target);
        ReleaseEvent (evtRef);
      }
      
      lock (queuelock) {
        if (MessageQueue.Count <= 0) {
          return false;
        } else {
          object queueobj;
          if (flags == (uint)PeekMessageFlags.PM_REMOVE)
            queueobj = MessageQueue.Dequeue ();
          else
            queueobj = MessageQueue.Peek ();

          if (queueobj is GCHandle) {
            XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
            return false;
          }
          msg = (MSG)queueobj;
          return true;
        }
      }
    }

    internal override bool PostMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
      MSG msg = new MSG();
      msg.hwnd = hwnd;
      msg.message = message;
      msg.wParam = wParam;
      msg.lParam = lParam;
      EnqueueMessage (msg);
      return true;
    }

    internal override void PostQuitMessage(int exitCode) {
      PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
    }

    internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave) {
    }

    internal override void RequestNCRecalc(IntPtr handle) {
      Hwnd hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (hwnd == null) {
        return;
      }

      PerformNCCalc(hwnd);
      SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
      InvalidateNC(handle);
    }

    [MonoTODO]    
    internal override void ResetMouseHover(IntPtr handle) {
      throw new NotImplementedException();
    }

    internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      Point point = ConvertScreenPointToClient (hwnd.ClientWindow, new Point (x, y));

      x = point.X;
      y = point.Y;
    }

    internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      Point point = ConvertScreenPointToClient (hwnd.WholeWindow, new Point (x, y));

      x = point.X;
      y = point.Y;
    }

    internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool clear) {
      /*
       * This used to use a HIViewScrollRect but this causes issues with the fact that we dont coalesce
       * updates properly with our short-circuiting of the window manager.  For now we'll do a less
       * efficient invalidation of the entire handle which appears to fix the problem
       * see bug #381084
       */
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
    }
    
    
    internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool clear) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
    }
    
    [MonoTODO]
    internal override void SendAsyncMethod (AsyncMethodData method) {
      // Fake async
      lock (queuelock) {
        MessageQueue.Enqueue (GCHandle.Alloc (method));
      }
    }

    [MonoTODO]
    internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
      return NativeWindow.WndProc(hwnd, message, wParam, lParam);
    }
    
    internal override int SendInput(IntPtr hwnd, Queue keys) {
      return 0;
    }


    internal override void SetCaretPos (IntPtr hwnd, int x, int y) {
      if (hwnd != IntPtr.Zero && hwnd == Caret.Hwnd) {
        Caret.X = x;
        Caret.Y = y;
        ClientToScreen (hwnd, ref x, ref y);
        SizeWindow (new Rectangle (x, y, Caret.Width, Caret.Height), CaretWindow);
        Caret.Timer.Stop ();
        HideCaret ();
        if (Caret.Visible == 1) {
          ShowCaret ();
          Caret.Timer.Start ();
        }
      }
    }

    internal override void SetClipRegion(IntPtr hwnd, Region region) {
      throw new NotImplementedException();
    }
    
    internal override void SetCursor(IntPtr window, IntPtr cursor) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (window);

      hwnd.Cursor = cursor;
    }
    
    internal override void SetCursorPos(IntPtr handle, int x, int y) {
      CGDisplayMoveCursorToPoint (CGMainDisplayID (), new Carbon.CGPoint (x, y));
    }
    
    internal override void SetFocus(IntPtr handle) {
      if (FocusWindow != IntPtr.Zero) {
        PostMessage(FocusWindow, Msg.WM_KILLFOCUS, handle, IntPtr.Zero);
      }
      PostMessage(handle, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
      FocusWindow = handle;
    }

    internal override void SetIcon(IntPtr handle, Icon icon) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      // FIXME: we need to map the icon for active window switches
      if (WindowMapping [hwnd.Handle] != null) {
        if (icon == null) { 
          RestoreApplicationDockTileImage ();
        } else {
          Bitmap    bitmap;
          int    size;
          IntPtr[]  data;
          int    index;
  
          bitmap = new Bitmap (128, 128);
          using (Graphics g = Graphics.FromImage (bitmap)) {
            g.DrawImage (icon.ToBitmap (), 0, 0, 128, 128);
          }
          index = 0;
          size = bitmap.Width * bitmap.Height;
          data = new IntPtr[size];
  
          for (int y = 0; y < bitmap.Height; y++) {
            for (int x = 0; x < bitmap.Width; x++) {
              int pixel = bitmap.GetPixel (x, y).ToArgb ();
              if (BitConverter.IsLittleEndian) {
                byte a = (byte) ((pixel >> 24) & 0xFF);
                byte r = (byte) ((pixel >> 16) & 0xFF);
                byte g = (byte) ((pixel >> 8) & 0xFF);
                byte b = (byte) (pixel & 0xFF);
                data[index++] = (IntPtr)(a + (r << 8) + (g << 16) + (b << 24));
              } else {
                data[index++] = (IntPtr)pixel;
              }
            }
          }

          IntPtr provider = CGDataProviderCreateWithData (IntPtr.Zero, data, size*4, IntPtr.Zero);
          IntPtr image = CGImageCreate (128, 128, 8, 32, 4*128, CGColorSpaceCreateDeviceRGB (), 4, provider, IntPtr.Zero, 0, 0);
          SetApplicationDockTileImage (image);
        }
      }
    }

    
    internal override void SetModal(IntPtr handle, bool Modal) {
      IntPtr hWnd = HIViewGetWindow (Hwnd.ObjectFromHandle (handle).WholeWindow);
      if (Modal)
        BeginAppModalStateForWindow (hWnd);
      else
        EndAppModalStateForWindow (hWnd);
      return;
    }

    internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
      IntPtr ParentHandle = IntPtr.Zero;
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      
      hwnd.Parent = Hwnd.ObjectFromHandle (parent);
      if (HIViewGetSuperview (hwnd.whole_window) != IntPtr.Zero) {
        HIViewRemoveFromSuperview (hwnd.whole_window);
      }
      if (hwnd.parent == null)
        HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
      HIViewAddSubview (hwnd.parent == null ? ParentHandle : hwnd.Parent.client_window, hwnd.whole_window);
      HIViewPlaceInSuperviewAt (hwnd.whole_window, hwnd.X, hwnd.Y);
      HIViewAddSubview (hwnd.whole_window, hwnd.client_window);
      HIViewPlaceInSuperviewAt (hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y);
      
      return IntPtr.Zero;
    }
    
    internal override void SetTimer (Timer timer) {
      lock (TimerList) {
        TimerList.Add (timer);
      }
    }
    
    internal override bool SetTopmost(IntPtr hWnd, bool Enabled) {
      HIViewSetZOrder (hWnd, 1, IntPtr.Zero);
      return true;
    }
    
    internal override bool SetOwner(IntPtr hWnd, IntPtr hWndOwner) {
      // TODO: Set window owner. 
      return true;
    }
    
    internal override bool SetVisible(IntPtr handle, bool visible, bool activate) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      object window = WindowMapping [hwnd.Handle];
      if (window != null)
        if (visible)
          ShowWindow ((IntPtr)window);
        else
          HideWindow ((IntPtr)window);
      
      if (visible)
        SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
          
      HIViewSetVisible (hwnd.whole_window, visible);
      HIViewSetVisible (hwnd.client_window, visible);

      hwnd.visible = visible;
      hwnd.Mapped = true;
      return true;
    }
    
    internal override void SetAllowDrop (IntPtr handle, bool value) {
      // Like X11 we allow drop on al windows and filter in our handler
    }

    internal override DragDropEffects StartDrag (IntPtr handle, object data, DragDropEffects allowed_effects) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      
      if (hwnd == null)
        throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");

      return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
    }

    internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
      Form form = Control.FromHandle (handle) as Form;
      if (form != null && form.window_manager == null && (border_style == FormBorderStyle.FixedToolWindow ||
        border_style == FormBorderStyle.SizableToolWindow)) {
        form.window_manager = new ToolWindowManager (form);
      }

      RequestNCRecalc(handle);
    }

    internal override void SetMenu(IntPtr handle, Menu menu) {
      Hwnd  hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);
      hwnd.menu = menu;

      RequestNCRecalc(handle);
    }
    
    internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
    }

    internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);

      if (hwnd == null) {
        return;
      }

      // Win32 automatically changes negative width/height to 0.
      if (width < 0)
        width = 0;
      if (height < 0)
        height = 0;
        
      // X requires a sanity check for width & height; otherwise it dies
      if (hwnd.zero_sized && width > 0 && height > 0) {
        if (hwnd.visible) {
          HIViewSetVisible(hwnd.WholeWindow, true);
        }
        hwnd.zero_sized = false;
      }

      if ((width < 1) || (height < 1)) {
        hwnd.zero_sized = true;
        HIViewSetVisible(hwnd.WholeWindow, false);
      }

      // Save a server roundtrip (and prevent a feedback loop)
      if ((hwnd.x == x) && (hwnd.y == y) && (hwnd.width == width) && (hwnd.height == height)) {
        return;
      }

      if (!hwnd.zero_sized) {
        hwnd.x = x;
        hwnd.y = y;
        hwnd.width = width;
        hwnd.height = height;
        SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);

        Control ctrl = Control.FromHandle (handle);
        CreateParams cp = ctrl.GetCreateParams ();
        Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (cp, new Size (width, height));
        Carbon.Rect rect = new Carbon.Rect ();

        if (WindowMapping [hwnd.Handle] != null) {
          if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
            SetRect (ref rect, (short)x, (short)y, (short)(x+TranslatedSize.Width), (short)(y+TranslatedSize.Height));
          } else {
            SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
          }
          SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
          Carbon.HIRect frame_rect = new Carbon.HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
          HIViewSetFrame (hwnd.whole_window, ref frame_rect);
          SetCaretPos (Caret.Hwnd, Caret.X, Caret.Y);
        } else {
          Carbon.HIRect frame_rect = new Carbon.HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
          HIViewSetFrame (hwnd.whole_window, ref frame_rect);
        }
        PerformNCCalc(hwnd);
      }

      hwnd.x = x;
      hwnd.y = y;
      hwnd.width = width;
      hwnd.height = height;
    }
    
    internal override void SetWindowState(IntPtr handle, FormWindowState state) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      IntPtr window = HIViewGetWindow (handle);

      switch (state) {
        case FormWindowState.Minimized: {
          CollapseWindow (window, true);
          break;
        }
        case FormWindowState.Normal: {
          ZoomWindow (window, 7, false);
          break;
        }
        case FormWindowState.Maximized: {
          Form form = Control.FromHandle (hwnd.Handle) as Form;
          if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
            Carbon.Rect rect = new Carbon.Rect ();
            Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
            SetRect (ref rect, (short)0, (short)0, (short)bounds.size.width, (short)bounds.size.height);
            SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
            HIViewSetFrame (hwnd.whole_window, ref bounds);
          } else {
            ZoomWindow (window, 8, false);
          }
          break;
        }
      }
    }
    
    internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      SetHwndStyles(hwnd, cp);
      
      if (WindowMapping [hwnd.Handle] != null) {
        Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
        if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) { 
          attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
        }
        if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
          attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
        }
        if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
          attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
        }
        if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
          attributes = Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute;
        }
        attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;

        Carbon.WindowAttributes outAttributes = Carbon.WindowAttributes.kWindowNoAttributes;
        GetWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], ref outAttributes);
        ChangeWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], attributes, outAttributes);
      }
    }

    internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
    }

    internal override double GetWindowTransparency(IntPtr handle)
    {
      return 1.0;
    }

    internal override TransparencySupport SupportsTransparency() {
      return TransparencySupport.None;
    }
    
    internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool Top, bool Bottom) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      
      if (Top) {
        HIViewSetZOrder (hwnd.whole_window, 2, IntPtr.Zero);
        return true;
      } else if (!Bottom) {
        Hwnd after_hwnd = Hwnd.ObjectFromHandle (after_handle);
        HIViewSetZOrder (hwnd.whole_window, 2, (after_handle == IntPtr.Zero ? IntPtr.Zero : after_hwnd.whole_window));
      } else {
        HIViewSetZOrder (hwnd.whole_window, 1, IntPtr.Zero);
        return true;
      }
      return false;
    }

    internal override void ShowCursor(bool show) {
      if (show)
        CGDisplayShowCursor (CGMainDisplayID ());
      else
        CGDisplayHideCursor (CGMainDisplayID ());
    }

    internal override object StartLoop(Thread thread) {
      return new object ();
    }
    
    [MonoTODO]
    internal override bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {
      throw new NotImplementedException();
    }

    [MonoTODO]
    internal override bool SystrayChange(IntPtr hwnd, string tip, Icon icon, ref ToolTip tt) {
      throw new NotImplementedException();
    }

    [MonoTODO]
    internal override void SystrayRemove(IntPtr hwnd, ref ToolTip tt) {
      throw new NotImplementedException();
    }

#if NET_2_0
    [MonoTODO]
    internal override void SystrayBalloon(IntPtr hwnd, int timeout, string title, string text, ToolTipIcon icon)
    {
      throw new NotImplementedException ();
    }
#endif
    
    internal override bool Text(IntPtr handle, string text) {
      Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
      if (WindowMapping [hwnd.Handle] != null) {
        SetWindowTitleWithCFString ((IntPtr)(WindowMapping [hwnd.Handle]), __CFStringMakeConstantString (text));
      }
      SetControlTitleWithCFString (hwnd.whole_window, __CFStringMakeConstantString (text));
      SetControlTitleWithCFString (hwnd.client_window, __CFStringMakeConstantString (text));
      return true;
    }
    
    internal override void UpdateWindow(IntPtr handle) {
      Hwnd  hwnd;

      hwnd = Hwnd.ObjectFromHandle(handle);

      if (!hwnd.visible || !HIViewIsVisible (handle)) {
        return;
      }

      SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
    }
    
    internal override bool TranslateMessage(ref MSG msg) {
      return Carbon.EventHandler.TranslateMessage (ref msg);
    }
    
    #region Reversible regions
    /* 
     * Quartz has no concept of XOR drawing due to its compositing nature
     * We fake this by mapping a overlay window on the first draw and mapping it on the second.
     * This has some issues with it because its POSSIBLE for ControlPaint.DrawReversible* to actually
     * reverse two regions at once.  We dont do this in MWF, but this behaviour woudn't work.
     * We could in theory cache the Rectangle/Color combination to handle this behaviour.
     *
     * PROBLEMS: This has some flicker / banding
     */
    internal void SizeWindow (Rectangle rect, IntPtr window) {
      Carbon.Rect qrect = new Carbon.Rect ();

      SetRect (ref qrect, (short)rect.X, (short)rect.Y, (short)(rect.X+rect.Width), (short)(rect.Y+rect.Height));

      SetWindowBounds (window, 33, ref qrect);
    }

    internal override void DrawReversibleLine(Point start, Point end, Color backColor) {
//      throw new NotImplementedException();
    }

    internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) {
//      throw new NotImplementedException();
    }

    internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
//      throw new NotImplementedException();
    }

    internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
      Rectangle size_rect = rect;
      int new_x = 0;
      int new_y = 0;

      if (ReverseWindowMapped) {
        HideWindow (ReverseWindow);
        ReverseWindowMapped = false;
      } else {
        ClientToScreen(handle, ref new_x, ref new_y);

        size_rect.X += new_x;
        size_rect.Y += new_y;

        SizeWindow (size_rect, ReverseWindow);
        ShowWindow (ReverseWindow);

        rect.X = 0;
        rect.Y = 0;
        rect.Width -= 1;
        rect.Height -= 1;

        Graphics g = Graphics.FromHwnd (HIViewGetRoot (ReverseWindow));

        for (int i = 0; i < line_width; i++) {
          g.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (Color.Black), rect);
          rect.X += 1;
          rect.Y += 1;
          rect.Width -= 1;
          rect.Height -= 1;
        }
  
        g.Flush ();
        g.Dispose ();
        
        ReverseWindowMapped = true;
      }
    }
    #endregion

    internal override SizeF GetAutoScaleSize(Font font) {
      Graphics        g;
      float           width;
      string          magic_string = "The quick brown fox jumped over the lazy dog.";
      double          magic_number = 44.549996948242189;

      g = Graphics.FromImage (new Bitmap (1, 1));

      width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
      return new SizeF(width, font.Height);
    }

    internal override Point MousePosition {
      get {
        return mouse_position;
      }
    }
    #endregion
    
    #region System information
    internal override int KeyboardSpeed { get{ throw new NotImplementedException(); } } 
    internal override int KeyboardDelay { get{ throw new NotImplementedException(); } } 

    internal override int CaptionHeight {
      get {
        return 19;
      }
    }

    internal override  Size CursorSize { get{ throw new NotImplementedException(); } }
    internal override  bool DragFullWindows { get{ throw new NotImplementedException(); } }
    internal override  Size DragSize {
      get {
        return new Size(4, 4);
      }
    }

    internal override  Size FrameBorderSize {
      get {
        return new Size (2, 2);
      }
    }

    internal override  Size IconSize { get{ throw new NotImplementedException(); } }
    internal override  Size MaxWindowTrackSize { get{ throw new NotImplementedException(); } }
    internal override bool MenuAccessKeysUnderlined {
      get {
        return false;
      }
    }
    internal override Size MinimizedWindowSpacingSize { get{ throw new NotImplementedException(); } }

    internal override Size MinimumWindowSize {
      get {
        return new Size(110, 22);
      }
    }

    internal override Keys ModifierKeys {
      get {
        return KeyboardHandler.ModifierKeys;
      }
    }
    internal override Size SmallIconSize { get{ throw new NotImplementedException(); } }
    internal override int MouseButtonCount { get{ throw new NotImplementedException(); } }
    internal override bool MouseButtonsSwapped { get{ throw new NotImplementedException(); } }
    internal override bool MouseWheelPresent { get{ throw new NotImplementedException(); } }

    internal override MouseButtons MouseButtons {
      get {
        return MouseState;
      }
    }

    internal override Rectangle VirtualScreen {
      get {
        return WorkingArea;
      }
    }

    internal override Rectangle WorkingArea { 
      get { 
        Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
        return new Rectangle ((int)bounds.origin.x, (int)bounds.origin.y, (int)bounds.size.width, (int)bounds.size.height);
      }
    }
    internal override bool ThemesEnabled {
      get {
        return XplatUICarbon.themes_enabled;
      }
    }
 

    #endregion
    
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewConvertPoint (ref Carbon.CGPoint point, IntPtr pView, IntPtr cView);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewChangeFeatures (IntPtr aView, ulong bitsin, ulong bitsout);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewFindByID (IntPtr rootWnd, Carbon.HIViewID id, ref IntPtr outPtr);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIGrowBoxViewSetTransparent (IntPtr GrowBox, bool transparency);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr HIViewGetRoot (IntPtr hWnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIObjectCreate (IntPtr cfStr, uint what, ref IntPtr hwnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIObjectRegisterSubclass (IntPtr classid, IntPtr superclassid, uint options, Carbon.EventDelegate upp, uint count, Carbon.EventTypeSpec [] list, IntPtr state, ref IntPtr cls);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewPlaceInSuperviewAt (IntPtr view, float x, float y);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewAddSubview (IntPtr parentHnd, IntPtr childHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr HIViewGetPreviousView (IntPtr aView);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr HIViewGetSuperview (IntPtr aView);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewRemoveFromSuperview (IntPtr aView);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewSetVisible (IntPtr vHnd, bool visible);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static bool HIViewIsVisible (IntPtr vHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewGetBounds (IntPtr vHnd, ref Carbon.HIRect r);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewScrollRect (IntPtr vHnd, ref Carbon.HIRect rect, float x, float y);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewSetZOrder (IntPtr hWnd, int cmd, IntPtr oHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewNewTrackingArea (IntPtr inView, IntPtr inShape, UInt64 inID, ref IntPtr outRef);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr HIViewGetWindow (IntPtr aView);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int HIViewSetFrame (IntPtr view_handle, ref Carbon.HIRect bounds);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static int HIViewSetNeedsDisplayInRect (IntPtr view_handle, ref Carbon.HIRect rect, bool needs_display);
    
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void SetRect (ref Carbon.Rect r, short left, short top, short right, short bottom);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    static extern int ActivateWindow (IntPtr windowHnd, bool inActivate);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    static extern bool IsWindowActive (IntPtr windowHnd);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    static extern int SetAutomaticControlDragTrackingEnabledForWindow (IntPtr window, bool enabled);

    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr GetEventDispatcherTarget ();
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int SendEventToEventTarget (IntPtr evt, IntPtr target);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int ReleaseEvent (IntPtr evt);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int ReceiveNextEvent (uint evtCount, IntPtr evtTypes, double timeout, bool processEvt, ref IntPtr evt);

    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static bool IsWindowCollapsed (IntPtr hWnd);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static bool IsWindowInStandardState (IntPtr hWnd, IntPtr a, IntPtr b);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void CollapseWindow (IntPtr hWnd, bool collapse);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void ZoomWindow (IntPtr hWnd, short partCode, bool front);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int GetWindowAttributes (IntPtr hWnd, ref Carbon.WindowAttributes outAttributes);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int ChangeWindowAttributes (IntPtr hWnd, Carbon.WindowAttributes inAttributes, Carbon.WindowAttributes outAttributes);
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static int GetGlobalMouse (ref Carbon.QDPoint outData);
    
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int BeginAppModalStateForWindow (IntPtr window);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int EndAppModalStateForWindow (IntPtr window);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int CreateNewWindow (Carbon.WindowClass klass, Carbon.WindowAttributes attributes, ref Carbon.Rect r, ref IntPtr window);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int DisposeWindow (IntPtr wHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static int ShowWindow (IntPtr wHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static int HideWindow (IntPtr wHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static bool IsWindowVisible (IntPtr wHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int SetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int GetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);

    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int SetControlTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int SetWindowTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static IntPtr __CFStringMakeConstantString (string cString);
    
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    internal extern static int CFRelease (IntPtr wHnd);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static short GetMBarHeight ();
    
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void AlertSoundPlay ();

    #region Cursor imports
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static Carbon.HIRect CGDisplayBounds (IntPtr displayID);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr CGMainDisplayID ();
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void CGDisplayShowCursor (IntPtr display);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void CGDisplayHideCursor (IntPtr display);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void CGDisplayMoveCursorToPoint (IntPtr display, Carbon.CGPoint point);
    #endregion

    #region Process imports
    [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int GetCurrentProcess (ref Carbon.ProcessSerialNumber psn);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int TransformProcessType (ref Carbon.ProcessSerialNumber psn, uint type);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static int SetFrontProcess (ref Carbon.ProcessSerialNumber psn);
    #endregion

    #region Dock tile imports
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr CGColorSpaceCreateDeviceRGB();
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static IntPtr CGDataProviderCreateWithData (IntPtr info, IntPtr [] data, int size, IntPtr releasefunc);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    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);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void SetApplicationDockTileImage(IntPtr imageRef);
    [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    extern static void RestoreApplicationDockTileImage();
    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.