diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj
index f52bd3ed..ee17f232 100644
--- a/Source/OpenTK/OpenTK.csproj
+++ b/Source/OpenTK/OpenTK.csproj
@@ -816,6 +816,11 @@
+
+
+
+
+
diff --git a/Source/OpenTK/Platform/LegacyInputDriver.cs b/Source/OpenTK/Platform/LegacyInputDriver.cs
new file mode 100644
index 00000000..67461587
--- /dev/null
+++ b/Source/OpenTK/Platform/LegacyInputDriver.cs
@@ -0,0 +1,103 @@
+#region License
+//
+// LegacyInputDriver.cs
+//
+// Author:
+// Stefanos A.
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+#endregion
+
+using System;
+using System.Collections.Generic;
+using OpenTK.Input;
+
+namespace OpenTK.Platform
+{
+ // IInputDriver implementation to satisfy INativeWindow
+ // while reducing code duplication.
+ class LegacyInputDriver : IInputDriver
+ {
+ List dummy_keyboard_list = new List(1);
+ List dummy_mice_list = new List(1);
+
+ readonly LegacyJoystickDriver JoystickDriver = new LegacyJoystickDriver();
+
+ internal LegacyInputDriver()
+ {
+ dummy_mice_list.Add(new MouseDevice());
+ Mouse[0].Description = "Standard Mouse";
+ Mouse[0].NumberOfButtons = 3;
+ Mouse[0].NumberOfWheels = 1;
+
+ dummy_keyboard_list.Add(new KeyboardDevice());
+ Keyboard[0].Description = "Standard Keyboard";
+ Keyboard[0].NumberOfKeys = 101;
+ Keyboard[0].NumberOfLeds = 3;
+ Keyboard[0].NumberOfFunctionKeys = 12;
+ }
+
+ #region IInputDriver Members
+
+ public void Poll()
+ {
+ }
+
+ #endregion
+
+ #region IKeyboardDriver Members
+
+ public IList Keyboard
+ {
+ get { return dummy_keyboard_list; }
+ }
+
+ #endregion
+
+ #region IMouseDriver Members
+
+ public IList Mouse
+ {
+ get { return dummy_mice_list; }
+ }
+
+ #endregion
+
+ #region IJoystickDriver Members
+
+ public IList Joysticks
+ {
+ get { return JoystickDriver.Joysticks; }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ }
+
+ #endregion
+ }
+}
+
diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs b/Source/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
index 8cd64eeb..0f0d45f9 100644
--- a/Source/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
+++ b/Source/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
@@ -6,11 +6,16 @@ namespace OpenTK.Platform.MacOS
{
static class Cocoa
{
+ static readonly IntPtr selUTF8String = Selector.Get("UTF8String");
+
internal const string LibObjC = "/usr/lib/libobjc.dylib";
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector);
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, ulong ulong1);
+
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
@@ -20,11 +25,20 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2);
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3);
+
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, RectangleF rectangle1, int int1, int int2, bool bool1);
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
- public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, uint mask, IntPtr intPtr1, IntPtr intPtr2, bool bool1);
+ public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, uint uint1, IntPtr intPtr1, IntPtr intPtr2, bool bool1);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, RectangleF rectangle1, int int1, IntPtr intPtr1, IntPtr intPtr2);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static bool SendBool(IntPtr receiver, IntPtr selector);
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static bool SendBool(IntPtr receiver, IntPtr selector, int int1);
@@ -32,12 +46,18 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector);
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static void SendVoid(IntPtr receiver, IntPtr selector, uint uint1);
+
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1, int int1);
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2);
+
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, int int1);
@@ -47,7 +67,52 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, PointF point1);
- public static IntPtr ToNative(string str)
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static void SendVoid(IntPtr receiver, IntPtr selector, RectangleF rect1, bool bool1);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static int SendInt(IntPtr receiver, IntPtr selector);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static uint SendUint(IntPtr receiver, IntPtr selector);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static ushort SendUshort(IntPtr receiver, IntPtr selector);
+
+ [DllImport(LibObjC, EntryPoint="objc_msgSend")]
+ public extern static float SendFloat(IntPtr receiver, IntPtr selector);
+
+ [DllImport (LibObjC, EntryPoint="objc_msgSend_stret")]
+ extern static void SendRect(out System.Drawing.RectangleF retval, IntPtr receiver, IntPtr selector);
+
+ [DllImport (LibObjC, EntryPoint="objc_msgSend_stret")]
+ extern static void SendRect(out System.Drawing.RectangleF retval, IntPtr receiver, IntPtr selector, RectangleF rect1);
+
+ [DllImport (LibObjC, EntryPoint="objc_msgSend_stret")]
+ extern static void SendPoint(out System.Drawing.PointF retval, IntPtr receiver, IntPtr selector);
+
+ public static RectangleF SendRect(IntPtr receiver, IntPtr selector)
+ {
+ RectangleF r;
+ SendRect(out r, receiver, selector);
+ return r;
+ }
+
+ public static RectangleF SendRect(IntPtr receiver, IntPtr selector, RectangleF rect1)
+ {
+ RectangleF r;
+ SendRect(out r, receiver, selector, rect1);
+ return r;
+ }
+
+ public static PointF SendPoint(IntPtr receiver, IntPtr selector)
+ {
+ PointF r;
+ SendPoint(out r, receiver, selector);
+ return r;
+ }
+
+ public static IntPtr ToNSString(string str)
{
if (str == null)
return IntPtr.Zero;
@@ -63,6 +128,33 @@ namespace OpenTK.Platform.MacOS
}
}
+ public static string FromNSString(IntPtr handle)
+ {
+ return Marshal.PtrToStringAuto(SendIntPtr(handle, selUTF8String));
+ }
+
+ public static unsafe IntPtr ToNSImage(Image img)
+ {
+ using (System.IO.MemoryStream s = new System.IO.MemoryStream())
+ {
+ img.Save(s, System.Drawing.Imaging.ImageFormat.Png);
+ byte[] b = s.ToArray();
+
+ fixed (byte* pBytes = b)
+ {
+ IntPtr nsData = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSData"), Selector.Alloc),
+ Selector.Get("initWithBytes:length:"), (IntPtr)pBytes, b.Length),
+ Selector.Autorelease);
+
+ IntPtr nsImage = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSImage"), Selector.Alloc),
+ Selector.Get("initWithData:"), nsData),
+ Selector.Autorelease);
+
+ return nsImage;
+ }
+ }
+ }
+
public static IntPtr GetStringConstant(IntPtr handle, string symbol)
{
var indirect = NS.GetSymbol(handle, symbol);
@@ -74,7 +166,6 @@ namespace OpenTK.Platform.MacOS
return IntPtr.Zero;
return actual;
- //return (NSString) Runtime.GetNSObject (actual);
}
public static IntPtr AppKitLibrary;
diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSApplicationPresentationOptions.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSApplicationPresentationOptions.cs
new file mode 100755
index 00000000..dbc349ba
--- /dev/null
+++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSApplicationPresentationOptions.cs
@@ -0,0 +1,19 @@
+namespace OpenTK.Platform.MacOS
+{
+ public enum NSApplicationPresentationOptions
+ {
+ Default = 0,
+ AutoHideDock = 1,
+ HideDock = 2,
+ AutoHideMenuBar = 4,
+ HideMenuBar = 8,
+ DisableAppleMenu = 16,
+ DisableProcessSwitching = 32,
+ DisableForceQuit = 64,
+ DisableSessionTermination = 128,
+ DisableHideApplication = 256,
+ DisableMenuBarTransparency = 512,
+ FullScreen = 1024,
+ AutoHideToolbar = 2048,
+ }
+}
diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSEventModifierMask.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSEventModifierMask.cs
new file mode 100755
index 00000000..e889f6c6
--- /dev/null
+++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSEventModifierMask.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace OpenTK.Platform.MacOS
+{
+ [Flags]
+ public enum NSEventModifierMask : uint
+ {
+ AlphaShiftKeyMask = 65536U,
+ ShiftKeyMask = 131072U,
+ ControlKeyMask = 262144U,
+ AlternateKeyMask = 524288U,
+ CommandKeyMask = 1048576U,
+ NumericPadKeyMask = 2097152U,
+ HelpKeyMask = 4194304U,
+ FunctionKeyMask = 8388608U,
+ DeviceIndependentModifierFlagsMask = 4294901760U,
+ }
+}
diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSEventType.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSEventType.cs
new file mode 100755
index 00000000..a96e0186
--- /dev/null
+++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSEventType.cs
@@ -0,0 +1,37 @@
+namespace OpenTK.Platform.MacOS
+{
+ public enum NSEventType
+ {
+ LeftMouseDown = 1,
+ LeftMouseUp = 2,
+ RightMouseDown = 3,
+ RightMouseUp = 4,
+ MouseMoved = 5,
+ LeftMouseDragged = 6,
+ RightMouseDragged = 7,
+ MouseEntered = 8,
+ MouseExited = 9,
+ KeyDown = 10,
+ KeyUp = 11,
+ FlagsChanged = 12,
+ AppKitDefined = 13,
+ SystemDefined = 14,
+ ApplicationDefined = 15,
+ Periodic = 16,
+ CursorUpdate = 17,
+ Rotate = 18,
+ BeginGesture = 19,
+ EndGesture = 20,
+ ScrollWheel = 22,
+ TabletPoint = 23,
+ TabletProximity = 24,
+ OtherMouseDown = 25,
+ OtherMouseUp = 26,
+ OtherMouseDragged = 27,
+ Gesture = 29,
+ Magnify = 30,
+ Swipe = 31,
+ SmartMagnify = 32,
+ QuickLook = 33,
+ }
+}
diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/NSTrackingAreaOptions.cs b/Source/OpenTK/Platform/MacOS/Cocoa/NSTrackingAreaOptions.cs
new file mode 100755
index 00000000..7ad420ff
--- /dev/null
+++ b/Source/OpenTK/Platform/MacOS/Cocoa/NSTrackingAreaOptions.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace OpenTK.Platform.MacOS
+{
+ [Flags]
+ public enum NSTrackingAreaOptions
+ {
+ MouseEnteredAndExited = 1,
+ MouseMoved = 2,
+ CursorUpdate = 4,
+ ActiveWhenFirstResponder = 16,
+ ActiveInKeyWindow = 32,
+ ActiveInActiveApp = 64,
+ ActiveAlways = 128,
+ AssumeInside = 256,
+ InVisibleRect = 512,
+ EnabledDuringMouseDrag = 1024,
+ }
+}
diff --git a/Source/OpenTK/Platform/MacOS/CocoaContext.cs b/Source/OpenTK/Platform/MacOS/CocoaContext.cs
index 45b9f323..d5927ea5 100644
--- a/Source/OpenTK/Platform/MacOS/CocoaContext.cs
+++ b/Source/OpenTK/Platform/MacOS/CocoaContext.cs
@@ -14,10 +14,10 @@ namespace OpenTK
private IntPtr shareContextRef;
static readonly IntPtr NSOpenGLContext = Class.Get("NSOpenGLContext");
- static readonly IntPtr currentContext = Selector.Get("currentContext");
- static readonly IntPtr flushBuffer = Selector.Get("flushBuffer");
- static readonly IntPtr makeCurrentContext = Selector.Get("makeCurrentContext");
- static readonly IntPtr update = Selector.Get("update");
+ static readonly IntPtr selCurrentContext = Selector.Get("currentContext");
+ static readonly IntPtr selFlushBuffer = Selector.Get("flushBuffer");
+ static readonly IntPtr selMakeCurrentContext = Selector.Get("makeCurrentContext");
+ static readonly IntPtr selUpdate = Selector.Get("update");
static CocoaContext()
{
@@ -155,12 +155,12 @@ namespace OpenTK
public override void SwapBuffers()
{
- Cocoa.SendVoid(Handle.Handle, flushBuffer);
+ Cocoa.SendVoid(Handle.Handle, selFlushBuffer);
}
public override void MakeCurrent(IWindowInfo window)
{
- Cocoa.SendVoid(Handle.Handle, makeCurrentContext);
+ Cocoa.SendVoid(Handle.Handle, selMakeCurrentContext);
}
public override bool IsCurrent
@@ -175,7 +175,7 @@ namespace OpenTK
{
get
{
- return Cocoa.SendIntPtr(NSOpenGLContext, currentContext);
+ return Cocoa.SendIntPtr(NSOpenGLContext, selCurrentContext);
}
}
@@ -207,7 +207,7 @@ namespace OpenTK
public override void Update(IWindowInfo window)
{
- Cocoa.SendVoid(Handle.Handle, update);
+ Cocoa.SendVoid(Handle.Handle, selUpdate);
}
#region IDisposable Members
@@ -230,8 +230,8 @@ namespace OpenTK
Debug.Print("Disposing of Cocoa context.");
Cocoa.SendVoid(NSOpenGLContext, Selector.Get("clearCurrentContext"));
- Cocoa.SendVoid(currentContext, Selector.Get("clearDrawable"));
- Cocoa.SendVoid(currentContext, Selector.Get("release"));
+ Cocoa.SendVoid(Handle.Handle, Selector.Get("clearDrawable"));
+ Cocoa.SendVoid(Handle.Handle, Selector.Get("release"));
Handle = ContextHandle.Zero;
diff --git a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
index 2aa15044..95401c57 100644
--- a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
+++ b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs
@@ -1,116 +1,389 @@
using System;
using OpenTK.Graphics;
using System.Drawing;
+using System.ComponentModel;
+using OpenTK.Input;
+using System.Diagnostics;
namespace OpenTK.Platform.MacOS
{
class CocoaNativeWindow : INativeWindow
{
- public event System.EventHandler Move;
- public event System.EventHandler Resize;
- public event System.EventHandler Closing;
- public event System.EventHandler Closed;
- public event System.EventHandler Disposed;
- public event System.EventHandler IconChanged;
- public event System.EventHandler TitleChanged;
- public event System.EventHandler VisibleChanged;
- public event System.EventHandler FocusedChanged;
- public event System.EventHandler WindowBorderChanged;
- public event System.EventHandler WindowStateChanged;
- public event System.EventHandler KeyDown;
- public event System.EventHandler KeyPress;
- public event System.EventHandler KeyUp;
- public event System.EventHandler MouseLeave;
- public event System.EventHandler MouseEnter;
+ public event EventHandler Move = delegate { };
+ public event EventHandler Resize = delegate { };
+ public event EventHandler Closing = delegate { };
+ public event EventHandler Closed = delegate { };
+ public event EventHandler Disposed = delegate { };
+ public event EventHandler IconChanged = delegate { };
+ public event EventHandler TitleChanged = delegate { };
+ public event EventHandler VisibleChanged = delegate { };
+ public event EventHandler FocusedChanged = delegate { };
+ public event EventHandler WindowBorderChanged = delegate { };
+ public event EventHandler WindowStateChanged = delegate { };
+ public event EventHandler KeyDown = delegate { };
+ public event EventHandler KeyPress = delegate { };
+ public event EventHandler KeyUp = delegate { };
+ public event EventHandler MouseLeave = delegate { };
+ public event EventHandler MouseEnter = delegate { };
- static readonly IntPtr nextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
- static readonly IntPtr sendEvent = Selector.Get("sendEvent:");
- static readonly IntPtr updateWindows = Selector.Get("updateWindows");
- static readonly IntPtr contentView = Selector.Get("contentView");
+ static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
+ static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
+ static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
+ static readonly IntPtr selContentView = Selector.Get("contentView");
+ static readonly IntPtr selConvertRectFromScreen = Selector.Get("convertRectFromScreen:");
+ static readonly IntPtr selConvertRectToScreen = Selector.Get("convertRectToScreen:");
+ static readonly IntPtr selPerformClose = Selector.Get("performClose:");
+ static readonly IntPtr selClose = Selector.Get("close");
+ static readonly IntPtr selTitle = Selector.Get("title");
+ static readonly IntPtr selSetTitle = Selector.Get("setTitle:");
+ static readonly IntPtr selSetApplicationIconImage = Selector.Get("setApplicationIconImage:");
+ static readonly IntPtr selIsKeyWindow = Selector.Get("isKeyWindow");
+ static readonly IntPtr selIsVisible = Selector.Get("isVisible");
+ static readonly IntPtr selSetIsVisible = Selector.Get("setIsVisible:");
+ static readonly IntPtr selFrame = Selector.Get("frame");
+ static readonly IntPtr selBounds = Selector.Get("bounds");
+ static readonly IntPtr selScreen = Selector.Get("screen");
+ static readonly IntPtr selSetFrame = Selector.Get("setFrame:display:");
+ static readonly IntPtr selConvertRectToBacking = Selector.Get("convertRectToBacking:");
+ static readonly IntPtr selConvertRectFromBacking = Selector.Get("convertRectFromBacking:");
+ static readonly IntPtr selFrameRectForContentRect = Selector.Get("frameRectForContentRect:");
+ static readonly IntPtr selType = Selector.Get("type");
+ static readonly IntPtr selKeyCode = Selector.Get("keyCode");
+ static readonly IntPtr selModifierFlags = Selector.Get("modifierFlags");
+ static readonly IntPtr selIsARepeat = Selector.Get("isARepeat");
+ static readonly IntPtr selCharactersIgnoringModifiers = Selector.Get("charactersIgnoringModifiers");
+ static readonly IntPtr selAddTrackingArea = Selector.Get("addTrackingArea:");
+ static readonly IntPtr selRemoveTrackingArea = Selector.Get("removeTrackingArea:");
+ static readonly IntPtr selTrackingArea = Selector.Get("trackingArea");
+ static readonly IntPtr selInitWithRect = Selector.Get("initWithRect:options:owner:userInfo:");
+ static readonly IntPtr selOwner = Selector.Get("owner");
+ static readonly IntPtr selLocationInWindowOwner = Selector.Get("locationInWindow");
+ static readonly IntPtr selHide = Selector.Get("hide");
+ static readonly IntPtr selUnhide = Selector.Get("unhide");
+ static readonly IntPtr selScrollingDeltaY = Selector.Get("scrollingDeltaY");
+ static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber");
+ static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:");
+ static readonly IntPtr selIsInFullScreenMode = Selector.Get("isInFullScreenMode");
+ static readonly IntPtr selIsMiniaturized = Selector.Get("isMiniaturized");
+ static readonly IntPtr selIsZoomed = Selector.Get("isZoomed");
+ static readonly IntPtr selMiniaturize = Selector.Get("miniaturize:");
+ static readonly IntPtr selDeminiaturize = Selector.Get("deminiaturize:");
+ static readonly IntPtr selZoom = Selector.Get("zoom:");
+ static readonly IntPtr selExitFullScreenModeWithOptions = Selector.Get("exitFullScreenModeWithOptions:");
+ static readonly IntPtr selEnterFullScreenModeWithOptions = Selector.Get("enterFullScreenMode:withOptions:");
+
static readonly IntPtr NSDefaultRunLoopMode;
+ static readonly IntPtr NSCursor;
static CocoaNativeWindow()
{
Cocoa.Initialize();
NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode");
+ NSCursor = Class.Get("NSCursor");
}
private CocoaWindowInfo windowInfo;
private IntPtr windowClass;
+ private IntPtr trackingArea;
+ private bool disposed = false;
+ private bool exists = true;
+ private bool cursorVisible = true;
+ private System.Drawing.Icon icon;
+ private LegacyInputDriver inputDriver = new LegacyInputDriver();
+ private WindowBorder windowBorder = WindowBorder.Resizable;
+ private MacOSKeyMap keyMap = new MacOSKeyMap();
+ private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
+ private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{
// Create the window class
windowClass = Class.AllocateClass("OpenTKWindow", "NSWindow");
Class.RegisterMethod(windowClass, new WindowDidResizeDelegate(WindowDidResize), "windowDidResize:", "v@:@");
+ Class.RegisterMethod(windowClass, new WindowShouldCloseDelegate(WindowShouldClose), "windowShouldClose:", "b@:@");
+ Class.RegisterMethod(windowClass, new AcceptsFirstResponderDelegate(AcceptsFirstResponder), "acceptsFirstResponder", "b@:");
+ Class.RegisterMethod(windowClass, new CanBecomeKeyWindowDelegate(CanBecomeKeyWindow), "canBecomeKeyWindow", "b@:");
+ Class.RegisterMethod(windowClass, new CanBecomeMainWindowDelegate(CanBecomeMainWindow), "canBecomeMainWindow", "b@:");
+
Class.RegisterClass(windowClass);
// Create window instance
var contentRect = new System.Drawing.RectangleF(x, y, width, height);
- var style = NSWindowStyle.Titled | NSWindowStyle.Resizable;
+ var style = GetStyleMask(windowBorder);
var bufferingType = NSBackingStore.Buffered;
IntPtr windowPtr;
windowPtr = Cocoa.SendIntPtr(windowClass, Selector.Alloc);
windowPtr = Cocoa.SendIntPtr(windowPtr, Selector.Get("initWithContentRect:styleMask:backing:defer:"), contentRect, (int)style, (int)bufferingType, false);
- windowPtr = Cocoa.SendIntPtr(windowPtr, Selector.Autorelease);
// Set up behavior
Cocoa.SendIntPtr(windowPtr, Selector.Get("setDelegate:"), windowPtr); // The window class acts as its own delegate
Cocoa.SendVoid(windowPtr, Selector.Get("cascadeTopLeftFromPoint:"), new System.Drawing.PointF(20, 20));
- Cocoa.SendVoid(windowPtr, Selector.Get("setTitle:"), Cocoa.ToNative(title));
+ Cocoa.SendVoid(windowPtr, Selector.Get("setTitle:"), Cocoa.ToNSString(title));
Cocoa.SendVoid(windowPtr, Selector.Get("makeKeyAndOrderFront:"), IntPtr.Zero);
windowInfo = new CocoaWindowInfo(windowPtr);
+ ResetTrackingArea();
}
delegate void WindowDidResizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification);
+ delegate bool WindowShouldCloseDelegate(IntPtr self, IntPtr cmd, IntPtr sender);
+ delegate bool AcceptsFirstResponderDelegate(IntPtr self, IntPtr cmd);
+ delegate bool CanBecomeKeyWindowDelegate(IntPtr self, IntPtr cmd);
+ delegate bool CanBecomeMainWindowDelegate(IntPtr self, IntPtr cmd);
- void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
+ private void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification)
{
+ ResetTrackingArea();
GraphicsContext.CurrentContext.Update(windowInfo);
}
- public static IntPtr GetView(IntPtr windowHandle)
+ private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender)
{
- return Cocoa.SendIntPtr(windowHandle, contentView);
+ var cancelArgs = new CancelEventArgs();
+ Closing(this, cancelArgs);
+
+ if (!cancelArgs.Cancel)
+ {
+ Closed(this, EventArgs.Empty);
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool AcceptsFirstResponder(IntPtr self, IntPtr cmd)
+ {
+ return true;
+ }
+
+ private bool CanBecomeKeyWindow(IntPtr self, IntPtr cmd)
+ {
+ return true;
+ }
+
+ private bool CanBecomeMainWindow(IntPtr self, IntPtr cmd)
+ {
+ return true;
+ }
+
+ private void ResetTrackingArea()
+ {
+ var owner = windowInfo.ViewHandle;
+ if (trackingArea != IntPtr.Zero)
+ {
+ Cocoa.SendVoid(owner, selRemoveTrackingArea, trackingArea);
+ }
+
+ var ownerBounds = Cocoa.SendRect(owner, selBounds);
+ var options = (int)(NSTrackingAreaOptions.MouseEnteredAndExited | NSTrackingAreaOptions.ActiveInKeyWindow | NSTrackingAreaOptions.MouseMoved);
+
+ trackingArea = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSTrackingArea"), Selector.Alloc),
+ selInitWithRect, ownerBounds, options, owner, IntPtr.Zero);
+
+ Cocoa.SendVoid(owner, selAddTrackingArea, trackingArea);
}
public void Close()
{
- throw new System.NotImplementedException();
+ // PerformClose is equivalent to pressing the close-button, which
+ // does not work in a borderless window. Handle this special case.
+ if (WindowBorder == WindowBorder.Hidden)
+ {
+ if (WindowShouldClose(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selClose);
+ }
+ }
+ else
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selPerformClose, windowInfo.Handle);
+ }
+ }
+
+ private KeyModifiers GetModifiers(NSEventModifierMask mask)
+ {
+ OpenTK.Input.KeyModifiers modifiers = 0;
+ if ((mask & NSEventModifierMask.ControlKeyMask) != 0) modifiers |= OpenTK.Input.KeyModifiers.Control;
+ if ((mask & NSEventModifierMask.ShiftKeyMask) != 0) modifiers |= OpenTK.Input.KeyModifiers.Shift;
+ if ((mask & NSEventModifierMask.AlternateKeyMask) != 0) modifiers |= OpenTK.Input.KeyModifiers.Alt;
+ return modifiers;
+ }
+
+ private void GetKey(ushort keyCode, NSEventModifierMask modifierFlags, OpenTK.Input.KeyboardKeyEventArgs args)
+ {
+ OpenTK.Input.Key key;
+ if (!keyMap.TryGetValue((OpenTK.Platform.MacOS.Carbon.MacOSKeyCode)keyCode, out key))
+ {
+ key = OpenTK.Input.Key.Unknown;
+ }
+
+ args.Key = key;
+ args.Modifiers = GetModifiers(modifierFlags);
+ args.ScanCode = (uint)keyCode;
+ }
+
+ private MouseButton GetMouseButton(int cocoaButtonIndex)
+ {
+ if (cocoaButtonIndex == 0) return MouseButton.Left;
+ if (cocoaButtonIndex == 1) return MouseButton.Right;
+ if (cocoaButtonIndex == 2) return MouseButton.Middle;
+ if (cocoaButtonIndex >= (int)MouseButton.LastButton)
+ return MouseButton.LastButton;
+
+ return (MouseButton)cocoaButtonIndex;
}
public void ProcessEvents()
{
- var e = Cocoa.SendIntPtr(NSApplication.Handle, nextEventMatchingMask, uint.MaxValue, IntPtr.Zero, NSDefaultRunLoopMode, true);
+ var e = Cocoa.SendIntPtr(NSApplication.Handle, selNextEventMatchingMask, uint.MaxValue, IntPtr.Zero, NSDefaultRunLoopMode, true);
if (e == IntPtr.Zero)
return;
- Cocoa.SendVoid(NSApplication.Handle, sendEvent, e);
- Cocoa.SendVoid(NSApplication.Handle, updateWindows);
+ var type = (NSEventType)Cocoa.SendInt(e, selType);
+ switch (type)
+ {
+ case NSEventType.KeyDown:
+ {
+ var keyCode = Cocoa.SendUshort(e, selKeyCode);
+ var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
+ var isARepeat = Cocoa.SendBool(e, selIsARepeat);
+ GetKey(keyCode, modifierFlags, keyArgs);
+ InputDriver.Keyboard[0].SetKey(keyArgs.Key, keyArgs.ScanCode, true);
+
+ if (!isARepeat || InputDriver.Keyboard[0].KeyRepeat)
+ {
+ KeyDown(this, keyArgs);
+ }
+
+ var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers));
+ foreach (var c in s)
+ {
+ int intVal = (int)c;
+ if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235))
+ {
+ // For some reason, arrow keys (mapped 63232-63235) are seen as non-control characters, so get rid of those.
+
+ keyPressArgs.KeyChar = c;
+ KeyPress(this, keyPressArgs);
+ }
+ }
+
+ // Steal all keydown events to avoid the annoying "bleep" sound.
+ return;
+ }
+
+ case NSEventType.KeyUp:
+ {
+ var keyCode = Cocoa.SendUshort(e, selKeyCode);
+ var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
+
+ GetKey(keyCode, modifierFlags, keyArgs);
+ InputDriver.Keyboard[0].SetKey(keyArgs.Key, keyArgs.ScanCode, false);
+
+ KeyUp(this, keyArgs);
+ }
+ break;
+
+ case NSEventType.MouseEntered:
+ {
+ var eventTrackingArea = Cocoa.SendIntPtr(e, selTrackingArea);
+ var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
+ if (trackingAreaOwner == windowInfo.ViewHandle)
+ {
+ if (!cursorVisible)
+ {
+ SetCursorVisible(false);
+ }
+
+ MouseEnter(this, EventArgs.Empty);
+ }
+ }
+ break;
+
+ case NSEventType.MouseExited:
+ {
+ var eventTrackingArea = Cocoa.SendIntPtr(e, selTrackingArea);
+ var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
+ if (trackingAreaOwner == windowInfo.ViewHandle)
+ {
+ if (!cursorVisible)
+ {
+ SetCursorVisible(true);
+ }
+
+ MouseLeave(this, EventArgs.Empty);
+ }
+ }
+ break;
+
+ case NSEventType.MouseMoved:
+ {
+ var pf = Cocoa.SendPoint(e, selLocationInWindowOwner);
+ var p = new Point((int)pf.X, (int)pf.Y);
+
+ var s = ClientSize;
+ if (p.X < 0) p.X = 0;
+ if (p.Y < 0) p.Y = 0;
+ if (p.X > s.Width) p.X = s.Width;
+ if (p.Y > s.Height) p.Y = s.Height;
+ p.Y = s.Height - p.Y;
+
+ InputDriver.Mouse[0].Position = p;
+ }
+ break;
+
+ case NSEventType.ScrollWheel:
+ {
+ var scrollingDelta = Cocoa.SendFloat(e, selScrollingDeltaY);
+ InputDriver.Mouse[0].WheelPrecise += scrollingDelta;
+ }
+ break;
+
+ case NSEventType.LeftMouseDown:
+ case NSEventType.RightMouseDown:
+ case NSEventType.OtherMouseDown:
+ {
+ var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
+ InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = true;
+ }
+ break;
+
+ case NSEventType.LeftMouseUp:
+ case NSEventType.RightMouseUp:
+ case NSEventType.OtherMouseUp:
+ {
+ var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
+ InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = false;
+ }
+ break;
+ }
+
+ Cocoa.SendVoid(NSApplication.Handle, selSendEvent, e);
+ Cocoa.SendVoid(NSApplication.Handle, selUpdateWindows);
}
public System.Drawing.Point PointToClient(System.Drawing.Point point)
{
- throw new System.NotImplementedException();
+ var r = Cocoa.SendRect(windowInfo.Handle, selConvertRectFromScreen, new RectangleF(point.X, point.Y, 0, 0));
+ return new Point((int)r.X, (int)(GetContentViewFrame().Height - GetCurrentScreenFrame().Height - r.Y));
}
public System.Drawing.Point PointToScreen(System.Drawing.Point point)
{
- throw new System.NotImplementedException();
+ var r = Cocoa.SendRect(windowInfo.Handle, selConvertRectToScreen, new RectangleF(point.X, point.Y, 0, 0));
+ return new Point((int)r.X, (int)(-GetContentViewFrame().Height + GetCurrentScreenFrame().Height - r.Y));
}
public System.Drawing.Icon Icon
{
- get
- {
- throw new System.NotImplementedException();
- }
+ get { return icon; }
set
{
- throw new System.NotImplementedException();
+ icon = value;
+ Cocoa.SendVoid(NSApplication.Handle, selSetApplicationIconImage, Cocoa.ToNSImage(icon.ToBitmap()));
+ IconChanged(this, EventArgs.Empty);
}
}
@@ -118,11 +391,12 @@ namespace OpenTK.Platform.MacOS
{
get
{
- throw new System.NotImplementedException();
+ return Cocoa.FromNSString(Cocoa.SendIntPtr(windowInfo.Handle, selTitle));
}
set
{
- throw new System.NotImplementedException();
+ Cocoa.SendIntPtr(windowInfo.Handle, selSetTitle, Cocoa.ToNSString(value));
+ TitleChanged(this, EventArgs.Empty);
}
}
@@ -130,7 +404,7 @@ namespace OpenTK.Platform.MacOS
{
get
{
- throw new System.NotImplementedException();
+ return Cocoa.SendBool(windowInfo.Handle, selIsKeyWindow);
}
}
@@ -138,12 +412,12 @@ namespace OpenTK.Platform.MacOS
{
get
{
- //throw new System.NotImplementedException();
- return true;
+ return Cocoa.SendBool(windowInfo.Handle, selIsVisible);
}
set
{
- //throw new System.NotImplementedException();
+ Cocoa.SendVoid(windowInfo.Handle, selSetIsVisible, value);
+ VisibleChanged(this, EventArgs.Empty);
}
}
@@ -151,7 +425,7 @@ namespace OpenTK.Platform.MacOS
{
get
{
- return true;
+ return exists;
}
}
@@ -163,75 +437,162 @@ namespace OpenTK.Platform.MacOS
}
}
+ private void RestoreWindowState()
+ {
+ var ws = WindowState;
+ if (ws == WindowState.Fullscreen)
+ {
+ IntPtr nsDictionary = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSDictionary"), Selector.Alloc), Selector.Init), Selector.Autorelease);
+ Cocoa.SendVoid(windowInfo.ViewHandle, selExitFullScreenModeWithOptions, nsDictionary);
+ }
+ else if (ws == WindowState.Maximized)
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selZoom, windowInfo.Handle);
+ }
+ else if (ws == WindowState.Minimized)
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selDeminiaturize, windowInfo.Handle);
+ }
+ }
+
public WindowState WindowState
{
get
{
- throw new System.NotImplementedException();
+ if (Cocoa.SendBool(windowInfo.ViewHandle, selIsInFullScreenMode))
+ return WindowState.Fullscreen;
+
+ if (Cocoa.SendBool(windowInfo.Handle, selIsMiniaturized))
+ return WindowState.Minimized;
+
+ if (Cocoa.SendBool(windowInfo.Handle, selIsZoomed))
+ return WindowState.Maximized;
+
+ return WindowState.Normal;
}
set
{
- throw new System.NotImplementedException();
+ var oldState = WindowState;
+ if (oldState == value)
+ return;
+
+ RestoreWindowState();
+
+ if (value == WindowState.Fullscreen)
+ {
+ NSApplicationPresentationOptions options =
+ NSApplicationPresentationOptions.DisableAppleMenu |
+ NSApplicationPresentationOptions.HideMenuBar |
+ NSApplicationPresentationOptions.HideDock;
+
+ // "Exclusive fullscreen"?
+ //NSApplicationPresentationOptions.DisableProcessSwitching;
+
+ var obj = Cocoa.SendIntPtr(Class.Get("NSNumber"), Selector.Get("numberWithUnsignedLong:"), (ulong)options);
+ var key = Cocoa.ToNSString("NSFullScreenModeApplicationPresentationOptions");
+
+ var nsDictionary = Cocoa.SendIntPtr(Class.Get("NSDictionary"), Selector.Alloc);
+ nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Get("initWithObjectsAndKeys:"), obj, key, IntPtr.Zero);
+ nsDictionary = Cocoa.SendIntPtr(nsDictionary, Selector.Autorelease);
+
+ Cocoa.SendVoid(windowInfo.ViewHandle, selEnterFullScreenModeWithOptions, GetCurrentScreen(), nsDictionary);
+ }
+
+ if (value == WindowState.Maximized)
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selZoom, windowInfo.Handle);
+ }
+
+ if (value == WindowState.Minimized)
+ {
+ Cocoa.SendVoid(windowInfo.Handle, selMiniaturize, windowInfo.Handle);
+ }
+
+ WindowStateChanged(this, EventArgs.Empty);
+ WindowDidResize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}
}
public WindowBorder WindowBorder
{
- get
- {
- throw new System.NotImplementedException();
+ get
+ {
+ return windowBorder;
}
set
{
- throw new System.NotImplementedException();
+ windowBorder = value;
+ Cocoa.SendVoid(windowInfo.Handle, selSetStyleMask, (uint)GetStyleMask(windowBorder));
+ WindowBorderChanged(this, EventArgs.Empty);
}
}
+ private static NSWindowStyle GetStyleMask(WindowBorder windowBorder)
+ {
+ switch (windowBorder)
+ {
+ case WindowBorder.Resizable: return NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Titled | NSWindowStyle.Resizable;
+ case WindowBorder.Fixed: return NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Titled;
+ case WindowBorder.Hidden: return NSWindowStyle.Borderless;
+ }
+
+ return (NSWindowStyle)0;
+ }
+
public System.Drawing.Rectangle Bounds
{
get
{
- throw new System.NotImplementedException();
+ var r = Cocoa.SendRect(windowInfo.Handle, selFrame);
+ return new Rectangle((int)r.X, (int)(GetCurrentScreenFrame().Height - r.Y), (int)r.Width, (int)r.Height);
}
set
{
- throw new System.NotImplementedException();
+ Cocoa.SendVoid(windowInfo.Handle, selSetFrame, new RectangleF(value.X, GetCurrentScreenFrame().Height - value.Y, value.Width, value.Height), true);
}
}
public System.Drawing.Point Location
{
- get
- {
- throw new System.NotImplementedException();
+ get
+ {
+ return Bounds.Location;
}
set
{
- throw new System.NotImplementedException();
+ var b = Bounds;
+ b.Location = value;
+ Bounds = b;
}
}
public System.Drawing.Size Size
{
- get
- {
- throw new System.NotImplementedException();
+ get
+ {
+ return Bounds.Size;
}
set
{
- throw new System.NotImplementedException();
+ var b = Bounds;
+ b.Y -= Bounds.Height;
+ b.Y += value.Height;
+ b.Size = value;
+ Bounds = b;
}
}
public int X
{
- get
+ get
{
- throw new System.NotImplementedException();
+ return Bounds.X;
}
set
{
- throw new System.NotImplementedException();
+ var b = Bounds;
+ b.X = value;
+ Bounds = b;
}
}
@@ -239,35 +600,35 @@ namespace OpenTK.Platform.MacOS
{
get
{
- throw new System.NotImplementedException();
+ return Bounds.Y;
}
set
{
- throw new System.NotImplementedException();
+ var b = Bounds;
+ b.Y = value;
+ Bounds = b;
}
}
public int Width
{
- get
- {
- throw new System.NotImplementedException();
- }
+ get { return ClientRectangle.Width; }
set
{
- throw new System.NotImplementedException();
+ var s = Size;
+ s.Width = value;
+ ClientSize = s;
}
}
public int Height
{
- get
- {
- throw new System.NotImplementedException();
- }
+ get { return ClientRectangle.Height; }
set
{
- throw new System.NotImplementedException();
+ var s = Size;
+ s.Height = value;
+ ClientSize = s;
}
}
@@ -275,23 +636,27 @@ namespace OpenTK.Platform.MacOS
{
get
{
- throw new System.NotImplementedException();
+ var contentViewBounds = Cocoa.SendRect(windowInfo.ViewHandle, selBounds);
+ var bounds = Cocoa.SendRect(windowInfo.Handle, selConvertRectToBacking, contentViewBounds);
+ return new Rectangle((int)bounds.X, (int)bounds.Y, (int)bounds.Width, (int)bounds.Height);
}
- set
+ set
{
- throw new System.NotImplementedException();
+ ClientSize = value.Size; // Just set size, to be consistent with WinGLNative.
}
}
public System.Drawing.Size ClientSize
{
- get
+ get
{
- throw new System.NotImplementedException();
+ return ClientRectangle.Size;
}
set
{
- throw new System.NotImplementedException();
+ var r_scaled = Cocoa.SendRect(windowInfo.Handle, selConvertRectFromBacking, new RectangleF(PointF.Empty, value));
+ var r = Cocoa.SendRect(windowInfo.Handle, selFrameRectForContentRect, r_scaled);
+ Size = new Size((int)r.Width, (int)r.Height);
}
}
@@ -299,25 +664,87 @@ namespace OpenTK.Platform.MacOS
{
get
{
- throw new System.NotImplementedException();
+ return inputDriver;
}
}
public bool CursorVisible
{
- get
- {
- throw new System.NotImplementedException();
- }
+ get { return cursorVisible; }
set
{
- throw new System.NotImplementedException();
+ cursorVisible = value;
+ if (value)
+ {
+ SetCursorVisible(true);
+ }
+ else
+ {
+ SetCursorVisible(false);
+ }
}
}
public void Dispose()
{
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ Debug.Print("Disposing of CocoaNativeWindow.");
+
+ CursorVisible = true;
+ disposed = true;
+ exists = false;
+
+ if (disposing)
+ {
+ if (trackingArea != IntPtr.Zero)
+ {
+ Cocoa.SendVoid(windowInfo.ViewHandle, selRemoveTrackingArea, trackingArea);
+ Cocoa.SendVoid(trackingArea, Selector.Release);
+ trackingArea = IntPtr.Zero;
+ }
+
+ Cocoa.SendVoid(windowInfo.Handle, Selector.Release);
+ }
+
+ Disposed(this, EventArgs.Empty);
+ }
+
+ ~CocoaNativeWindow()
+ {
+ Dispose(false);
+ }
+
+ public static IntPtr GetView(IntPtr windowHandle)
+ {
+ return Cocoa.SendIntPtr(windowHandle, selContentView);
+ }
+
+ private RectangleF GetContentViewFrame()
+ {
+ return Cocoa.SendRect(windowInfo.ViewHandle, selFrame);
+ }
+
+ private IntPtr GetCurrentScreen()
+ {
+ return Cocoa.SendIntPtr(windowInfo.Handle, selScreen);
+ }
+
+ private RectangleF GetCurrentScreenFrame()
+ {
+ return Cocoa.SendRect(GetCurrentScreen(), selFrame);
+ }
+
+ private void SetCursorVisible(bool visible)
+ {
+ Cocoa.SendVoid(NSCursor, visible ? selUnhide : selHide);
}
}
}