1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2007 Novell, Inc.
23 // Geoff Norton <gnorton@novell.com>
28 using System.Threading;
30 using System.ComponentModel;
31 using System.Collections;
32 using System.Diagnostics;
33 using System.Runtime.InteropServices;
35 using Carbon = System.Windows.Forms.CarbonInternal;
38 namespace System.Windows.Forms {
39 internal delegate Rectangle [] HwndDelegate (IntPtr handle);
41 internal class XplatUICarbon : XplatUIDriver {
42 #region Local Variables
43 // General driver variables
44 private static XplatUICarbon Instance;
45 private static int RefCount;
46 private static bool themes_enabled;
48 // Internal members available to the event handler sub-system
49 internal static IntPtr FocusWindow;
50 internal static IntPtr ActiveWindow;
51 internal static IntPtr UnactiveWindow;
52 internal static IntPtr ReverseWindow;
53 internal static IntPtr CaretWindow;
55 internal static Hwnd MouseHwnd;
57 internal static MouseButtons MouseState;
58 internal static Carbon.Hover Hover;
60 internal static HwndDelegate HwndDelegate = new HwndDelegate (GetClippingRectangles);
62 internal Point mouse_position;
65 internal Carbon.ApplicationHandler ApplicationHandler;
66 internal Carbon.ControlHandler ControlHandler;
67 internal Carbon.HIObjectHandler HIObjectHandler;
68 internal Carbon.KeyboardHandler KeyboardHandler;
69 internal Carbon.MouseHandler MouseHandler;
70 internal Carbon.WindowHandler WindowHandler;
73 internal static GrabStruct Grab;
74 internal static Carbon.Caret Caret;
75 private static Carbon.Dnd Dnd;
76 private static Hashtable WindowMapping;
77 private static Hashtable HandleMapping;
78 private static IntPtr FosterParent;
79 private static IntPtr Subclass;
80 private static int MenuBarHeight;
81 internal static ArrayList UtilityWindows;
84 private static Queue MessageQueue;
85 private static bool GetMessageResult;
87 private static bool ReverseWindowMapped;
90 private ArrayList TimerList;
91 private static bool in_doevents;
93 static readonly object instancelock = new object ();
94 static readonly object queuelock = new object ();
97 internal override event EventHandler Idle;
101 private XplatUICarbon() {
104 TimerList = new ArrayList ();
106 MessageQueue = new Queue ();
112 // FIXME: Clean up the FosterParent here.
116 #region Singleton specific code
117 public static XplatUICarbon GetInstance() {
118 lock (instancelock) {
119 if (Instance == null) {
120 Instance = new XplatUICarbon ();
127 public int Reference {
134 #region Internal methods
135 internal void AddExpose (Hwnd hwnd, bool client, Carbon.HIRect rect) {
136 AddExpose (hwnd, client, (int) rect.origin.x, (int) rect.origin.y, (int) rect.size.width, (int) rect.size.height);
139 internal void AddExpose (Hwnd hwnd, bool client, Rectangle rect) {
140 AddExpose (hwnd, client, (int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height);
143 internal void FlushQueue () {
144 CheckTimers (DateTime.UtcNow);
146 while (MessageQueue.Count > 0) {
147 object queueobj = MessageQueue.Dequeue ();
148 if (queueobj is GCHandle) {
149 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
151 MSG msg = (MSG)queueobj;
152 NativeWindow.WndProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
158 internal static Rectangle [] GetClippingRectangles (IntPtr handle) {
159 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
163 if (hwnd.Handle != handle)
164 return new Rectangle [] {hwnd.ClientRect};
166 return (Rectangle []) hwnd.GetClippingRectangles ().ToArray (typeof (Rectangle));
169 internal IntPtr GetMousewParam(int Delta) {
172 if ((MouseState & MouseButtons.Left) != 0) {
173 result |= (int)MsgButtons.MK_LBUTTON;
176 if ((MouseState & MouseButtons.Middle) != 0) {
177 result |= (int)MsgButtons.MK_MBUTTON;
180 if ((MouseState & MouseButtons.Right) != 0) {
181 result |= (int)MsgButtons.MK_RBUTTON;
184 Keys mods = ModifierKeys;
185 if ((mods & Keys.Control) != 0) {
186 result |= (int)MsgButtons.MK_CONTROL;
189 if ((mods & Keys.Shift) != 0) {
190 result |= (int)MsgButtons.MK_SHIFT;
193 result |= Delta << 16;
195 return (IntPtr)result;
198 internal IntPtr HandleToWindow (IntPtr handle) {
199 if (HandleMapping [handle] != null)
200 return (IntPtr) HandleMapping [handle];
204 internal void Initialize () {
205 if (Marshal.SizeOf<IntPtr> () == 8){
206 Console.Error.WriteLine ("WARNING: The Carbon driver has not been ported to 64bits, and very few parts of Windows.Forms will work properly, or at all");
208 // Initialize the event handlers
209 Carbon.EventHandler.Driver = this;
210 ApplicationHandler = new Carbon.ApplicationHandler (this);
211 ControlHandler = new Carbon.ControlHandler (this);
212 HIObjectHandler = new Carbon.HIObjectHandler (this);
213 KeyboardHandler = new Carbon.KeyboardHandler (this);
214 MouseHandler = new Carbon.MouseHandler (this);
215 WindowHandler = new Carbon.WindowHandler (this);
217 // Initilize the mouse controls
218 Hover.Interval = 500;
219 Hover.Timer = new Timer ();
220 Hover.Timer.Enabled = false;
221 Hover.Timer.Interval = Hover.Interval;
222 Hover.Timer.Tick += new EventHandler (HoverCallback);
225 MouseState = MouseButtons.None;
226 mouse_position = Point.Empty;
228 // Initialize the Caret
229 Caret.Timer = new Timer ();
230 Caret.Timer.Interval = 500;
231 Caret.Timer.Tick += new EventHandler (CaretCallback);
233 // Initialize the D&D
234 Dnd = new Carbon.Dnd ();
236 // Initialize the Carbon Specific stuff
237 WindowMapping = new Hashtable ();
238 HandleMapping = new Hashtable ();
239 UtilityWindows = new ArrayList ();
241 // Initialize the FosterParent
242 Carbon.Rect rect = new Carbon.Rect ();
243 SetRect (ref rect, (short)0, (short)0, (short)0, (short)0);
244 Carbon.ProcessSerialNumber psn = new Carbon.ProcessSerialNumber();
246 GetCurrentProcess( ref psn );
247 TransformProcessType (ref psn, 1);
248 SetFrontProcess (ref psn);
250 HIObjectRegisterSubclass (__CFStringMakeConstantString ("com.novell.mwfview"), __CFStringMakeConstantString ("com.apple.hiview"), 0, Carbon.EventHandler.EventHandlerDelegate, (uint)Carbon.EventHandler.HIObjectEvents.Length, Carbon.EventHandler.HIObjectEvents, IntPtr.Zero, ref Subclass);
252 Carbon.EventHandler.InstallApplicationHandler ();
254 CreateNewWindow (Carbon.WindowClass.kDocumentWindowClass, Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCloseBoxAttribute | Carbon.WindowAttributes.kWindowFullZoomAttribute | Carbon.WindowAttributes.kWindowCollapseBoxAttribute | Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute, ref rect, ref FosterParent);
256 CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref ReverseWindow);
257 CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref CaretWindow);
259 // Get some values about bar heights
260 Carbon.Rect structRect = new Carbon.Rect ();
261 Carbon.Rect contentRect = new Carbon.Rect ();
262 GetWindowBounds (FosterParent, 32, ref structRect);
263 GetWindowBounds (FosterParent, 33, ref contentRect);
265 MenuBarHeight = GetMBarHeight ();
268 FocusWindow = IntPtr.Zero;
271 GetMessageResult = true;
273 ReverseWindowMapped = false;
276 internal void PerformNCCalc(Hwnd hwnd) {
277 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
281 rect = new Rectangle (0, 0, hwnd.Width, hwnd.Height);
283 ncp = new XplatUIWin32.NCCALCSIZE_PARAMS();
284 ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ncp));
286 ncp.rgrc1.left = rect.Left;
287 ncp.rgrc1.top = rect.Top;
288 ncp.rgrc1.right = rect.Right;
289 ncp.rgrc1.bottom = rect.Bottom;
291 Marshal.StructureToPtr(ncp, ptr, true);
292 NativeWindow.WndProc(hwnd.client_window, Msg.WM_NCCALCSIZE, (IntPtr)1, ptr);
293 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(ptr, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
294 Marshal.FreeHGlobal(ptr);
297 rect = new Rectangle(ncp.rgrc1.left, ncp.rgrc1.top, ncp.rgrc1.right - ncp.rgrc1.left, ncp.rgrc1.bottom - ncp.rgrc1.top);
298 hwnd.ClientRect = rect;
300 rect = TranslateClientRectangleToQuartzClientRectangle (hwnd);
303 Carbon.HIRect r = new Carbon.HIRect (rect.X, rect.Y, rect.Width, rect.Height);
304 HIViewSetFrame (hwnd.client_window, ref r);
307 AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
310 internal void ScreenToClient(IntPtr handle, ref Carbon.QDPoint point) {
311 int x = (int) point.x;
312 int y = (int) point.y;
314 ScreenToClient (handle, ref x, ref y);
320 internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd) {
321 return TranslateClientRectangleToQuartzClientRectangle (hwnd, Control.FromHandle (hwnd.Handle));
324 internal static Rectangle TranslateClientRectangleToQuartzClientRectangle (Hwnd hwnd, Control ctrl) {
326 * If this is a form with no window manager, X is handling all the border and caption painting
327 * so remove that from the area (since the area we set of the window here is the part of the window
328 * we're painting in only)
330 Rectangle rect = hwnd.ClientRect;
331 Form form = ctrl as Form;
332 CreateParams cp = null;
335 cp = form.GetCreateParams ();
337 if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
338 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
339 Rectangle qrect = rect;
341 qrect.Y -= borders.top;
342 qrect.X -= borders.left;
343 qrect.Width += borders.left + borders.right;
344 qrect.Height += borders.top + borders.bottom;
349 if (rect.Width < 1 || rect.Height < 1) {
359 internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp) {
360 return TranslateWindowSizeToQuartzWindowSize (cp, new Size (cp.Width, cp.Height));
363 internal static Size TranslateWindowSizeToQuartzWindowSize (CreateParams cp, Size size) {
365 * If this is a form with no window manager, X is handling all the border and caption painting
366 * so remove that from the area (since the area we set of the window here is the part of the window
367 * we're painting in only)
369 Form form = cp.control as Form;
370 if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
371 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
374 qsize.Width -= borders.left + borders.right;
375 qsize.Height -= borders.top + borders.bottom;
380 if (size.Height == 0)
387 internal static Size TranslateQuartzWindowSizeToWindowSize (CreateParams cp, int width, int height) {
389 * If this is a form with no window manager, X is handling all the border and caption painting
390 * so remove that from the area (since the area we set of the window here is the part of the window
391 * we're painting in only)
393 Size size = new Size (width, height);
394 Form form = cp.control as Form;
395 if (form != null && (form.window_manager == null || cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW))) {
396 Hwnd.Borders borders = Hwnd.GetBorders (cp, null);
399 qsize.Width += borders.left + borders.right;
400 qsize.Height += borders.top + borders.bottom;
410 private void CaretCallback (object sender, EventArgs e) {
422 private void HoverCallback (object sender, EventArgs e) {
423 if ((Hover.X == mouse_position.X) && (Hover.Y == mouse_position.Y)) {
424 MSG msg = new MSG ();
425 msg.hwnd = Hover.Hwnd;
426 msg.message = Msg.WM_MOUSEHOVER;
427 msg.wParam = GetMousewParam (0);
428 msg.lParam = (IntPtr)((ushort)Hover.X << 16 | (ushort)Hover.X);
429 EnqueueMessage (msg);
434 #region Private Methods
435 private Point ConvertScreenPointToClient (IntPtr handle, Point point) {
436 Point converted_point = new Point ();
437 Carbon.Rect window_bounds = new Carbon.Rect ();
438 Carbon.CGPoint native_point = new Carbon.CGPoint ();
440 GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
442 native_point.x = (point.X - window_bounds.left);
443 native_point.y = (point.Y - window_bounds.top);
445 HIViewConvertPoint (ref native_point, IntPtr.Zero, handle);
447 converted_point.X = (int)native_point.x;
448 converted_point.Y = (int)native_point.y;
450 return converted_point;
453 private Point ConvertClientPointToScreen (IntPtr handle, Point point) {
454 Point converted_point = new Point ();
455 Carbon.Rect window_bounds = new Carbon.Rect ();
456 Carbon.CGPoint native_point = new Carbon.CGPoint ();
458 GetWindowBounds (HIViewGetWindow (handle), 32, ref window_bounds);
460 native_point.x = point.X;
461 native_point.y = point.Y;
463 HIViewConvertPoint (ref native_point, handle, IntPtr.Zero);
465 converted_point.X = (int)(native_point.x + window_bounds.left);
466 converted_point.Y = (int)(native_point.y + window_bounds.top);
468 return converted_point;
471 private double NextTimeout () {
472 DateTime now = DateTime.UtcNow;
473 int timeout = 0x7FFFFFF;
475 foreach (Timer timer in TimerList) {
476 int next = (int) (timer.Expires - now).TotalMilliseconds;
483 if (timeout < Timer.Minimum)
484 timeout = Timer.Minimum;
486 return (double)((double)timeout/1000);
489 private void CheckTimers (DateTime now) {
491 int count = TimerList.Count;
494 for (int i = 0; i < TimerList.Count; i++) {
495 Timer timer = (Timer) TimerList [i];
496 if (timer.Enabled && timer.Expires <= now) {
498 // - Before MainForm.OnLoad if DoEvents () is called.
499 // - After MainForm.OnLoad if not.
502 (Application.MWFThread.Current.Context != null &&
503 Application.MWFThread.Current.Context.MainForm != null &&
504 Application.MWFThread.Current.Context.MainForm.IsLoaded)) {
513 private void WaitForHwndMessage (Hwnd hwnd, Msg message) {
514 MSG msg = new MSG ();
518 if (GetMessage(null, ref msg, IntPtr.Zero, 0, 0)) {
519 if ((Msg)msg.message == Msg.WM_QUIT) {
524 if (msg.hwnd == hwnd.Handle) {
525 if ((Msg)msg.message == message)
527 else if ((Msg)msg.message == Msg.WM_DESTROY)
531 TranslateMessage (ref msg);
532 DispatchMessage (ref msg);
538 private void SendParentNotify(IntPtr child, Msg cause, int x, int y) {
541 if (child == IntPtr.Zero) {
545 hwnd = Hwnd.GetObjectFromWindow (child);
551 if (hwnd.Handle == IntPtr.Zero) {
555 if (ExStyleSet ((int) hwnd.initial_ex_style, WindowExStyles.WS_EX_NOPARENTNOTIFY)) {
559 if (hwnd.Parent == null) {
563 if (hwnd.Parent.Handle == IntPtr.Zero) {
567 if (cause == Msg.WM_CREATE || cause == Msg.WM_DESTROY) {
568 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), child);
570 SendMessage(hwnd.Parent.Handle, Msg.WM_PARENTNOTIFY, Control.MakeParam((int)cause, 0), Control.MakeParam(x, y));
573 SendParentNotify (hwnd.Parent.Handle, cause, x, y);
576 private bool StyleSet (int s, WindowStyles ws) {
577 return (s & (int)ws) == (int)ws;
580 private bool ExStyleSet (int ex, WindowExStyles exws) {
581 return (ex & (int)exws) == (int)exws;
584 private void DeriveStyles(int Style, int ExStyle, out FormBorderStyle border_style, out bool border_static, out TitleStyle title_style, out int caption_height, out int tool_caption_height) {
587 tool_caption_height = 0;
588 border_static = false;
590 if (StyleSet (Style, WindowStyles.WS_CHILD)) {
591 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
592 border_style = FormBorderStyle.Fixed3D;
593 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
594 border_style = FormBorderStyle.Fixed3D;
595 border_static = true;
596 } else if (!StyleSet (Style, WindowStyles.WS_BORDER)) {
597 border_style = FormBorderStyle.None;
599 border_style = FormBorderStyle.FixedSingle;
601 title_style = TitleStyle.None;
603 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
605 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
606 title_style = TitleStyle.Tool;
608 title_style = TitleStyle.Normal;
612 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_MDICHILD)) {
615 if (StyleSet (Style, WindowStyles.WS_OVERLAPPEDWINDOW) ||
616 ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
617 border_style = (FormBorderStyle) 0xFFFF;
619 border_style = FormBorderStyle.None;
624 title_style = TitleStyle.None;
625 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
626 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
627 title_style = TitleStyle.Tool;
629 title_style = TitleStyle.Normal;
633 border_style = FormBorderStyle.None;
635 if (StyleSet (Style, WindowStyles.WS_THICKFRAME)) {
636 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
637 border_style = FormBorderStyle.SizableToolWindow;
639 border_style = FormBorderStyle.Sizable;
642 if (StyleSet (Style, WindowStyles.WS_CAPTION)) {
643 if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_CLIENTEDGE)) {
644 border_style = FormBorderStyle.Fixed3D;
645 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_STATICEDGE)) {
646 border_style = FormBorderStyle.Fixed3D;
647 border_static = true;
648 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_DLGMODALFRAME)) {
649 border_style = FormBorderStyle.FixedDialog;
650 } else if (ExStyleSet (ExStyle, WindowExStyles.WS_EX_TOOLWINDOW)) {
651 border_style = FormBorderStyle.FixedToolWindow;
652 } else if (StyleSet (Style, WindowStyles.WS_BORDER)) {
653 border_style = FormBorderStyle.FixedSingle;
656 if (StyleSet (Style, WindowStyles.WS_BORDER)) {
657 border_style = FormBorderStyle.FixedSingle;
664 private void SetHwndStyles(Hwnd hwnd, CreateParams cp) {
665 DeriveStyles(cp.Style, cp.ExStyle, out hwnd.border_style, out hwnd.border_static, out hwnd.title_style, out hwnd.caption_height, out hwnd.tool_caption_height);
668 private void ShowCaret () {
672 ShowWindow (CaretWindow);
673 Graphics g = Graphics.FromHwnd (HIViewGetRoot (CaretWindow));
675 g.FillRectangle (new SolidBrush (Color.Black), new Rectangle (0, 0, Caret.Width, Caret.Height));
680 private void HideCaret () {
684 HideWindow (CaretWindow);
687 private void AccumulateDestroyedHandles (Control c, ArrayList list) {
689 Control[] controls = c.Controls.GetAllControls ();
691 if (c.IsHandleCreated && !c.IsDisposed) {
692 Hwnd hwnd = Hwnd.ObjectFromHandle(c.Handle);
695 CleanupCachedWindows (hwnd);
698 for (int i = 0; i < controls.Length; i ++) {
699 AccumulateDestroyedHandles (controls[i], list);
705 private void CleanupCachedWindows (Hwnd hwnd) {
706 if (ActiveWindow == hwnd.Handle) {
707 SendMessage(hwnd.client_window, Msg.WM_ACTIVATE, (IntPtr)WindowActiveFlags.WA_INACTIVE, IntPtr.Zero);
708 ActiveWindow = IntPtr.Zero;
711 if (FocusWindow == hwnd.Handle) {
712 SendMessage(hwnd.client_window, Msg.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
713 FocusWindow = IntPtr.Zero;
716 if (Grab.Hwnd == hwnd.Handle) {
717 Grab.Hwnd = IntPtr.Zero;
718 Grab.Confined = false;
721 DestroyCaret (hwnd.Handle);
724 private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) {
726 if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) {
730 // Keep the invalid area as small as needed
731 if ((x + width) > hwnd.width) {
732 width = hwnd.width - x;
735 if ((y + height) > hwnd.height) {
736 height = hwnd.height - y;
740 hwnd.AddInvalidArea(x, y, width, height);
741 if (!hwnd.expose_pending && hwnd.visible) {
742 MSG msg = new MSG ();
743 msg.message = Msg.WM_PAINT;
744 msg.hwnd = hwnd.Handle;
745 EnqueueMessage (msg);
746 hwnd.expose_pending = true;
749 hwnd.AddNcInvalidArea (x, y, width, height);
750 if (!hwnd.nc_expose_pending && hwnd.visible) {
751 MSG msg = new MSG ();
752 Region rgn = new Region (hwnd.Invalid);
753 IntPtr hrgn = rgn.GetHrgn (null); // Graphics object isn't needed
754 msg.message = Msg.WM_NCPAINT;
755 msg.wParam = hrgn == IntPtr.Zero ? (IntPtr)1 : hrgn;
757 msg.hwnd = hwnd.Handle;
758 EnqueueMessage (msg);
759 hwnd.nc_expose_pending = true;
766 #region Public Methods
767 internal void EnqueueMessage (MSG msg) {
769 MessageQueue.Enqueue (msg);
773 internal override void RaiseIdle (EventArgs e)
779 internal override IntPtr InitializeDriver() {
783 internal override void ShutdownDriver(IntPtr token) {
786 internal override void EnableThemes() {
787 themes_enabled = true;
790 internal override void Activate(IntPtr handle) {
791 if (ActiveWindow != IntPtr.Zero) {
792 UnactiveWindow = ActiveWindow;
793 ActivateWindow (HIViewGetWindow (ActiveWindow), false);
795 ActivateWindow (HIViewGetWindow (handle), true);
796 ActiveWindow = handle;
799 internal override void AudibleAlert(AlertType alert) {
803 internal override void BeginMoveResize (IntPtr handle) {
806 internal override void CaretVisible (IntPtr hwnd, bool visible) {
807 if (Caret.Hwnd == hwnd) {
809 if (Caret.Visible < 1) {
812 if (Caret.Visible == 1) {
814 Caret.Timer.Start ();
819 if (Caret.Visible == 0) {
827 internal override bool CalculateWindowRect(ref Rectangle ClientRect, CreateParams cp, Menu menu, out Rectangle WindowRect) {
828 WindowRect = Hwnd.GetWindowRectangle (cp, menu, ClientRect);
832 internal override void ClientToScreen(IntPtr handle, ref int x, ref int y) {
833 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
835 Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));
841 internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {
842 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
844 Point point = ConvertClientPointToScreen (hwnd.ClientWindow, new Point (x, y));
850 internal override int[] ClipboardAvailableFormats(IntPtr handle) {
851 ArrayList list = new ArrayList ();
852 DataFormats.Format f = DataFormats.Format.List;
859 return (int [])list.ToArray (typeof (int));
862 internal override void ClipboardClose(IntPtr handle) {
865 //TODO: Map our internal formats to the right os code where we can
866 internal override int ClipboardGetID(IntPtr handle, string format) {
867 return (int)__CFStringMakeConstantString (format);
870 internal override IntPtr ClipboardOpen(bool primary_selection) {
871 if (primary_selection)
872 return Carbon.Pasteboard.Primary;
873 return Carbon.Pasteboard.Application;
876 internal override object ClipboardRetrieve(IntPtr handle, int type, XplatUI.ClipboardToObject converter) {
877 return Carbon.Pasteboard.Retrieve (handle, type);
880 internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy) {
881 Carbon.Pasteboard.Store (handle, obj, type);
884 internal override void CreateCaret (IntPtr hwnd, int width, int height) {
885 if (Caret.Hwnd != IntPtr.Zero)
886 DestroyCaret (Caret.Hwnd);
890 Caret.Height = height;
895 internal override IntPtr CreateWindow(CreateParams cp) {
897 Hwnd parent_hwnd = null;
906 IntPtr WholeWindowTracking;
907 IntPtr ClientWindowTracking;
915 ParentHandle = IntPtr.Zero;
916 WindowHandle = IntPtr.Zero;
917 WholeWindow = IntPtr.Zero;
918 ClientWindow = IntPtr.Zero;
919 WholeWindowTracking = IntPtr.Zero;
920 ClientWindowTracking = IntPtr.Zero;
922 if (Width < 1) Width = 1;
923 if (Height < 1) Height = 1;
925 if (cp.Parent != IntPtr.Zero) {
926 parent_hwnd = Hwnd.ObjectFromHandle (cp.Parent);
927 ParentHandle = parent_hwnd.client_window;
929 if (StyleSet (cp.Style, WindowStyles.WS_CHILD)) {
930 HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
935 if (cp.control is Form) {
936 next = Hwnd.GetNextStackedFormLocation (cp, parent_hwnd);
944 hwnd.height = Height;
945 hwnd.Parent = Hwnd.ObjectFromHandle (cp.Parent);
946 hwnd.initial_style = cp.WindowStyle;
947 hwnd.initial_ex_style = cp.WindowExStyle;
948 hwnd.visible = false;
950 if (StyleSet (cp.Style, WindowStyles.WS_DISABLED)) {
951 hwnd.enabled = false;
954 ClientWindow = IntPtr.Zero;
956 Size QWindowSize = TranslateWindowSizeToQuartzWindowSize (cp);
957 Rectangle QClientRect = TranslateClientRectangleToQuartzClientRectangle (hwnd, cp.control);
959 SetHwndStyles(hwnd, cp);
961 if (ParentHandle == IntPtr.Zero) {
962 IntPtr WindowView = IntPtr.Zero;
963 IntPtr GrowBox = IntPtr.Zero;
964 Carbon.WindowClass windowklass = Carbon.WindowClass.kOverlayWindowClass;
965 Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
966 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZEBOX)) {
967 attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
969 if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZEBOX)) {
970 attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
972 if (StyleSet (cp.Style, WindowStyles.WS_SYSMENU)) {
973 attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
975 if (StyleSet (cp.Style, WindowStyles.WS_CAPTION)) {
976 windowklass = Carbon.WindowClass.kDocumentWindowClass;
978 if (hwnd.border_style == FormBorderStyle.FixedToolWindow) {
979 windowklass = Carbon.WindowClass.kUtilityWindowClass;
980 } else if (hwnd.border_style == FormBorderStyle.SizableToolWindow) {
981 attributes |= Carbon.WindowAttributes.kWindowResizableAttribute;
982 windowklass = Carbon.WindowClass.kUtilityWindowClass;
984 if (windowklass == Carbon.WindowClass.kOverlayWindowClass) {
985 attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
987 attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;
989 Carbon.Rect rect = new Carbon.Rect ();
990 if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
991 SetRect (ref rect, (short)X, (short)(Y), (short)(X + QWindowSize.Width), (short)(Y + QWindowSize.Height));
993 SetRect (ref rect, (short)X, (short)(Y + MenuBarHeight), (short)(X + QWindowSize.Width), (short)(Y + MenuBarHeight + QWindowSize.Height));
996 CreateNewWindow (windowklass, attributes, ref rect, ref WindowHandle);
998 Carbon.EventHandler.InstallWindowHandler (WindowHandle);
999 HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref WindowView);
1000 HIViewFindByID (HIViewGetRoot (WindowHandle), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 7), ref GrowBox);
1001 HIGrowBoxViewSetTransparent (GrowBox, true);
1002 SetAutomaticControlDragTrackingEnabledForWindow (WindowHandle, true);
1003 ParentHandle = WindowView;
1006 HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref WholeWindow);
1007 HIObjectCreate (__CFStringMakeConstantString ("com.novell.mwfview"), 0, ref ClientWindow);
1009 Carbon.EventHandler.InstallControlHandler (WholeWindow);
1010 Carbon.EventHandler.InstallControlHandler (ClientWindow);
1012 // Enable embedding on controls
1013 HIViewChangeFeatures (WholeWindow, 1<<1, 0);
1014 HIViewChangeFeatures (ClientWindow, 1<<1, 0);
1016 HIViewNewTrackingArea (WholeWindow, IntPtr.Zero, (UInt64)WholeWindow, ref WholeWindowTracking);
1017 HIViewNewTrackingArea (ClientWindow, IntPtr.Zero, (UInt64)ClientWindow, ref ClientWindowTracking);
1018 Carbon.HIRect WholeRect;
1019 if (WindowHandle != IntPtr.Zero) {
1020 WholeRect = new Carbon.HIRect (0, 0, QWindowSize.Width, QWindowSize.Height);
1022 WholeRect = new Carbon.HIRect (X, Y, QWindowSize.Width, QWindowSize.Height);
1024 Carbon.HIRect ClientRect = new Carbon.HIRect (QClientRect.X, QClientRect.Y, QClientRect.Width, QClientRect.Height);
1025 HIViewSetFrame (WholeWindow, ref WholeRect);
1026 HIViewSetFrame (ClientWindow, ref ClientRect);
1028 HIViewAddSubview (ParentHandle, WholeWindow);
1029 HIViewAddSubview (WholeWindow, ClientWindow);
1031 hwnd.WholeWindow = WholeWindow;
1032 hwnd.ClientWindow = ClientWindow;
1034 if (WindowHandle != IntPtr.Zero) {
1035 WindowMapping [hwnd.Handle] = WindowHandle;
1036 HandleMapping [WindowHandle] = hwnd.Handle;
1037 if (hwnd.border_style == FormBorderStyle.FixedToolWindow || hwnd.border_style == FormBorderStyle.SizableToolWindow) {
1038 UtilityWindows.Add (WindowHandle);
1042 // Allow dnd on controls
1043 Dnd.SetAllowDrop (hwnd, true);
1045 Text (hwnd.Handle, cp.Caption);
1047 SendMessage (hwnd.Handle, Msg.WM_CREATE, (IntPtr)1, IntPtr.Zero /* XXX unused */);
1048 SendParentNotify (hwnd.Handle, Msg.WM_CREATE, int.MaxValue, int.MaxValue);
1050 if (StyleSet (cp.Style, WindowStyles.WS_VISIBLE)) {
1051 if (WindowHandle != IntPtr.Zero) {
1052 if (Control.FromHandle(hwnd.Handle) is Form) {
1053 Form f = Control.FromHandle(hwnd.Handle) as Form;
1054 if (f.WindowState == FormWindowState.Normal) {
1055 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1058 ShowWindow (WindowHandle);
1059 WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
1061 HIViewSetVisible (WholeWindow, true);
1062 HIViewSetVisible (ClientWindow, true);
1063 hwnd.visible = true;
1064 if (!(Control.FromHandle(hwnd.Handle) is Form)) {
1065 SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
1069 if (StyleSet (cp.Style, WindowStyles.WS_MINIMIZE)) {
1070 SetWindowState(hwnd.Handle, FormWindowState.Minimized);
1071 } else if (StyleSet (cp.Style, WindowStyles.WS_MAXIMIZE)) {
1072 SetWindowState(hwnd.Handle, FormWindowState.Maximized);
1078 internal override IntPtr CreateWindow(IntPtr Parent, int X, int Y, int Width, int Height) {
1079 CreateParams create_params = new CreateParams();
1081 create_params.Caption = "";
1082 create_params.X = X;
1083 create_params.Y = Y;
1084 create_params.Width = Width;
1085 create_params.Height = Height;
1087 create_params.ClassName=XplatUI.GetDefaultClassName (GetType ());
1088 create_params.ClassStyle = 0;
1089 create_params.ExStyle=0;
1090 create_params.Parent=IntPtr.Zero;
1091 create_params.Param=0;
1093 return CreateWindow(create_params);
1096 internal override Bitmap DefineStdCursorBitmap (StdCursor id) {
1097 return Carbon.Cursor.DefineStdCursorBitmap (id);
1100 internal override IntPtr DefineCursor (Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
1101 return Carbon.Cursor.DefineCursor (bitmap, mask, cursor_pixel, mask_pixel, xHotSpot, yHotSpot);
1104 internal override IntPtr DefineStdCursor (StdCursor id) {
1105 return Carbon.Cursor.DefineStdCursor (id);
1108 internal override IntPtr DefWndProc(ref Message msg) {
1109 Hwnd hwnd = Hwnd.ObjectFromHandle (msg.HWnd);
1110 switch ((Msg)msg.Msg) {
1111 case Msg.WM_IME_COMPOSITION:
1112 string s = KeyboardHandler.ComposedString;
1113 foreach (char c in s)
1114 SendMessage (msg.HWnd, Msg.WM_IME_CHAR, (IntPtr) c, msg.LParam);
1116 case Msg.WM_IME_CHAR:
1117 // On Windows API it sends two WM_CHAR messages for each byte, but
1118 // I wonder if it is worthy to emulate it (also no idea how to
1119 // reconstruct those bytes into chars).
1120 SendMessage (msg.HWnd, Msg.WM_CHAR, msg.WParam, msg.LParam);
1123 if (WindowMapping [hwnd.Handle] != null)
1128 case Msg.WM_PAINT: {
1129 hwnd.expose_pending = false;
1132 case Msg.WM_NCPAINT: {
1133 hwnd.nc_expose_pending = false;
1136 case Msg.WM_NCCALCSIZE: {
1137 if (msg.WParam == (IntPtr)1) {
1138 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
1139 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (msg.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
1141 // Add all the stuff X is supposed to draw.
1142 Control ctrl = Control.FromHandle (hwnd.Handle);
1144 Hwnd.Borders rect = Hwnd.GetBorders (ctrl.GetCreateParams (), null);
1146 ncp.rgrc1.top += rect.top;
1147 ncp.rgrc1.bottom -= rect.bottom;
1148 ncp.rgrc1.left += rect.left;
1149 ncp.rgrc1.right -= rect.right;
1151 Marshal.StructureToPtr (ncp, msg.LParam, true);
1156 case Msg.WM_SETCURSOR: {
1157 // Pass to parent window first
1158 while ((hwnd.parent != null) && (msg.Result == IntPtr.Zero)) {
1160 msg.Result = NativeWindow.WndProc(hwnd.Handle, Msg.WM_SETCURSOR, msg.HWnd, msg.LParam);
1163 if (msg.Result == IntPtr.Zero) {
1166 switch((HitTest)(msg.LParam.ToInt32() & 0xffff)) {
1167 case HitTest.HTBOTTOM: handle = Cursors.SizeNS.handle; break;
1168 case HitTest.HTBORDER: handle = Cursors.SizeNS.handle; break;
1169 case HitTest.HTBOTTOMLEFT: handle = Cursors.SizeNESW.handle; break;
1170 case HitTest.HTBOTTOMRIGHT: handle = Cursors.SizeNWSE.handle; break;
1171 case HitTest.HTERROR: if ((msg.LParam.ToInt32() >> 16) == (int)Msg.WM_LBUTTONDOWN) {
1172 //FIXME: AudibleAlert();
1174 handle = Cursors.Default.handle;
1177 case HitTest.HTHELP: handle = Cursors.Help.handle; break;
1178 case HitTest.HTLEFT: handle = Cursors.SizeWE.handle; break;
1179 case HitTest.HTRIGHT: handle = Cursors.SizeWE.handle; break;
1180 case HitTest.HTTOP: handle = Cursors.SizeNS.handle; break;
1181 case HitTest.HTTOPLEFT: handle = Cursors.SizeNWSE.handle; break;
1182 case HitTest.HTTOPRIGHT: handle = Cursors.SizeNESW.handle; break;
1185 case HitTest.HTGROWBOX:
1186 case HitTest.HTSIZE:
1187 case HitTest.HTZOOM:
1188 case HitTest.HTVSCROLL:
1189 case HitTest.HTSYSMENU:
1190 case HitTest.HTREDUCE:
1191 case HitTest.HTNOWHERE:
1192 case HitTest.HTMAXBUTTON:
1193 case HitTest.HTMINBUTTON:
1194 case HitTest.HTMENU:
1195 case HitTest.HSCROLL:
1196 case HitTest.HTBOTTOM:
1197 case HitTest.HTCAPTION:
1198 case HitTest.HTCLIENT:
1199 case HitTest.HTCLOSE:
1201 default: handle = Cursors.Default.handle; break;
1203 SetCursor(msg.HWnd, handle);
1211 internal override void DestroyCaret (IntPtr hwnd) {
1212 if (Caret.Hwnd == hwnd) {
1213 if (Caret.Visible == 1) {
1214 Caret.Timer.Stop ();
1217 Caret.Hwnd = IntPtr.Zero;
1224 internal override void DestroyCursor(IntPtr cursor) {
1225 throw new NotImplementedException ();
1228 internal override void DestroyWindow(IntPtr handle) {
1231 hwnd = Hwnd.ObjectFromHandle(handle);
1237 SendParentNotify (hwnd.Handle, Msg.WM_DESTROY, int.MaxValue, int.MaxValue);
1239 CleanupCachedWindows (hwnd);
1241 ArrayList windows = new ArrayList ();
1243 AccumulateDestroyedHandles (Control.ControlNativeWindow.ControlFromHandle(hwnd.Handle), windows);
1246 foreach (Hwnd h in windows) {
1247 SendMessage (h.Handle, Msg.WM_DESTROY, IntPtr.Zero, IntPtr.Zero);
1251 // TODO: This is crashing swf-messageboxes
1253 if (false && hwnd.whole_window != IntPtr.Zero)
1254 CFRelease (hwnd.whole_window);
1255 if (false && hwnd.client_window != IntPtr.Zero)
1256 CFRelease (hwnd.client_window);
1259 if (WindowMapping [hwnd.Handle] != null) {
1260 DisposeWindow ((IntPtr)(WindowMapping [hwnd.Handle]));
1261 WindowMapping.Remove (hwnd.Handle);
1265 internal override IntPtr DispatchMessage(ref MSG msg) {
1266 return NativeWindow.WndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1269 internal override void DoEvents() {
1270 MSG msg = new MSG ();
1273 while (PeekMessage (null, ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)) {
1274 TranslateMessage (ref msg);
1275 DispatchMessage (ref msg);
1277 in_doevents = false;
1281 internal override void EnableWindow(IntPtr handle, bool Enable) {
1282 //Like X11 we need not do anything here
1285 internal override void EndLoop(Thread thread) {
1288 internal void Exit () {
1289 GetMessageResult = false;
1292 internal override IntPtr GetActive() {
1293 return ActiveWindow;
1296 internal override Region GetClipRegion(IntPtr hwnd) {
1301 internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
1308 internal override void GetDisplaySize(out Size size) {
1309 Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
1310 size = new Size ((int)bounds.size.width, (int)bounds.size.height);
1313 internal override IntPtr GetParent(IntPtr handle) {
1316 hwnd = Hwnd.ObjectFromHandle(handle);
1317 if (hwnd != null && hwnd.Parent != null) {
1318 return hwnd.Parent.Handle;
1323 internal override IntPtr GetPreviousWindow(IntPtr handle) {
1324 return HIViewGetPreviousView(handle);
1327 internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
1328 Carbon.QDPoint pt = new Carbon.QDPoint ();
1329 GetGlobalMouse (ref pt);
1334 internal override IntPtr GetFocus() {
1339 internal override bool GetFontMetrics(Graphics g, Font font, out int ascent, out int descent) {
1340 FontFamily ff = font.FontFamily;
1341 ascent = ff.GetCellAscent (font.Style);
1342 descent = ff.GetCellDescent (font.Style);
1346 internal override Point GetMenuOrigin(IntPtr handle) {
1349 hwnd = Hwnd.ObjectFromHandle(handle);
1352 return hwnd.MenuOrigin;
1357 internal override bool GetMessage(object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
1358 IntPtr evtRef = IntPtr.Zero;
1359 IntPtr target = GetEventDispatcherTarget();
1360 CheckTimers (DateTime.UtcNow);
1361 ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
1362 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1363 SendEventToEventTarget (evtRef, target);
1364 ReleaseEvent (evtRef);
1371 if (MessageQueue.Count <= 0) {
1373 Idle (this, EventArgs.Empty);
1374 else if (TimerList.Count == 0) {
1375 ReceiveNextEvent (0, IntPtr.Zero, 0.15, true, ref evtRef);
1376 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1377 SendEventToEventTarget (evtRef, target);
1378 ReleaseEvent (evtRef);
1381 ReceiveNextEvent (0, IntPtr.Zero, NextTimeout (), true, ref evtRef);
1382 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1383 SendEventToEventTarget (evtRef, target);
1384 ReleaseEvent (evtRef);
1387 msg.hwnd = IntPtr.Zero;
1388 msg.message = Msg.WM_ENTERIDLE;
1389 return GetMessageResult;
1391 queueobj = MessageQueue.Dequeue ();
1393 if (queueobj is GCHandle) {
1394 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
1397 msg = (MSG)queueobj;
1399 return GetMessageResult;
1403 internal override bool GetText(IntPtr handle, out string text) {
1404 throw new NotImplementedException ();
1407 internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
1410 hwnd = Hwnd.ObjectFromHandle(handle);
1416 height = hwnd.height;
1418 PerformNCCalc(hwnd);
1420 client_width = hwnd.ClientRect.Width;
1421 client_height = hwnd.ClientRect.Height;
1426 // Should we throw an exception or fail silently?
1427 // throw new ArgumentException("Called with an invalid window handle", "handle");
1437 internal override FormWindowState GetWindowState(IntPtr hwnd) {
1438 IntPtr window = HIViewGetWindow (hwnd);
1440 if (IsWindowCollapsed (window))
1441 return FormWindowState.Minimized;
1442 if (IsWindowInStandardState (window, IntPtr.Zero, IntPtr.Zero))
1443 return FormWindowState.Maximized;
1445 return FormWindowState.Normal;
1448 internal override void GrabInfo(out IntPtr handle, out bool GrabConfined, out Rectangle GrabArea) {
1450 GrabConfined = Grab.Confined;
1451 GrabArea = Grab.Area;
1454 internal override void GrabWindow(IntPtr handle, IntPtr confine_to_handle) {
1456 Grab.Confined = confine_to_handle != IntPtr.Zero;
1457 /* FIXME: Set the Grab.Area */
1460 internal override void UngrabWindow(IntPtr hwnd) {
1461 bool was_grabbed = Grab.Hwnd != IntPtr.Zero;
1463 Grab.Hwnd = IntPtr.Zero;
1464 Grab.Confined = false;
1467 // lparam should be the handle to the window gaining the mouse capture,
1468 // but we dont have that information like X11.
1469 // Also only generate WM_CAPTURECHANGED if the window actually was grabbed.
1470 SendMessage (hwnd, Msg.WM_CAPTURECHANGED, IntPtr.Zero, IntPtr.Zero);
1474 internal override void HandleException(Exception e) {
1475 StackTrace st = new StackTrace(e);
1476 Console.WriteLine("Exception '{0}'", e.Message+st.ToString());
1477 Console.WriteLine("{0}{1}", e.Message, st.ToString());
1480 internal override void Invalidate (IntPtr handle, Rectangle rc, bool clear) {
1483 hwnd = Hwnd.ObjectFromHandle(handle);
1486 AddExpose (hwnd, true, hwnd.X, hwnd.Y, hwnd.Width, hwnd.Height);
1488 AddExpose (hwnd, true, rc.X, rc.Y, rc.Width, rc.Height);
1492 internal override void InvalidateNC (IntPtr handle)
1496 hwnd = Hwnd.ObjectFromHandle(handle);
1498 AddExpose (hwnd, false, 0, 0, hwnd.Width, hwnd.Height);
1501 internal override bool IsEnabled(IntPtr handle) {
1502 return Hwnd.ObjectFromHandle(handle).Enabled;
1505 internal override bool IsVisible(IntPtr handle) {
1506 return Hwnd.ObjectFromHandle(handle).visible;
1509 internal override void KillTimer(Timer timer) {
1511 TimerList.Remove(timer);
1516 internal override void OverrideCursor(IntPtr cursor) {
1519 internal override PaintEventArgs PaintEventStart(ref Message msg, IntPtr handle, bool client) {
1520 PaintEventArgs paint_event;
1524 hwnd = Hwnd.ObjectFromHandle(msg.HWnd);
1525 if (msg.HWnd == handle) {
1528 paint_hwnd = Hwnd.ObjectFromHandle (handle);
1531 if (Caret.Visible == 1) {
1532 Caret.Paused = true;
1539 dc = Graphics.FromHwnd (paint_hwnd.client_window);
1541 Region clip_region = new Region ();
1542 clip_region.MakeEmpty();
1544 foreach (Rectangle r in hwnd.ClipRectangles) {
1545 /* Expand the region slightly.
1548 Rectangle r2 = Rectangle.FromLTRB (r.Left, r.Top, r.Right, r.Bottom + 1);
1549 clip_region.Union (r2);
1552 if (hwnd.UserClip != null) {
1553 clip_region.Intersect(hwnd.UserClip);
1556 // FIXME: Clip region is hosed
1557 dc.Clip = clip_region;
1558 paint_event = new PaintEventArgs(dc, hwnd.Invalid);
1559 hwnd.expose_pending = false;
1560 hwnd.ClearInvalidArea();
1562 hwnd.drawing_stack.Push (paint_event);
1563 hwnd.drawing_stack.Push (dc);
1565 dc = Graphics.FromHwnd (paint_hwnd.whole_window);
1567 if (!hwnd.nc_invalid.IsEmpty) {
1568 // FIXME: Clip region is hosed
1569 dc.SetClip (hwnd.nc_invalid);
1570 paint_event = new PaintEventArgs(dc, hwnd.nc_invalid);
1572 paint_event = new PaintEventArgs(dc, new Rectangle(0, 0, hwnd.width, hwnd.height));
1574 hwnd.nc_expose_pending = false;
1575 hwnd.ClearNcInvalidArea ();
1577 hwnd.drawing_stack.Push (paint_event);
1578 hwnd.drawing_stack.Push (dc);
1584 internal override void PaintEventEnd(ref Message msg, IntPtr handle, bool client) {
1587 hwnd = Hwnd.ObjectFromHandle(handle);
1589 // FIXME: Pop is causing invalid stack ops sometimes; race condition?
1591 Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
1595 PaintEventArgs pe = (PaintEventArgs)hwnd.drawing_stack.Pop();
1596 pe.SetGraphics (null);
1600 if (Caret.Visible == 1) {
1602 Caret.Paused = false;
1606 internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
1607 IntPtr evtRef = IntPtr.Zero;
1608 IntPtr target = GetEventDispatcherTarget();
1609 CheckTimers (DateTime.UtcNow);
1610 ReceiveNextEvent (0, IntPtr.Zero, 0, true, ref evtRef);
1611 if (evtRef != IntPtr.Zero && target != IntPtr.Zero) {
1612 SendEventToEventTarget (evtRef, target);
1613 ReleaseEvent (evtRef);
1617 if (MessageQueue.Count <= 0) {
1621 if (flags == (uint)PeekMessageFlags.PM_REMOVE)
1622 queueobj = MessageQueue.Dequeue ();
1624 queueobj = MessageQueue.Peek ();
1626 if (queueobj is GCHandle) {
1627 XplatUIDriverSupport.ExecuteClientMessage((GCHandle)queueobj);
1630 msg = (MSG)queueobj;
1636 internal override bool PostMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
1637 MSG msg = new MSG();
1639 msg.message = message;
1640 msg.wParam = wParam;
1641 msg.lParam = lParam;
1642 EnqueueMessage (msg);
1646 internal override void PostQuitMessage(int exitCode) {
1647 PostMessage (FosterParent, Msg.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
1650 internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave) {
1653 internal override void RequestNCRecalc(IntPtr handle) {
1656 hwnd = Hwnd.ObjectFromHandle(handle);
1662 PerformNCCalc(hwnd);
1663 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1664 InvalidateNC(handle);
1668 internal override void ResetMouseHover(IntPtr handle) {
1669 throw new NotImplementedException();
1672 internal override void ScreenToClient(IntPtr handle, ref int x, ref int y) {
1673 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1675 Point point = ConvertScreenPointToClient (hwnd.ClientWindow, new Point (x, y));
1681 internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
1682 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1684 Point point = ConvertScreenPointToClient (hwnd.WholeWindow, new Point (x, y));
1690 internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool clear) {
1692 * This used to use a HIViewScrollRect but this causes issues with the fact that we dont coalesce
1693 * updates properly with our short-circuiting of the window manager. For now we'll do a less
1694 * efficient invalidation of the entire handle which appears to fix the problem
1697 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1698 Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
1702 internal override void ScrollWindow(IntPtr handle, int XAmount, int YAmount, bool clear) {
1703 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1704 Invalidate (handle, new Rectangle (0, 0, hwnd.Width, hwnd.Height), false);
1708 internal override void SendAsyncMethod (AsyncMethodData method) {
1711 MessageQueue.Enqueue (GCHandle.Alloc (method));
1716 internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
1717 return NativeWindow.WndProc(hwnd, message, wParam, lParam);
1720 internal override int SendInput(IntPtr hwnd, Queue keys) {
1725 internal override void SetCaretPos (IntPtr hwnd, int x, int y) {
1726 if (hwnd != IntPtr.Zero && hwnd == Caret.Hwnd) {
1729 ClientToScreen (hwnd, ref x, ref y);
1730 SizeWindow (new Rectangle (x, y, Caret.Width, Caret.Height), CaretWindow);
1731 Caret.Timer.Stop ();
1733 if (Caret.Visible == 1) {
1735 Caret.Timer.Start ();
1740 internal override void SetClipRegion(IntPtr hwnd, Region region) {
1741 throw new NotImplementedException();
1744 internal override void SetCursor(IntPtr window, IntPtr cursor) {
1745 Hwnd hwnd = Hwnd.ObjectFromHandle (window);
1747 hwnd.Cursor = cursor;
1750 internal override void SetCursorPos(IntPtr handle, int x, int y) {
1751 CGDisplayMoveCursorToPoint (CGMainDisplayID (), new Carbon.CGPoint (x, y));
1754 internal override void SetFocus(IntPtr handle) {
1755 if (FocusWindow != IntPtr.Zero) {
1756 PostMessage(FocusWindow, Msg.WM_KILLFOCUS, handle, IntPtr.Zero);
1758 PostMessage(handle, Msg.WM_SETFOCUS, FocusWindow, IntPtr.Zero);
1759 FocusWindow = handle;
1762 internal override void SetIcon(IntPtr handle, Icon icon) {
1763 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1765 // FIXME: we need to map the icon for active window switches
1766 if (WindowMapping [hwnd.Handle] != null) {
1768 RestoreApplicationDockTileImage ();
1775 bitmap = new Bitmap (128, 128);
1776 using (Graphics g = Graphics.FromImage (bitmap)) {
1777 g.DrawImage (icon.ToBitmap (), 0, 0, 128, 128);
1780 size = bitmap.Width * bitmap.Height;
1781 data = new IntPtr[size];
1783 for (int y = 0; y < bitmap.Height; y++) {
1784 for (int x = 0; x < bitmap.Width; x++) {
1785 int pixel = bitmap.GetPixel (x, y).ToArgb ();
1786 if (BitConverter.IsLittleEndian) {
1787 byte a = (byte) ((pixel >> 24) & 0xFF);
1788 byte r = (byte) ((pixel >> 16) & 0xFF);
1789 byte g = (byte) ((pixel >> 8) & 0xFF);
1790 byte b = (byte) (pixel & 0xFF);
1791 data[index++] = (IntPtr)(a + (r << 8) + (g << 16) + (b << 24));
1793 data[index++] = (IntPtr)pixel;
1798 IntPtr provider = CGDataProviderCreateWithData (IntPtr.Zero, data, size*4, IntPtr.Zero);
1799 IntPtr image = CGImageCreate (128, 128, 8, 32, 4*128, CGColorSpaceCreateDeviceRGB (), 4, provider, IntPtr.Zero, 0, 0);
1800 SetApplicationDockTileImage (image);
1806 internal override void SetModal(IntPtr handle, bool Modal) {
1807 IntPtr hWnd = HIViewGetWindow (Hwnd.ObjectFromHandle (handle).WholeWindow);
1809 BeginAppModalStateForWindow (hWnd);
1811 EndAppModalStateForWindow (hWnd);
1815 internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
1816 IntPtr ParentHandle = IntPtr.Zero;
1817 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1819 hwnd.Parent = Hwnd.ObjectFromHandle (parent);
1820 if (HIViewGetSuperview (hwnd.whole_window) != IntPtr.Zero) {
1821 HIViewRemoveFromSuperview (hwnd.whole_window);
1823 if (hwnd.parent == null)
1824 HIViewFindByID (HIViewGetRoot (FosterParent), new Carbon.HIViewID (Carbon.EventHandler.kEventClassWindow, 1), ref ParentHandle);
1825 HIViewAddSubview (hwnd.parent == null ? ParentHandle : hwnd.Parent.client_window, hwnd.whole_window);
1826 HIViewPlaceInSuperviewAt (hwnd.whole_window, hwnd.X, hwnd.Y);
1827 HIViewAddSubview (hwnd.whole_window, hwnd.client_window);
1828 HIViewPlaceInSuperviewAt (hwnd.client_window, hwnd.ClientRect.X, hwnd.ClientRect.Y);
1833 internal override void SetTimer (Timer timer) {
1835 TimerList.Add (timer);
1839 internal override bool SetTopmost(IntPtr hWnd, bool Enabled) {
1840 HIViewSetZOrder (hWnd, 1, IntPtr.Zero);
1844 internal override bool SetOwner(IntPtr hWnd, IntPtr hWndOwner) {
1845 // TODO: Set window owner.
1849 internal override bool SetVisible(IntPtr handle, bool visible, bool activate) {
1850 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1851 object window = WindowMapping [hwnd.Handle];
1854 ShowWindow ((IntPtr)window);
1856 HideWindow ((IntPtr)window);
1859 SendMessage(handle, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1861 HIViewSetVisible (hwnd.whole_window, visible);
1862 HIViewSetVisible (hwnd.client_window, visible);
1864 hwnd.visible = visible;
1869 internal override void SetAllowDrop (IntPtr handle, bool value) {
1870 // Like X11 we allow drop on al windows and filter in our handler
1873 internal override DragDropEffects StartDrag (IntPtr handle, object data, DragDropEffects allowed_effects) {
1874 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1877 throw new ArgumentException ("Attempt to begin drag from invalid window handle (" + handle.ToInt32 () + ").");
1879 return Dnd.StartDrag (hwnd.client_window, data, allowed_effects);
1882 internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) {
1883 Form form = Control.FromHandle (handle) as Form;
1884 if (form != null && form.window_manager == null && (border_style == FormBorderStyle.FixedToolWindow ||
1885 border_style == FormBorderStyle.SizableToolWindow)) {
1886 form.window_manager = new ToolWindowManager (form);
1889 RequestNCRecalc(handle);
1892 internal override void SetMenu(IntPtr handle, Menu menu) {
1895 hwnd = Hwnd.ObjectFromHandle(handle);
1898 RequestNCRecalc(handle);
1901 internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
1904 internal override void SetWindowPos(IntPtr handle, int x, int y, int width, int height) {
1905 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1911 // Win32 automatically changes negative width/height to 0.
1917 // X requires a sanity check for width & height; otherwise it dies
1918 if (hwnd.zero_sized && width > 0 && height > 0) {
1920 HIViewSetVisible(hwnd.WholeWindow, true);
1922 hwnd.zero_sized = false;
1925 if ((width < 1) || (height < 1)) {
1926 hwnd.zero_sized = true;
1927 HIViewSetVisible(hwnd.WholeWindow, false);
1930 // Save a server roundtrip (and prevent a feedback loop)
1931 if ((hwnd.x == x) && (hwnd.y == y) && (hwnd.width == width) && (hwnd.height == height)) {
1935 if (!hwnd.zero_sized) {
1939 hwnd.height = height;
1940 SendMessage(hwnd.client_window, Msg.WM_WINDOWPOSCHANGED, IntPtr.Zero, IntPtr.Zero);
1942 Control ctrl = Control.FromHandle (handle);
1943 CreateParams cp = ctrl.GetCreateParams ();
1944 Size TranslatedSize = TranslateWindowSizeToQuartzWindowSize (cp, new Size (width, height));
1945 Carbon.Rect rect = new Carbon.Rect ();
1947 if (WindowMapping [hwnd.Handle] != null) {
1948 if (StyleSet (cp.Style, WindowStyles.WS_POPUP)) {
1949 SetRect (ref rect, (short)x, (short)y, (short)(x+TranslatedSize.Width), (short)(y+TranslatedSize.Height));
1951 SetRect (ref rect, (short)x, (short)(y+MenuBarHeight), (short)(x+TranslatedSize.Width), (short)(y+MenuBarHeight+TranslatedSize.Height));
1953 SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
1954 Carbon.HIRect frame_rect = new Carbon.HIRect (0, 0, TranslatedSize.Width, TranslatedSize.Height);
1955 HIViewSetFrame (hwnd.whole_window, ref frame_rect);
1956 SetCaretPos (Caret.Hwnd, Caret.X, Caret.Y);
1958 Carbon.HIRect frame_rect = new Carbon.HIRect (x, y, TranslatedSize.Width, TranslatedSize.Height);
1959 HIViewSetFrame (hwnd.whole_window, ref frame_rect);
1961 PerformNCCalc(hwnd);
1967 hwnd.height = height;
1970 internal override void SetWindowState(IntPtr handle, FormWindowState state) {
1971 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
1972 IntPtr window = HIViewGetWindow (handle);
1975 case FormWindowState.Minimized: {
1976 CollapseWindow (window, true);
1979 case FormWindowState.Normal: {
1980 ZoomWindow (window, 7, false);
1983 case FormWindowState.Maximized: {
1984 Form form = Control.FromHandle (hwnd.Handle) as Form;
1985 if (form != null && form.FormBorderStyle == FormBorderStyle.None) {
1986 Carbon.Rect rect = new Carbon.Rect ();
1987 Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
1988 SetRect (ref rect, (short)0, (short)0, (short)bounds.size.width, (short)bounds.size.height);
1989 SetWindowBounds ((IntPtr) WindowMapping [hwnd.Handle], 33, ref rect);
1990 HIViewSetFrame (hwnd.whole_window, ref bounds);
1992 ZoomWindow (window, 8, false);
1999 internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
2000 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
2001 SetHwndStyles(hwnd, cp);
2003 if (WindowMapping [hwnd.Handle] != null) {
2004 Carbon.WindowAttributes attributes = Carbon.WindowAttributes.kWindowCompositingAttribute | Carbon.WindowAttributes.kWindowStandardHandlerAttribute;
2005 if ((cp.Style & ((int)WindowStyles.WS_MINIMIZEBOX)) != 0) {
2006 attributes |= Carbon.WindowAttributes.kWindowCollapseBoxAttribute;
2008 if ((cp.Style & ((int)WindowStyles.WS_MAXIMIZEBOX)) != 0) {
2009 attributes |= Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowHorizontalZoomAttribute | Carbon.WindowAttributes.kWindowVerticalZoomAttribute;
2011 if ((cp.Style & ((int)WindowStyles.WS_SYSMENU)) != 0) {
2012 attributes |= Carbon.WindowAttributes.kWindowCloseBoxAttribute;
2014 if ((cp.ExStyle & ((int)WindowExStyles.WS_EX_TOOLWINDOW)) != 0) {
2015 attributes = Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute;
2017 attributes |= Carbon.WindowAttributes.kWindowLiveResizeAttribute;
2019 Carbon.WindowAttributes outAttributes = Carbon.WindowAttributes.kWindowNoAttributes;
2020 GetWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], ref outAttributes);
2021 ChangeWindowAttributes ((IntPtr)WindowMapping [hwnd.Handle], attributes, outAttributes);
2025 internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
2028 internal override double GetWindowTransparency(IntPtr handle)
2033 internal override TransparencySupport SupportsTransparency() {
2034 return TransparencySupport.None;
2037 internal override bool SetZOrder(IntPtr handle, IntPtr after_handle, bool Top, bool Bottom) {
2038 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
2041 HIViewSetZOrder (hwnd.whole_window, 2, IntPtr.Zero);
2043 } else if (!Bottom) {
2044 Hwnd after_hwnd = Hwnd.ObjectFromHandle (after_handle);
2045 HIViewSetZOrder (hwnd.whole_window, 2, (after_handle == IntPtr.Zero ? IntPtr.Zero : after_hwnd.whole_window));
2047 HIViewSetZOrder (hwnd.whole_window, 1, IntPtr.Zero);
2053 internal override void ShowCursor(bool show) {
2055 CGDisplayShowCursor (CGMainDisplayID ());
2057 CGDisplayHideCursor (CGMainDisplayID ());
2060 internal override object StartLoop(Thread thread) {
2061 return new object ();
2065 internal override bool SystrayAdd(IntPtr hwnd, string tip, Icon icon, out ToolTip tt) {
2066 throw new NotImplementedException();
2070 internal override bool SystrayChange(IntPtr hwnd, string tip, Icon icon, ref ToolTip tt) {
2071 throw new NotImplementedException();
2075 internal override void SystrayRemove(IntPtr hwnd, ref ToolTip tt) {
2076 throw new NotImplementedException();
2080 internal override void SystrayBalloon(IntPtr hwnd, int timeout, string title, string text, ToolTipIcon icon)
2082 throw new NotImplementedException ();
2085 internal override bool Text(IntPtr handle, string text) {
2086 Hwnd hwnd = Hwnd.ObjectFromHandle (handle);
2087 if (WindowMapping [hwnd.Handle] != null) {
2088 SetWindowTitleWithCFString ((IntPtr)(WindowMapping [hwnd.Handle]), __CFStringMakeConstantString (text));
2090 SetControlTitleWithCFString (hwnd.whole_window, __CFStringMakeConstantString (text));
2091 SetControlTitleWithCFString (hwnd.client_window, __CFStringMakeConstantString (text));
2095 internal override void UpdateWindow(IntPtr handle) {
2098 hwnd = Hwnd.ObjectFromHandle(handle);
2100 if (!hwnd.visible || !HIViewIsVisible (handle)) {
2104 SendMessage(handle, Msg.WM_PAINT, IntPtr.Zero, IntPtr.Zero);
2107 internal override bool TranslateMessage(ref MSG msg) {
2108 return Carbon.EventHandler.TranslateMessage (ref msg);
2111 #region Reversible regions
2113 * Quartz has no concept of XOR drawing due to its compositing nature
2114 * We fake this by mapping a overlay window on the first draw and mapping it on the second.
2115 * This has some issues with it because its POSSIBLE for ControlPaint.DrawReversible* to actually
2116 * reverse two regions at once. We dont do this in MWF, but this behaviour woudn't work.
2117 * We could in theory cache the Rectangle/Color combination to handle this behaviour.
2119 * PROBLEMS: This has some flicker / banding
2121 internal void SizeWindow (Rectangle rect, IntPtr window) {
2122 Carbon.Rect qrect = new Carbon.Rect ();
2124 SetRect (ref qrect, (short)rect.X, (short)rect.Y, (short)(rect.X+rect.Width), (short)(rect.Y+rect.Height));
2126 SetWindowBounds (window, 33, ref qrect);
2129 internal override void DrawReversibleLine(Point start, Point end, Color backColor) {
2130 // throw new NotImplementedException();
2133 internal override void FillReversibleRectangle (Rectangle rectangle, Color backColor) {
2134 // throw new NotImplementedException();
2137 internal override void DrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
2138 // throw new NotImplementedException();
2141 internal override void DrawReversibleRectangle(IntPtr handle, Rectangle rect, int line_width) {
2142 Rectangle size_rect = rect;
2146 if (ReverseWindowMapped) {
2147 HideWindow (ReverseWindow);
2148 ReverseWindowMapped = false;
2150 ClientToScreen(handle, ref new_x, ref new_y);
2152 size_rect.X += new_x;
2153 size_rect.Y += new_y;
2155 SizeWindow (size_rect, ReverseWindow);
2156 ShowWindow (ReverseWindow);
2163 Graphics g = Graphics.FromHwnd (HIViewGetRoot (ReverseWindow));
2165 for (int i = 0; i < line_width; i++) {
2166 g.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (Color.Black), rect);
2176 ReverseWindowMapped = true;
2181 internal override SizeF GetAutoScaleSize(Font font) {
2184 string magic_string = "The quick brown fox jumped over the lazy dog.";
2185 double magic_number = 44.549996948242189;
2187 g = Graphics.FromImage (new Bitmap (1, 1));
2189 width = (float) (g.MeasureString (magic_string, font).Width / magic_number);
2190 return new SizeF(width, font.Height);
2193 internal override Point MousePosition {
2195 return mouse_position;
2200 #region System information
2201 internal override int KeyboardSpeed { get{ throw new NotImplementedException(); } }
2202 internal override int KeyboardDelay { get{ throw new NotImplementedException(); } }
2204 internal override int CaptionHeight {
2210 internal override Size CursorSize { get{ throw new NotImplementedException(); } }
2211 internal override bool DragFullWindows { get{ throw new NotImplementedException(); } }
2212 internal override Size DragSize {
2214 return new Size(4, 4);
2218 internal override Size FrameBorderSize {
2220 return new Size (2, 2);
2224 internal override Size IconSize { get{ throw new NotImplementedException(); } }
2225 internal override Size MaxWindowTrackSize { get{ throw new NotImplementedException(); } }
2226 internal override bool MenuAccessKeysUnderlined {
2231 internal override Size MinimizedWindowSpacingSize { get{ throw new NotImplementedException(); } }
2233 internal override Size MinimumWindowSize {
2235 return new Size(110, 22);
2239 internal override Keys ModifierKeys {
2241 return KeyboardHandler.ModifierKeys;
2244 internal override Size SmallIconSize { get{ throw new NotImplementedException(); } }
2245 internal override int MouseButtonCount { get{ throw new NotImplementedException(); } }
2246 internal override bool MouseButtonsSwapped { get{ throw new NotImplementedException(); } }
2247 internal override bool MouseWheelPresent { get{ throw new NotImplementedException(); } }
2249 internal override MouseButtons MouseButtons {
2255 internal override Rectangle VirtualScreen {
2261 internal override Rectangle WorkingArea {
2263 Carbon.HIRect bounds = CGDisplayBounds (CGMainDisplayID ());
2264 return new Rectangle ((int)bounds.origin.x, (int)bounds.origin.y, (int)bounds.size.width, (int)bounds.size.height);
2269 internal override Screen[] AllScreens {
2275 internal override bool ThemesEnabled {
2277 return XplatUICarbon.themes_enabled;
2284 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2285 extern static int HIViewConvertPoint (ref Carbon.CGPoint point, IntPtr pView, IntPtr cView);
2286 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2287 extern static int HIViewChangeFeatures (IntPtr aView, ulong bitsin, ulong bitsout);
2288 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2289 extern static int HIViewFindByID (IntPtr rootWnd, Carbon.HIViewID id, ref IntPtr outPtr);
2290 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2291 extern static int HIGrowBoxViewSetTransparent (IntPtr GrowBox, bool transparency);
2292 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2293 extern static IntPtr HIViewGetRoot (IntPtr hWnd);
2294 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2295 extern static int HIObjectCreate (IntPtr cfStr, uint what, ref IntPtr hwnd);
2296 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2297 extern static int HIObjectRegisterSubclass (IntPtr classid, IntPtr superclassid, uint options, Carbon.EventDelegate upp, uint count, Carbon.EventTypeSpec [] list, IntPtr state, ref IntPtr cls);
2298 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2299 extern static int HIViewPlaceInSuperviewAt (IntPtr view, float x, float y);
2300 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2301 extern static int HIViewAddSubview (IntPtr parentHnd, IntPtr childHnd);
2302 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2303 extern static IntPtr HIViewGetPreviousView (IntPtr aView);
2304 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2305 extern static IntPtr HIViewGetSuperview (IntPtr aView);
2306 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2307 extern static int HIViewRemoveFromSuperview (IntPtr aView);
2308 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2309 extern static int HIViewSetVisible (IntPtr vHnd, bool visible);
2310 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2311 extern static bool HIViewIsVisible (IntPtr vHnd);
2312 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2313 extern static int HIViewGetBounds (IntPtr vHnd, ref Carbon.HIRect r);
2314 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2315 extern static int HIViewScrollRect (IntPtr vHnd, ref Carbon.HIRect rect, float x, float y);
2316 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2317 extern static int HIViewSetZOrder (IntPtr hWnd, int cmd, IntPtr oHnd);
2318 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2319 extern static int HIViewNewTrackingArea (IntPtr inView, IntPtr inShape, UInt64 inID, ref IntPtr outRef);
2320 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2321 extern static IntPtr HIViewGetWindow (IntPtr aView);
2322 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2323 extern static int HIViewSetFrame (IntPtr view_handle, ref Carbon.HIRect bounds);
2324 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2325 internal extern static int HIViewSetNeedsDisplayInRect (IntPtr view_handle, ref Carbon.HIRect rect, bool needs_display);
2327 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2328 extern static void SetRect (ref Carbon.Rect r, short left, short top, short right, short bottom);
2329 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2330 static extern int ActivateWindow (IntPtr windowHnd, bool inActivate);
2331 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2332 static extern bool IsWindowActive (IntPtr windowHnd);
2333 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2334 static extern int SetAutomaticControlDragTrackingEnabledForWindow (IntPtr window, bool enabled);
2336 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2337 extern static IntPtr GetEventDispatcherTarget ();
2338 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2339 extern static int SendEventToEventTarget (IntPtr evt, IntPtr target);
2340 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2341 extern static int ReleaseEvent (IntPtr evt);
2342 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2343 extern static int ReceiveNextEvent (uint evtCount, IntPtr evtTypes, double timeout, bool processEvt, ref IntPtr evt);
2345 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2346 extern static bool IsWindowCollapsed (IntPtr hWnd);
2347 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2348 extern static bool IsWindowInStandardState (IntPtr hWnd, IntPtr a, IntPtr b);
2349 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2350 extern static void CollapseWindow (IntPtr hWnd, bool collapse);
2351 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2352 extern static void ZoomWindow (IntPtr hWnd, short partCode, bool front);
2353 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2354 extern static int GetWindowAttributes (IntPtr hWnd, ref Carbon.WindowAttributes outAttributes);
2355 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2356 extern static int ChangeWindowAttributes (IntPtr hWnd, Carbon.WindowAttributes inAttributes, Carbon.WindowAttributes outAttributes);
2357 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2358 internal extern static int GetGlobalMouse (ref Carbon.QDPoint outData);
2360 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2361 extern static int BeginAppModalStateForWindow (IntPtr window);
2362 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2363 extern static int EndAppModalStateForWindow (IntPtr window);
2364 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2365 extern static int CreateNewWindow (Carbon.WindowClass klass, Carbon.WindowAttributes attributes, ref Carbon.Rect r, ref IntPtr window);
2366 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2367 extern static int DisposeWindow (IntPtr wHnd);
2368 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2369 internal extern static int ShowWindow (IntPtr wHnd);
2370 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2371 internal extern static int HideWindow (IntPtr wHnd);
2372 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2373 internal extern static bool IsWindowVisible (IntPtr wHnd);
2374 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2375 extern static int SetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);
2376 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2377 extern static int GetWindowBounds (IntPtr wHnd, uint reg, ref Carbon.Rect rect);
2379 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2380 extern static int SetControlTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
2381 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2382 extern static int SetWindowTitleWithCFString (IntPtr hWnd, IntPtr titleCFStr);
2383 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2384 internal extern static IntPtr __CFStringMakeConstantString (string cString);
2386 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2387 internal extern static int CFRelease (IntPtr wHnd);
2388 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2389 extern static short GetMBarHeight ();
2391 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2392 extern static void AlertSoundPlay ();
2394 #region Cursor imports
2395 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2396 extern static Carbon.HIRect CGDisplayBounds (IntPtr displayID);
2397 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2398 extern static IntPtr CGMainDisplayID ();
2399 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2400 extern static void CGDisplayShowCursor (IntPtr display);
2401 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2402 extern static void CGDisplayHideCursor (IntPtr display);
2403 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2404 extern static void CGDisplayMoveCursorToPoint (IntPtr display, Carbon.CGPoint point);
2407 #region Process imports
2408 [DllImport ("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2409 extern static int GetCurrentProcess (ref Carbon.ProcessSerialNumber psn);
2410 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2411 extern static int TransformProcessType (ref Carbon.ProcessSerialNumber psn, uint type);
2412 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2413 extern static int SetFrontProcess (ref Carbon.ProcessSerialNumber psn);
2416 #region Dock tile imports
2417 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2418 extern static IntPtr CGColorSpaceCreateDeviceRGB();
2419 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2420 extern static IntPtr CGDataProviderCreateWithData (IntPtr info, IntPtr [] data, int size, IntPtr releasefunc);
2421 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2422 extern static IntPtr CGImageCreate (int width, int height, int bitsPerComponent, int bitsPerPixel, int bytesPerRow, IntPtr colorspace, uint bitmapInfo, IntPtr provider, IntPtr decode, int shouldInterpolate, int intent);
2423 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2424 extern static void SetApplicationDockTileImage(IntPtr imageRef);
2425 [DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
2426 extern static void RestoreApplicationDockTileImage();