From dbd8ffe3dc3e1ef5d889cb9334ae5806694500d0 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 1 Nov 2015 14:05:39 +1100 Subject: [PATCH] Hopefully fix Get/SetCursorPos on OSX. --- .../MacOS/CarbonBindings/CarbonAPI.cs | 126 ++++++++---------- .../MacOS/CarbonBindings/CoreFoundation.cs | 51 +++---- .../QuartzDisplayServicesAPI.cs | 2 + OpenTK/Platform/MacOS/CarbonGLNative.cs | 20 +-- .../MacOS/QuartzDisplayDeviceDriver.cs | 20 +-- 5 files changed, 95 insertions(+), 124 deletions(-) diff --git a/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs b/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs index 57a7231c5..bd6edafb4 100644 --- a/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs +++ b/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs @@ -33,53 +33,35 @@ namespace OpenTK.Platform.MacOS.Carbon short bottom; short right; - internal Rect(short _left, short _top, short _width, short _height) - { + internal Rect(short _left, short _top, short _width, short _height) { top = _top; left = _left; bottom = (short)(_top + _height); right = (short)(_left + _width); } - internal short X - { + internal short X { get { return left; } - set - { - short width = Width; - left = value; - right = (short)(left + width); - } } - internal short Y - { + + internal short Y { get { return top; } - set - { - short height = Height; - top = value; - bottom = (short)(top + height); - } } - internal short Width - { + + internal short Width { get { return (short)(right - left); } - set { right = (short)(left + value); } } - internal short Height - { + + internal short Height { get { return (short)(bottom - top); } - set { bottom = (short)(top + value); } } - public override string ToString() - { + public override string ToString() { return string.Format( "Rect: [{0}, {1}, {2}, {3}]", X, Y, Width, Height); } - public Rectangle ToRectangle() - { + public Rectangle ToRectangle() { return new Rectangle(X, Y, Width, Height); } } @@ -88,27 +70,51 @@ namespace OpenTK.Platform.MacOS.Carbon #region --- Types defined in HIGeometry.h --- [StructLayout(LayoutKind.Sequential)] - internal struct HIPoint - { - public float X; - public float Y; + internal struct HIPoint { + public IntPtr xVal; + public IntPtr yVal; + + public float X { + get { return GetFloat( xVal ); } + set { SetFloat( ref xVal, value ); } + } + + public float Y { + get { return GetFloat( yVal ); } + set { SetFloat( ref yVal, value ); } + } + + static unsafe float GetFloat( IntPtr val ) { + if( IntPtr.Size == 8 ) { + long raw = val.ToInt64(); + return (float)(*((double*)&raw)); + } else { + int raw = val.ToInt32(); + return *((float*)&raw); + } + } + + static unsafe void SetFloat( ref IntPtr val, float x ) { + if( IntPtr.Size == 8 ) { + long raw = 0; + *((double*)&raw) = x; + val = new IntPtr( raw ); + } else { + int raw = 0; + *((float*)&raw) = x; + val = new IntPtr( raw ); + } + } } + [StructLayout(LayoutKind.Sequential)] - internal struct HISize - { - public float Width; - public float Height; - } - [StructLayout(LayoutKind.Sequential)] - internal struct HIRect - { + internal struct HIRect { public HIPoint Origin; - public HISize Size; + public HIPoint Size; - public override string ToString() - { + public override string ToString() { return string.Format( - "Rect: [{0}, {1}, {2}, {3}]", Origin.X, Origin.Y, Size.Width, Size.Height); + "Rect: [{0}, {1}, {2}, {3}]", Origin.X, Origin.Y, Size.X, Size.Y); } } @@ -785,17 +791,6 @@ namespace OpenTK.Platform.MacOS.Carbon #endregion - [DllImport(carbon)] - static extern IntPtr GetControlBounds(IntPtr control, out Rect bounds); - - internal static Rect GetControlBounds(IntPtr control) - { - Rect retval; - GetControlBounds(control, out retval); - - return retval; - } - [DllImport(carbon)] internal static extern OSStatus ActivateWindow (IntPtr inWindow, bool inActivate); @@ -805,24 +800,6 @@ namespace OpenTK.Platform.MacOS.Carbon [DllImport(carbon)] internal static extern void QuitApplicationEventLoop(); - [DllImport(carbon)] - internal static extern IntPtr GetControlOwner(IntPtr control); - - [DllImport(carbon)] - internal static extern IntPtr HIViewGetWindow(IntPtr inView); - - [DllImport(carbon)] - static extern OSStatus HIViewGetFrame(IntPtr inView, out HIRect outRect); - internal static HIRect HIViewGetFrame(IntPtr inView) - { - HIRect retval; - OSStatus result = HIViewGetFrame(inView, out retval); - - if (result != OSStatus.NoError) - throw new MacOSException(result); - - return retval; - } #region --- SetWindowTitle --- [DllImport(carbon)] @@ -926,6 +903,9 @@ namespace OpenTK.Platform.MacOS.Carbon [DllImport(carbon)] internal unsafe static extern OSStatus DMGetGDeviceByDisplayID( IntPtr displayID, out IntPtr displayDevice, Boolean failToMain); + + [DllImport(carbon)] + internal unsafe static extern IntPtr HIGetMousePosition( HICoordinateSpace space, IntPtr obj, ref HIPoint point ); #region Nonworking HIPointConvert routines diff --git a/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs b/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs index 96dc16ddb..e294c782a 100644 --- a/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs +++ b/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs @@ -10,19 +10,16 @@ namespace OpenTK.Platform.MacOS.Carbon IntPtr arrayRef; public IntPtr Ref { get { return arrayRef; } set { arrayRef = value; } } - public CFArray(IntPtr reference) - { + public CFArray(IntPtr reference) { arrayRef = reference; } - public int Count - { + public int Count { get { return CF.CFArrayGetCount(arrayRef); } } - public IntPtr this[int index] - { - get - { + + public IntPtr this[int index] { + get { if (index >= Count || index < 0) throw new IndexOutOfRangeException(); @@ -30,37 +27,27 @@ namespace OpenTK.Platform.MacOS.Carbon } } } - struct CFDictionary - { - public CFDictionary(IntPtr reference) - { - dictionaryRef = reference; + + struct CFDictionary { + public CFDictionary(IntPtr reference) { + DictRef = reference; } - IntPtr dictionaryRef; - public IntPtr Ref { get { return dictionaryRef; } set { dictionaryRef = value; } } + public IntPtr DictRef; - public int Count - { - get - { - return CF.CFDictionaryGetCount(dictionaryRef); - } + public int Count { + get { return CF.CFDictionaryGetCount(DictRef); } } - public double GetNumberValue(string key) - { - unsafe - { - double retval; - IntPtr cfnum = CF.CFDictionaryGetValue(dictionaryRef, - CF.CFSTR(key)); + + public unsafe double GetNumberValue(string key) { + double retval; + IntPtr cfnum = CF.CFDictionaryGetValue(DictRef, CF.CFSTR(key)); - CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval); - - return retval; - } + CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval); + return retval; } } + class CF { const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices"; diff --git a/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs b/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs index fa658a339..1308b7767 100644 --- a/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs +++ b/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs @@ -55,5 +55,7 @@ namespace OpenTK.Platform.MacOS.Carbon [DllImport(appServices)] internal static extern CGDisplayErr CGDisplayShowCursor(IntPtr display); + [DllImport(appServices)] + internal static extern CGDisplayErr CGDisplayMoveCursorToPoint(IntPtr display, HIPoint point); } } diff --git a/OpenTK/Platform/MacOS/CarbonGLNative.cs b/OpenTK/Platform/MacOS/CarbonGLNative.cs index 04259b94e..674845ba8 100644 --- a/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ b/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -1025,16 +1025,18 @@ namespace OpenTK.Platform.MacOS get { return mouse; } } - // TODO: Implement using native API, rather than through Mono. - // http://webnnel.googlecode.com/svn/trunk/lib/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/CarbonEventsCore.h - // GetPos --> GetGlobalMouse (no 64 bit support?), and HIGetMousePosition() - // https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/Quartz_Services_Ref/index.html#//apple_ref/c/func/CGWarpMouseCursorPosition - // SetPos --> CGWarpMouseCursorPosition - // Note that: CGPoint uses float on 32 bit systems, double on 64 bit systems - // The rest of the MacOS OpenTK API will probably need to be fixed for this too... public Point DesktopCursorPos { - get { return System.Windows.Forms.Cursor.Position; } - set { System.Windows.Forms.Cursor.Position = value; } + get { + HIPoint point = default( HIPoint ); + // NOTE: HIGetMousePosition is only available on OSX 10.5 or later + API.HIGetMousePosition( HICoordinateSpace.ScreenPixel, IntPtr.Zero, ref point ); + return new Point( (int)point.X, (int)point.Y ); + } + set { + HIPoint point = default( HIPoint ); + point.X = value.X; point.Y = value.Y; + CG.CGDisplayMoveCursorToPoint( CG.CGMainDisplayID(), point ); + } } bool visible = true; diff --git a/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs b/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs index 50313aa6b..23744e9d6 100644 --- a/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs +++ b/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs @@ -30,25 +30,25 @@ namespace OpenTK.Platform.MacOS Debug.Print("CoreGraphics reported {0} display(s).", displayCount); for (int i = 0; i < displayCount; i++) { - IntPtr currentDisplay = displays[i]; + IntPtr curDisplay = displays[i]; // according to docs, first element in the array is always the main display. bool primary = (i == 0); if (primary) - mainDisplay = currentDisplay; + mainDisplay = curDisplay; // gets current settings - int currentWidth = CG.CGDisplayPixelsWide(currentDisplay); - int currentHeight = CG.CGDisplayPixelsHigh(currentDisplay); + int currentWidth = CG.CGDisplayPixelsWide(curDisplay); + int currentHeight = CG.CGDisplayPixelsHigh(curDisplay); Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight); - IntPtr displayModesPtr = CG.CGDisplayAvailableModes(currentDisplay); + IntPtr displayModesPtr = CG.CGDisplayAvailableModes(curDisplay); CFArray displayModes = new CFArray(displayModesPtr); Debug.Print("Supports {0} display modes.", displayModes.Count); DisplayResolution opentk_dev_current_res = null; List opentk_dev_available_res = new List(); - IntPtr currentModePtr = CG.CGDisplayCurrentMode(currentDisplay); + IntPtr currentModePtr = CG.CGDisplayCurrentMode(curDisplay); CFDictionary currentMode = new CFDictionary(currentModePtr); for (int j = 0; j < displayModes.Count; j++) @@ -59,7 +59,7 @@ namespace OpenTK.Platform.MacOS int height = (int) dict.GetNumberValue("Height"); int bpp = (int) dict.GetNumberValue("BitsPerPixel"); double freq = dict.GetNumberValue("RefreshRate"); - bool current = currentMode.Ref == dict.Ref; + bool current = currentMode.DictRef == dict.DictRef; //if (current) Debug.Write(" * "); //else Debug.Write(" "); @@ -73,16 +73,16 @@ namespace OpenTK.Platform.MacOS opentk_dev_current_res = thisRes; } - HIRect bounds = CG.CGDisplayBounds(currentDisplay); + HIRect bounds = CG.CGDisplayBounds(curDisplay); Rectangle newRect = new Rectangle( - (int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.Width, (int)bounds.Size.Height); + (int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.X, (int)bounds.Size.Y); Debug.Print("Display {0} bounds: {1}", i, newRect); DisplayDevice opentk_dev = new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect); - displayMap.Add(opentk_dev, currentDisplay); + displayMap.Add(opentk_dev, curDisplay); } }