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 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
{
get { return top; }
set
{
short height = Height;
top = value;
bottom = (short)(top + height);
}
}
internal short Width
{
get { return (short)(right - left); }
set { right = (short)(left + value); }
}
internal short Height
{
get { return (short)(bottom - top); }
set { bottom = (short)(top + value); }
}
public override string ToString()
{
internal short Y {
get { return top; }
}
internal short Width {
get { return (short)(right - left); }
}
internal short Height {
get { return (short)(bottom - top); }
}
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;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HISize
{
public float Width;
public float Height;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HIRect
{
public HIPoint Origin;
public HISize Size;
internal struct HIPoint {
public IntPtr xVal;
public IntPtr yVal;
public override string ToString()
{
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 HIRect {
public HIPoint Origin;
public HIPoint Size;
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)]
@ -927,6 +904,9 @@ namespace OpenTK.Platform.MacOS.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
// These seem to crash when called, and I haven't figured out why.

View File

@ -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
{
public unsafe double GetNumberValue(string key) {
double retval;
IntPtr cfnum = CF.CFDictionaryGetValue(dictionaryRef,
CF.CFSTR(key));
IntPtr cfnum = CF.CFDictionaryGetValue(DictRef, CF.CFSTR(key));
CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval);
return retval;
}
}
}
class CF
{
const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices";

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
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);
}
}