Hopefully fix Get/SetCursorPos on OSX.

This commit is contained in:
UnknownShadow200 2015-11-01 14:05:39 +11:00
parent 4ecb9ed833
commit dbd8ffe3dc
5 changed files with 95 additions and 124 deletions

View File

@ -33,53 +33,35 @@ namespace OpenTK.Platform.MacOS.Carbon
short bottom; short bottom;
short right; short right;
internal Rect(short _left, short _top, short _width, short _height) internal Rect(short _left, short _top, short _width, short _height) {
{
top = _top; top = _top;
left = _left; left = _left;
bottom = (short)(_top + _height); bottom = (short)(_top + _height);
right = (short)(_left + _width); right = (short)(_left + _width);
} }
internal short X internal short X {
{
get { return left; } get { return left; }
set
{
short width = Width;
left = value;
right = (short)(left + width);
}
} }
internal short Y
{ internal short Y {
get { return top; } get { return top; }
set
{
short height = Height;
top = value;
bottom = (short)(top + height);
}
} }
internal short Width
{ internal short Width {
get { return (short)(right - left); } get { return (short)(right - left); }
set { right = (short)(left + value); }
} }
internal short Height
{ internal short Height {
get { return (short)(bottom - top); } get { return (short)(bottom - top); }
set { bottom = (short)(top + value); }
} }
public override string ToString() public override string ToString() {
{
return string.Format( return string.Format(
"Rect: [{0}, {1}, {2}, {3}]", X, Y, Width, Height); "Rect: [{0}, {1}, {2}, {3}]", X, Y, Width, Height);
} }
public Rectangle ToRectangle() public Rectangle ToRectangle() {
{
return new Rectangle(X, Y, Width, Height); return new Rectangle(X, Y, Width, Height);
} }
} }
@ -88,27 +70,51 @@ namespace OpenTK.Platform.MacOS.Carbon
#region --- Types defined in HIGeometry.h --- #region --- Types defined in HIGeometry.h ---
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct HIPoint internal struct HIPoint {
{ public IntPtr xVal;
public float X; public IntPtr yVal;
public float Y;
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)] [StructLayout(LayoutKind.Sequential)]
internal struct HISize internal struct HIRect {
{
public float Width;
public float Height;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HIRect
{
public HIPoint Origin; public HIPoint Origin;
public HISize Size; public HIPoint Size;
public override string ToString() public override string ToString() {
{
return string.Format( 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 #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)] [DllImport(carbon)]
internal static extern OSStatus ActivateWindow (IntPtr inWindow, bool inActivate); internal static extern OSStatus ActivateWindow (IntPtr inWindow, bool inActivate);
@ -805,24 +800,6 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
internal static extern void QuitApplicationEventLoop(); 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 --- #region --- SetWindowTitle ---
[DllImport(carbon)] [DllImport(carbon)]
@ -926,6 +903,9 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(carbon)] [DllImport(carbon)]
internal unsafe static extern OSStatus DMGetGDeviceByDisplayID( internal unsafe static extern OSStatus DMGetGDeviceByDisplayID(
IntPtr displayID, out IntPtr displayDevice, Boolean failToMain); 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 #region Nonworking HIPointConvert routines

View File

@ -10,19 +10,16 @@ namespace OpenTK.Platform.MacOS.Carbon
IntPtr arrayRef; IntPtr arrayRef;
public IntPtr Ref { get { return arrayRef; } set { arrayRef = value; } } public IntPtr Ref { get { return arrayRef; } set { arrayRef = value; } }
public CFArray(IntPtr reference) public CFArray(IntPtr reference) {
{
arrayRef = reference; arrayRef = reference;
} }
public int Count public int Count {
{
get { return CF.CFArrayGetCount(arrayRef); } get { return CF.CFArrayGetCount(arrayRef); }
} }
public IntPtr this[int index]
{ public IntPtr this[int index] {
get get {
{
if (index >= Count || index < 0) if (index >= Count || index < 0)
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
@ -30,37 +27,27 @@ namespace OpenTK.Platform.MacOS.Carbon
} }
} }
} }
struct CFDictionary
{ struct CFDictionary {
public CFDictionary(IntPtr reference) public CFDictionary(IntPtr reference) {
{ DictRef = reference;
dictionaryRef = reference;
} }
IntPtr dictionaryRef; public IntPtr DictRef;
public IntPtr Ref { get { return dictionaryRef; } set { dictionaryRef = value; } }
public int Count public int Count {
{ get { return CF.CFDictionaryGetCount(DictRef); }
get
{
return CF.CFDictionaryGetCount(dictionaryRef);
}
} }
public double GetNumberValue(string key)
{ public unsafe double GetNumberValue(string key) {
unsafe double retval;
{ IntPtr cfnum = CF.CFDictionaryGetValue(DictRef, CF.CFSTR(key));
double retval;
IntPtr cfnum = CF.CFDictionaryGetValue(dictionaryRef,
CF.CFSTR(key));
CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval); CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval);
return retval;
return retval;
}
} }
} }
class CF class CF
{ {
const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices"; const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices";

View File

@ -55,5 +55,7 @@ namespace OpenTK.Platform.MacOS.Carbon
[DllImport(appServices)] [DllImport(appServices)]
internal static extern CGDisplayErr CGDisplayShowCursor(IntPtr display); internal static extern CGDisplayErr CGDisplayShowCursor(IntPtr display);
[DllImport(appServices)]
internal static extern CGDisplayErr CGDisplayMoveCursorToPoint(IntPtr display, HIPoint point);
} }
} }

View File

@ -1025,16 +1025,18 @@ namespace OpenTK.Platform.MacOS
get { return mouse; } 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 { public Point DesktopCursorPos {
get { return System.Windows.Forms.Cursor.Position; } get {
set { System.Windows.Forms.Cursor.Position = value; } 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; bool visible = true;

View File

@ -30,25 +30,25 @@ namespace OpenTK.Platform.MacOS
Debug.Print("CoreGraphics reported {0} display(s).", displayCount); Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
for (int i = 0; i < displayCount; i++) { 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. // according to docs, first element in the array is always the main display.
bool primary = (i == 0); bool primary = (i == 0);
if (primary) if (primary)
mainDisplay = currentDisplay; mainDisplay = curDisplay;
// gets current settings // gets current settings
int currentWidth = CG.CGDisplayPixelsWide(currentDisplay); int currentWidth = CG.CGDisplayPixelsWide(curDisplay);
int currentHeight = CG.CGDisplayPixelsHigh(currentDisplay); int currentHeight = CG.CGDisplayPixelsHigh(curDisplay);
Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight); 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); CFArray displayModes = new CFArray(displayModesPtr);
Debug.Print("Supports {0} display modes.", displayModes.Count); Debug.Print("Supports {0} display modes.", displayModes.Count);
DisplayResolution opentk_dev_current_res = null; DisplayResolution opentk_dev_current_res = null;
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>(); List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
IntPtr currentModePtr = CG.CGDisplayCurrentMode(currentDisplay); IntPtr currentModePtr = CG.CGDisplayCurrentMode(curDisplay);
CFDictionary currentMode = new CFDictionary(currentModePtr); CFDictionary currentMode = new CFDictionary(currentModePtr);
for (int j = 0; j < displayModes.Count; j++) for (int j = 0; j < displayModes.Count; j++)
@ -59,7 +59,7 @@ namespace OpenTK.Platform.MacOS
int height = (int) dict.GetNumberValue("Height"); int height = (int) dict.GetNumberValue("Height");
int bpp = (int) dict.GetNumberValue("BitsPerPixel"); int bpp = (int) dict.GetNumberValue("BitsPerPixel");
double freq = dict.GetNumberValue("RefreshRate"); double freq = dict.GetNumberValue("RefreshRate");
bool current = currentMode.Ref == dict.Ref; bool current = currentMode.DictRef == dict.DictRef;
//if (current) Debug.Write(" * "); //if (current) Debug.Write(" * ");
//else Debug.Write(" "); //else Debug.Write(" ");
@ -73,16 +73,16 @@ namespace OpenTK.Platform.MacOS
opentk_dev_current_res = thisRes; opentk_dev_current_res = thisRes;
} }
HIRect bounds = CG.CGDisplayBounds(currentDisplay); HIRect bounds = CG.CGDisplayBounds(curDisplay);
Rectangle newRect = new Rectangle( 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); Debug.Print("Display {0} bounds: {1}", i, newRect);
DisplayDevice opentk_dev = DisplayDevice opentk_dev =
new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect); new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect);
displayMap.Add(opentk_dev, currentDisplay); displayMap.Add(opentk_dev, curDisplay);
} }
} }