From 6c6beae4fcde426234dea86c8025e766f68f48da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olle=20H=C3=A5kansson?= Date: Sat, 19 Apr 2014 12:17:14 +0200 Subject: [PATCH] Setup listening for window events. --- Source/OpenTK/Platform/MacOS/Cocoa/Class.cs | 36 +++++++++++++++++++ .../Platform/MacOS/CocoaNativeWindow.cs | 23 ++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Source/OpenTK/Platform/MacOS/Cocoa/Class.cs b/Source/OpenTK/Platform/MacOS/Cocoa/Class.cs index 594ebebf..fa73e09c 100644 --- a/Source/OpenTK/Platform/MacOS/Cocoa/Class.cs +++ b/Source/OpenTK/Platform/MacOS/Cocoa/Class.cs @@ -5,9 +5,21 @@ namespace OpenTK.Platform.MacOS { static class Class { + [DllImport (Cocoa.LibObjC)] + extern static IntPtr class_getName(IntPtr handle); + + [DllImport (Cocoa.LibObjC)] + extern static bool class_addMethod(IntPtr classHandle, IntPtr selector, IntPtr method, string types); + [DllImport (Cocoa.LibObjC)] extern static IntPtr objc_getClass(string name); + [DllImport (Cocoa.LibObjC)] + extern static IntPtr objc_allocateClassPair(IntPtr parentClass, string name, int extraBytes); + + [DllImport (Cocoa.LibObjC)] + extern static void objc_registerClassPair(IntPtr classToRegister); + public static IntPtr Get(string name) { var id = objc_getClass(name); @@ -17,5 +29,29 @@ namespace OpenTK.Platform.MacOS } return id; } + + public static IntPtr AllocateClass(string className, string parentClass) + { + return objc_allocateClassPair(Get(parentClass), className, 0); + } + + public static void RegisterClass(IntPtr handle) + { + objc_registerClassPair(handle); + } + + public static void RegisterMethod(IntPtr handle, Delegate d, string selector, string typeString) + { + // TypeString info: + // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html + + IntPtr p = Marshal.GetFunctionPointerForDelegate(d); + bool r = class_addMethod(handle, Selector.Get(selector), p, typeString); + + if (!r) + { + throw new ArgumentException("Could not register method " + d + " in class + " + class_getName(handle)); + } + } } } diff --git a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index 6a42d48b..2aa15044 100644 --- a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -1,5 +1,6 @@ using System; using OpenTK.Graphics; +using System.Drawing; namespace OpenTK.Platform.MacOS { @@ -22,8 +23,6 @@ namespace OpenTK.Platform.MacOS public event System.EventHandler MouseLeave; public event System.EventHandler MouseEnter; - private CocoaWindowInfo windowInfo; - static readonly IntPtr nextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:"); static readonly IntPtr sendEvent = Selector.Get("sendEvent:"); static readonly IntPtr updateWindows = Selector.Get("updateWindows"); @@ -36,17 +35,28 @@ namespace OpenTK.Platform.MacOS NSDefaultRunLoopMode = Cocoa.GetStringConstant(Cocoa.FoundationLibrary, "NSDefaultRunLoopMode"); } + private CocoaWindowInfo windowInfo; + private IntPtr windowClass; + 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.RegisterClass(windowClass); + + // Create window instance var contentRect = new System.Drawing.RectangleF(x, y, width, height); var style = NSWindowStyle.Titled | NSWindowStyle.Resizable; var bufferingType = NSBackingStore.Buffered; IntPtr windowPtr; - windowPtr = Cocoa.SendIntPtr(Class.Get("NSWindow"), 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.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("makeKeyAndOrderFront:"), IntPtr.Zero); @@ -54,6 +64,13 @@ namespace OpenTK.Platform.MacOS windowInfo = new CocoaWindowInfo(windowPtr); } + delegate void WindowDidResizeDelegate(IntPtr self, IntPtr cmd, IntPtr notification); + + void WindowDidResize(IntPtr self, IntPtr cmd, IntPtr notification) + { + GraphicsContext.CurrentContext.Update(windowInfo); + } + public static IntPtr GetView(IntPtr windowHandle) { return Cocoa.SendIntPtr(windowHandle, contentView);