Restored most window functionality.

This commit is contained in:
Olle Håkansson 2014-04-20 10:08:44 +02:00 committed by thefiddler
parent 5457651676
commit 59d7889ce0
9 changed files with 819 additions and 100 deletions

View file

@ -816,6 +816,11 @@
<Compile Include="Platform\MacOS\Cocoa\NSOpenGLPixelFormatAttribute.cs" /> <Compile Include="Platform\MacOS\Cocoa\NSOpenGLPixelFormatAttribute.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSOpenGLProfile.cs" /> <Compile Include="Platform\MacOS\Cocoa\NSOpenGLProfile.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSOpenGLContextParameter.cs" /> <Compile Include="Platform\MacOS\Cocoa\NSOpenGLContextParameter.cs" />
<Compile Include="Platform\LegacyInputDriver.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSEventType.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSEventModifierMask.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSTrackingAreaOptions.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSApplicationPresentationOptions.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View file

@ -0,0 +1,103 @@
#region License
//
// LegacyInputDriver.cs
//
// Author:
// Stefanos A. <stapostol@gmail.com>
//
// 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<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(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<KeyboardDevice> Keyboard
{
get { return dummy_keyboard_list; }
}
#endregion
#region IMouseDriver Members
public IList<MouseDevice> Mouse
{
get { return dummy_mice_list; }
}
#endregion
#region IJoystickDriver Members
public IList<JoystickDevice> Joysticks
{
get { return JoystickDriver.Joysticks; }
}
#endregion
#region IDisposable Members
public void Dispose()
{
}
#endregion
}
}

View file

@ -6,11 +6,16 @@ namespace OpenTK.Platform.MacOS
{ {
static class Cocoa static class Cocoa
{ {
static readonly IntPtr selUTF8String = Selector.Get("UTF8String");
internal const string LibObjC = "/usr/lib/libobjc.dylib"; internal const string LibObjC = "/usr/lib/libobjc.dylib";
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector); 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")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1); public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
@ -20,11 +25,20 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2); 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")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, RectangleF rectangle1, int int1, int int2, bool bool1); public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, RectangleF rectangle1, int int1, int int2, bool bool1);
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [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")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static bool SendBool(IntPtr receiver, IntPtr selector, int int1); public extern static bool SendBool(IntPtr receiver, IntPtr selector, int int1);
@ -32,12 +46,18 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector); 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")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1); public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1, int int1); 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")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, int int1); public extern static void SendVoid(IntPtr receiver, IntPtr selector, int int1);
@ -47,7 +67,52 @@ namespace OpenTK.Platform.MacOS
[DllImport(LibObjC, EntryPoint="objc_msgSend")] [DllImport(LibObjC, EntryPoint="objc_msgSend")]
public extern static void SendVoid(IntPtr receiver, IntPtr selector, PointF point1); 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) if (str == null)
return IntPtr.Zero; 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) public static IntPtr GetStringConstant(IntPtr handle, string symbol)
{ {
var indirect = NS.GetSymbol(handle, symbol); var indirect = NS.GetSymbol(handle, symbol);
@ -74,7 +166,6 @@ namespace OpenTK.Platform.MacOS
return IntPtr.Zero; return IntPtr.Zero;
return actual; return actual;
//return (NSString) Runtime.GetNSObject (actual);
} }
public static IntPtr AppKitLibrary; public static IntPtr AppKitLibrary;

View file

@ -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,
}
}

View file

@ -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,
}
}

View file

@ -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,
}
}

View file

@ -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,
}
}

View file

@ -14,10 +14,10 @@ namespace OpenTK
private IntPtr shareContextRef; private IntPtr shareContextRef;
static readonly IntPtr NSOpenGLContext = Class.Get("NSOpenGLContext"); static readonly IntPtr NSOpenGLContext = Class.Get("NSOpenGLContext");
static readonly IntPtr currentContext = Selector.Get("currentContext"); static readonly IntPtr selCurrentContext = Selector.Get("currentContext");
static readonly IntPtr flushBuffer = Selector.Get("flushBuffer"); static readonly IntPtr selFlushBuffer = Selector.Get("flushBuffer");
static readonly IntPtr makeCurrentContext = Selector.Get("makeCurrentContext"); static readonly IntPtr selMakeCurrentContext = Selector.Get("makeCurrentContext");
static readonly IntPtr update = Selector.Get("update"); static readonly IntPtr selUpdate = Selector.Get("update");
static CocoaContext() static CocoaContext()
{ {
@ -155,12 +155,12 @@ namespace OpenTK
public override void SwapBuffers() public override void SwapBuffers()
{ {
Cocoa.SendVoid(Handle.Handle, flushBuffer); Cocoa.SendVoid(Handle.Handle, selFlushBuffer);
} }
public override void MakeCurrent(IWindowInfo window) public override void MakeCurrent(IWindowInfo window)
{ {
Cocoa.SendVoid(Handle.Handle, makeCurrentContext); Cocoa.SendVoid(Handle.Handle, selMakeCurrentContext);
} }
public override bool IsCurrent public override bool IsCurrent
@ -175,7 +175,7 @@ namespace OpenTK
{ {
get get
{ {
return Cocoa.SendIntPtr(NSOpenGLContext, currentContext); return Cocoa.SendIntPtr(NSOpenGLContext, selCurrentContext);
} }
} }
@ -207,7 +207,7 @@ namespace OpenTK
public override void Update(IWindowInfo window) public override void Update(IWindowInfo window)
{ {
Cocoa.SendVoid(Handle.Handle, update); Cocoa.SendVoid(Handle.Handle, selUpdate);
} }
#region IDisposable Members #region IDisposable Members
@ -230,8 +230,8 @@ namespace OpenTK
Debug.Print("Disposing of Cocoa context."); Debug.Print("Disposing of Cocoa context.");
Cocoa.SendVoid(NSOpenGLContext, Selector.Get("clearCurrentContext")); Cocoa.SendVoid(NSOpenGLContext, Selector.Get("clearCurrentContext"));
Cocoa.SendVoid(currentContext, Selector.Get("clearDrawable")); Cocoa.SendVoid(Handle.Handle, Selector.Get("clearDrawable"));
Cocoa.SendVoid(currentContext, Selector.Get("release")); Cocoa.SendVoid(Handle.Handle, Selector.Get("release"));
Handle = ContextHandle.Zero; Handle = ContextHandle.Zero;

View file

@ -1,116 +1,389 @@
using System; using System;
using OpenTK.Graphics; using OpenTK.Graphics;
using System.Drawing; using System.Drawing;
using System.ComponentModel;
using OpenTK.Input;
using System.Diagnostics;
namespace OpenTK.Platform.MacOS namespace OpenTK.Platform.MacOS
{ {
class CocoaNativeWindow : INativeWindow class CocoaNativeWindow : INativeWindow
{ {
public event System.EventHandler<System.EventArgs> Move; public event EventHandler<EventArgs> Move = delegate { };
public event System.EventHandler<System.EventArgs> Resize; public event EventHandler<EventArgs> Resize = delegate { };
public event System.EventHandler<System.ComponentModel.CancelEventArgs> Closing; public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
public event System.EventHandler<System.EventArgs> Closed; public event EventHandler<EventArgs> Closed = delegate { };
public event System.EventHandler<System.EventArgs> Disposed; public event EventHandler<EventArgs> Disposed = delegate { };
public event System.EventHandler<System.EventArgs> IconChanged; public event EventHandler<EventArgs> IconChanged = delegate { };
public event System.EventHandler<System.EventArgs> TitleChanged; public event EventHandler<EventArgs> TitleChanged = delegate { };
public event System.EventHandler<System.EventArgs> VisibleChanged; public event EventHandler<EventArgs> VisibleChanged = delegate { };
public event System.EventHandler<System.EventArgs> FocusedChanged; public event EventHandler<EventArgs> FocusedChanged = delegate { };
public event System.EventHandler<System.EventArgs> WindowBorderChanged; public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
public event System.EventHandler<System.EventArgs> WindowStateChanged; public event EventHandler<EventArgs> WindowStateChanged = delegate { };
public event System.EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown; public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown = delegate { };
public event System.EventHandler<KeyPressEventArgs> KeyPress; public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
public event System.EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyUp; public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyUp = delegate { };
public event System.EventHandler<System.EventArgs> MouseLeave; public event EventHandler<EventArgs> MouseLeave = delegate { };
public event System.EventHandler<System.EventArgs> MouseEnter; public event EventHandler<EventArgs> MouseEnter = delegate { };
static readonly IntPtr nextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:"); static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
static readonly IntPtr sendEvent = Selector.Get("sendEvent:"); static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
static readonly IntPtr updateWindows = Selector.Get("updateWindows"); static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
static readonly IntPtr contentView = Selector.Get("contentView"); 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 NSDefaultRunLoopMode;
static readonly IntPtr NSCursor;
static CocoaNativeWindow() static CocoaNativeWindow()
{ {
Cocoa.Initialize(); Cocoa.Initialize();
NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode"); NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode");
NSCursor = Class.Get("NSCursor");
} }
private CocoaWindowInfo windowInfo; private CocoaWindowInfo windowInfo;
private IntPtr windowClass; 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) public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{ {
// Create the window class // Create the window class
windowClass = Class.AllocateClass("OpenTKWindow", "NSWindow"); windowClass = Class.AllocateClass("OpenTKWindow", "NSWindow");
Class.RegisterMethod(windowClass, new WindowDidResizeDelegate(WindowDidResize), "windowDidResize:", "v@:@"); 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); Class.RegisterClass(windowClass);
// Create window instance // Create window instance
var contentRect = new System.Drawing.RectangleF(x, y, width, height); var contentRect = new System.Drawing.RectangleF(x, y, width, height);
var style = NSWindowStyle.Titled | NSWindowStyle.Resizable; var style = GetStyleMask(windowBorder);
var bufferingType = NSBackingStore.Buffered; var bufferingType = NSBackingStore.Buffered;
IntPtr windowPtr; IntPtr windowPtr;
windowPtr = Cocoa.SendIntPtr(windowClass, Selector.Alloc); 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.Get("initWithContentRect:styleMask:backing:defer:"), contentRect, (int)style, (int)bufferingType, false);
windowPtr = Cocoa.SendIntPtr(windowPtr, Selector.Autorelease);
// Set up behavior // Set up behavior
Cocoa.SendIntPtr(windowPtr, Selector.Get("setDelegate:"), windowPtr); // The window class acts as its own delegate 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("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); Cocoa.SendVoid(windowPtr, Selector.Get("makeKeyAndOrderFront:"), IntPtr.Zero);
windowInfo = new CocoaWindowInfo(windowPtr); windowInfo = new CocoaWindowInfo(windowPtr);
ResetTrackingArea();
} }
delegate void WindowDidResizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification); 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); 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() 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() 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) if (e == IntPtr.Zero)
return; return;
Cocoa.SendVoid(NSApplication.Handle, sendEvent, e); var type = (NSEventType)Cocoa.SendInt(e, selType);
Cocoa.SendVoid(NSApplication.Handle, updateWindows); 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) 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) 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 public System.Drawing.Icon Icon
{ {
get get { return icon; }
{
throw new System.NotImplementedException();
}
set 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 get
{ {
throw new System.NotImplementedException(); return Cocoa.FromNSString(Cocoa.SendIntPtr(windowInfo.Handle, selTitle));
} }
set 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 get
{ {
throw new System.NotImplementedException(); return Cocoa.SendBool(windowInfo.Handle, selIsKeyWindow);
} }
} }
@ -138,12 +412,12 @@ namespace OpenTK.Platform.MacOS
{ {
get get
{ {
//throw new System.NotImplementedException(); return Cocoa.SendBool(windowInfo.Handle, selIsVisible);
return true;
} }
set set
{ {
//throw new System.NotImplementedException(); Cocoa.SendVoid(windowInfo.Handle, selSetIsVisible, value);
VisibleChanged(this, EventArgs.Empty);
} }
} }
@ -151,7 +425,7 @@ namespace OpenTK.Platform.MacOS
{ {
get 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 public WindowState WindowState
{ {
get 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 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 public WindowBorder WindowBorder
{ {
get get
{ {
throw new System.NotImplementedException(); return windowBorder;
} }
set 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 public System.Drawing.Rectangle Bounds
{ {
get 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 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 public System.Drawing.Point Location
{ {
get get
{ {
throw new System.NotImplementedException(); return Bounds.Location;
} }
set set
{ {
throw new System.NotImplementedException(); var b = Bounds;
b.Location = value;
Bounds = b;
} }
} }
public System.Drawing.Size Size public System.Drawing.Size Size
{ {
get get
{ {
throw new System.NotImplementedException(); return Bounds.Size;
} }
set set
{ {
throw new System.NotImplementedException(); var b = Bounds;
b.Y -= Bounds.Height;
b.Y += value.Height;
b.Size = value;
Bounds = b;
} }
} }
public int X public int X
{ {
get get
{ {
throw new System.NotImplementedException(); return Bounds.X;
} }
set set
{ {
throw new System.NotImplementedException(); var b = Bounds;
b.X = value;
Bounds = b;
} }
} }
@ -239,35 +600,35 @@ namespace OpenTK.Platform.MacOS
{ {
get get
{ {
throw new System.NotImplementedException(); return Bounds.Y;
} }
set set
{ {
throw new System.NotImplementedException(); var b = Bounds;
b.Y = value;
Bounds = b;
} }
} }
public int Width public int Width
{ {
get get { return ClientRectangle.Width; }
{
throw new System.NotImplementedException();
}
set set
{ {
throw new System.NotImplementedException(); var s = Size;
s.Width = value;
ClientSize = s;
} }
} }
public int Height public int Height
{ {
get get { return ClientRectangle.Height; }
{
throw new System.NotImplementedException();
}
set set
{ {
throw new System.NotImplementedException(); var s = Size;
s.Height = value;
ClientSize = s;
} }
} }
@ -275,23 +636,27 @@ namespace OpenTK.Platform.MacOS
{ {
get 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 public System.Drawing.Size ClientSize
{ {
get get
{ {
throw new System.NotImplementedException(); return ClientRectangle.Size;
} }
set 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 get
{ {
throw new System.NotImplementedException(); return inputDriver;
} }
} }
public bool CursorVisible public bool CursorVisible
{ {
get get { return cursorVisible; }
{
throw new System.NotImplementedException();
}
set set
{ {
throw new System.NotImplementedException(); cursorVisible = value;
if (value)
{
SetCursorVisible(true);
}
else
{
SetCursorVisible(false);
}
} }
} }
public void Dispose() 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);
} }
} }
} }