// 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 // // using System; using System.Threading; using System.Drawing; using System.ComponentModel; using System.Collections; using System.Diagnostics; using System.Runtime.InteropServices; using Carbon = System.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 UnactiveWindow; 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 () { if (Marshal.SizeOf () == 8){ 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"); } // 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) { UnactiveWindow = ActiveWindow; 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, bool copy) { 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.GetDefaultClassName (GetType ()); 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) { /* Expand the region slightly. * See bug 464464. */ Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1); clip_region.Union (r2); } 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(); } [MonoTODO] internal override void SystrayBalloon(IntPtr hwnd, int timeout, string title, string text, ToolTipIcon icon) { throw new NotImplementedException (); } 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); } } [MonoTODO] internal override Screen[] AllScreens { get { return null; } } 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 } }