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

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

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

			HIObjectRegisterSubclass (__CFStringMakeConstantString ("com.novell.mwfview"), __CFStringMakeConstantString ("com.apple.hiview"), 0, Carbon.EventHandler.EventHandlerDelegate, (uint)Carbon.EventHandler.HIObjectEvents.Length, Carbon.EventHandler.HIObjectEvents, IntPtr.Zero, ref Subclass);

			Carbon.EventHandler.InstallApplicationHandler ();

			CreateNewWindow (Carbon.WindowClass.kDocumentWindowClass, Carbon.WindowAttributes.kWindowStandardHandlerAttribute | Carbon.WindowAttributes.kWindowCloseBoxAttribute | Carbon.WindowAttributes.kWindowFullZoomAttribute | Carbon.WindowAttributes.kWindowCollapseBoxAttribute | Carbon.WindowAttributes.kWindowResizableAttribute | Carbon.WindowAttributes.kWindowCompositingAttribute, ref rect, ref FosterParent);
			
			CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref ReverseWindow);
			CreateNewWindow (Carbon.WindowClass.kOverlayWindowClass, Carbon.WindowAttributes.kWindowNoUpdatesAttribute | Carbon.WindowAttributes.kWindowNoActivatesAttribute, ref rect, ref CaretWindow);
			
			// Get some values about bar heights
			Carbon.Rect structRect = new Carbon.Rect ();
			Carbon.Rect contentRect = new Carbon.Rect ();
			GetWindowBounds (FosterParent, 32, ref structRect);
			GetWindowBounds (FosterParent, 33, ref contentRect);
			
			MenuBarHeight = GetMBarHeight ();
			
			// Focus
			FocusWindow = IntPtr.Zero;
			
			// Message loop
			GetMessageResult = true;
			
			ReverseWindowMapped = false;
		}
		internal 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 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;
		}
Example #8
0
		public bool ProcessEvent (IntPtr callref, IntPtr eventref, IntPtr handle, uint kind, ref MSG msg) {
			QDPoint qdpoint = new QDPoint ();
			CGPoint point = new CGPoint ();
			Rect window_bounds = new Rect ();
			IntPtr view_handle = IntPtr.Zero;
			IntPtr window_handle = IntPtr.Zero;
			bool client = true;
			ushort button = 0;
			Hwnd hwnd;

			GetEventParameter (eventref, kEventParamMouseLocation, typeQDPoint, IntPtr.Zero, (uint)Marshal.SizeOf (typeof (QDPoint)), IntPtr.Zero, ref qdpoint);
			GetEventParameter (eventref, kEventParamMouseButton, typeMouseButton, IntPtr.Zero, (uint)Marshal.SizeOf (typeof (ushort)), IntPtr.Zero, ref button);
			
			if (button == 1 && ((Driver.ModifierKeys & Keys.Control) != 0))
				button = 2;

			point.x = qdpoint.x;
			point.y = qdpoint.y;

			if (FindWindow (qdpoint, ref window_handle) == 5)
				return true;

			GetWindowBounds (handle, 33, ref window_bounds);
			HIViewFindByID (HIViewGetRoot (handle), new HIViewID (EventHandler.kEventClassWindow, 1), ref window_handle);

			point.x -= window_bounds.left;
			point.y -= window_bounds.top;

			HIViewGetSubviewHit (window_handle, ref point, true, ref view_handle);
			HIViewConvertPoint (ref point, window_handle, view_handle);

			hwnd = Hwnd.ObjectFromHandle (view_handle);

			if (hwnd != null)
				client = (hwnd.ClientWindow == view_handle ? true : false);

			if (XplatUICarbon.Grab.Hwnd != IntPtr.Zero) {
				hwnd = Hwnd.ObjectFromHandle (XplatUICarbon.Grab.Hwnd); 
				client = true;
			}
			if (hwnd == null)
				return true;
			
			if (client) {
				qdpoint.x = (short) point.x;
				qdpoint.y = (short) point.y;

				Driver.ScreenToClient (hwnd.Handle, ref qdpoint);
			} else {
				point.x = qdpoint.x;
				point.y = qdpoint.y;
			}

			msg.hwnd = hwnd.Handle;
			msg.lParam = (IntPtr) ((ushort) point.y << 16 | (ushort) point.x);

			switch (kind) {
				case kEventMouseDown:
					UpdateMouseState (button, true);
					msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE) + ((button - 1) * 3) + 1;
					msg.wParam = Driver.GetMousewParam (0);
					if (ClickPending.Pending && (((DateTime.Now.Ticks - ClickPending.Time) < DoubleClickInterval) && (msg.hwnd == ClickPending.Hwnd) && (msg.wParam == ClickPending.wParam) && (msg.lParam == ClickPending.lParam) && (msg.message == ClickPending.Message))) {
						msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE) + ((button - 1) * 3) + 3;
						ClickPending.Pending = false;
					} else {
						ClickPending.Pending = true;
						ClickPending.Hwnd = msg.hwnd;
						ClickPending.Message = msg.message;
						ClickPending.wParam = msg.wParam;
						ClickPending.lParam = msg.lParam;
						ClickPending.Time = DateTime.Now.Ticks;
					}
					break;
				case kEventMouseUp:
					UpdateMouseState (button, false);
					msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE) + ((button - 1) * 3) + 2;
					msg.wParam = Driver.GetMousewParam (0);
					break;
				case kEventMouseDragged:
				case kEventMouseMoved:
					if (XplatUICarbon.Grab.Hwnd == IntPtr.Zero) {
						IntPtr ht = IntPtr.Zero;
						if (client) {
							ht = (IntPtr) HitTest.HTCLIENT;
							NativeWindow.WndProc(msg.hwnd, Msg.WM_SETCURSOR, msg.hwnd, (IntPtr)HitTest.HTCLIENT);
						} else {
	                                                ht = (IntPtr) NativeWindow.WndProc (hwnd.client_window, Msg.WM_NCHITTEST, IntPtr.Zero, msg.lParam).ToInt32 ();
							NativeWindow.WndProc(hwnd.client_window, Msg.WM_SETCURSOR, msg.hwnd, ht);
						}
					}
					msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE);
					msg.wParam = Driver.GetMousewParam (0);
					break;
				case kEventMouseWheelMoved:
				case kEventMouseScroll:
					UInt16 axis = 0;
					Int32 delta = 0;

					GetEventParameter (eventref, kEventParamMouseWheelAxis, typeMouseWheelAxis, IntPtr.Zero, (uint)Marshal.SizeOf (typeof (UInt16)), IntPtr.Zero, ref axis);
					GetEventParameter (eventref, kEventParamMouseWheelDelta, typeLongInteger, IntPtr.Zero, (uint)Marshal.SizeOf (typeof (Int32)), IntPtr.Zero, ref delta);

					if (axis == kEventMouseWheelAxisY) {
						msg.hwnd = XplatUICarbon.FocusWindow;
						msg.message = Msg.WM_MOUSEWHEEL;
						msg.wParam = Driver.GetMousewParam (delta*40);
						return true;
					}
					break;
				default:
					return false;
			}
			Driver.mouse_position.X = (int) point.x;
			Driver.mouse_position.Y = (int) point.y;
			return true;
		}
Example #9
0
		internal static extern int GetWindowBounds (IntPtr handle, uint region, ref Rect bounds);