mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-25 18:25:30 +00:00
* Platform/MacOS/CarbonGLNative.cs:
Implemented CursorVisible property. Aligned mouse behavior to win32 & x11. General code cleanup.
This commit is contained in:
parent
37a744acb3
commit
db6cc338f5
|
@ -62,7 +62,8 @@ namespace OpenTK.Platform.MacOS
|
||||||
private WindowBorder windowBorder = WindowBorder.Resizable;
|
private WindowBorder windowBorder = WindowBorder.Resizable;
|
||||||
private WindowState windowState = WindowState.Normal;
|
private WindowState windowState = WindowState.Normal;
|
||||||
|
|
||||||
static Dictionary<IntPtr, WeakReference> mWindows = new Dictionary<IntPtr, WeakReference>();
|
static Dictionary<IntPtr, WeakReference> mWindows =
|
||||||
|
new Dictionary<IntPtr, WeakReference>(new IntPtrEqualityComparer());
|
||||||
|
|
||||||
KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0);
|
KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0);
|
||||||
|
|
||||||
|
@ -71,6 +72,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
Icon mIcon;
|
Icon mIcon;
|
||||||
|
|
||||||
|
// Used to accumulate mouse motion when the cursor is hidden.
|
||||||
|
float mouse_rel_x;
|
||||||
|
float mouse_rel_y;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region AGL Device Hack
|
#region AGL Device Hack
|
||||||
|
@ -93,20 +98,25 @@ namespace OpenTK.Platform.MacOS
|
||||||
Application.Initialize();
|
Application.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
CarbonGLNative() : this(WindowClass.Document, WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.InWindowMenu | WindowAttributes.LiveResize)
|
CarbonGLNative() : this(WindowClass.Document,
|
||||||
|
WindowAttributes.StandardDocument | WindowAttributes.StandardHandler |
|
||||||
|
WindowAttributes.InWindowMenu | WindowAttributes.LiveResize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CarbonGLNative(WindowClass @class, WindowAttributes attrib)
|
CarbonGLNative(WindowClass @class, WindowAttributes attrib)
|
||||||
{
|
{
|
||||||
mWindowClass = @class;
|
mWindowClass = @class;
|
||||||
mWindowAttrib = attrib;
|
mWindowAttrib = attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarbonGLNative(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
public CarbonGLNative(int x, int y, int width, int height, string title,
|
||||||
|
GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||||
{
|
{
|
||||||
CreateNativeWindow(WindowClass.Document, WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, new Rect((short)x, (short)y, (short)width, (short)height));
|
CreateNativeWindow(WindowClass.Document,
|
||||||
|
WindowAttributes.StandardDocument | WindowAttributes.StandardHandler |
|
||||||
|
WindowAttributes.InWindowMenu | WindowAttributes.LiveResize,
|
||||||
|
new Rect((short)x, (short)y, (short)width, (short)height));
|
||||||
|
|
||||||
mDisplayDevice = device;
|
mDisplayDevice = device;
|
||||||
}
|
}
|
||||||
|
@ -128,11 +138,13 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
Debug.Print("Disposing of CarbonGLNative window.");
|
Debug.Print("Disposing of CarbonGLNative window.");
|
||||||
|
|
||||||
|
CursorVisible = true;
|
||||||
API.DisposeWindow(window.WindowRef);
|
API.DisposeWindow(window.WindowRef);
|
||||||
|
|
||||||
mIsDisposed = true;
|
mIsDisposed = true;
|
||||||
mExists = false;
|
mExists = false;
|
||||||
|
|
||||||
|
CG.SetLocalEventsSuppressionInterval(0.25);
|
||||||
|
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
mWindows.Remove(window.WindowRef);
|
mWindows.Remove(window.WindowRef);
|
||||||
|
@ -200,6 +212,13 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
mInputDriver = new CarbonInput();
|
mInputDriver = new CarbonInput();
|
||||||
|
|
||||||
|
EventTypeSpec[] eventTypes = new EventTypeSpec[]
|
||||||
|
{
|
||||||
|
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose),
|
||||||
|
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed),
|
||||||
|
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged),
|
||||||
|
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowActivate),
|
||||||
|
new EventTypeSpec(EventClass.Window, WindowEventKind.WindowDeactivate),
|
||||||
|
|
||||||
//new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
|
//new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
|
||||||
//new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
|
//new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
|
||||||
|
@ -213,12 +232,13 @@ namespace OpenTK.Platform.MacOS
|
||||||
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
|
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
|
||||||
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
|
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
|
||||||
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
|
//new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
|
||||||
EventTypeSpec[] eventTypes = new EventTypeSpec[] { new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowActivate), new EventTypeSpec(EventClass.Window, WindowEventKind.WindowDeactivate) };
|
};
|
||||||
|
|
||||||
MacOSEventHandler handler = EventHandler;
|
MacOSEventHandler handler = EventHandler;
|
||||||
uppHandler = API.NewEventHandlerUPP(handler);
|
uppHandler = API.NewEventHandlerUPP(handler);
|
||||||
|
|
||||||
API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero);
|
API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes,
|
||||||
|
window.WindowRef, IntPtr.Zero);
|
||||||
|
|
||||||
Application.WindowEventHandler = this;
|
Application.WindowEventHandler = this;
|
||||||
}
|
}
|
||||||
|
@ -439,6 +459,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
return OSStatus.EventNotHandled;
|
return OSStatus.EventNotHandled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData)
|
protected OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse);
|
System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse);
|
||||||
|
@ -446,128 +467,102 @@ namespace OpenTK.Platform.MacOS
|
||||||
HIPoint pt = new HIPoint();
|
HIPoint pt = new HIPoint();
|
||||||
HIPoint screenLoc = new HIPoint();
|
HIPoint screenLoc = new HIPoint();
|
||||||
|
|
||||||
OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc);
|
IntPtr thisEventWindow;
|
||||||
|
API.GetEventWindowRef(inEvent, out thisEventWindow);
|
||||||
|
|
||||||
|
OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc);
|
||||||
if (this.windowState == WindowState.Fullscreen)
|
if (this.windowState == WindowState.Fullscreen)
|
||||||
{
|
{
|
||||||
pt = screenLoc;
|
pt = screenLoc;
|
||||||
}
|
}
|
||||||
|
else if (CursorVisible)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
err = API.GetEventWindowMouseLocation(inEvent, out pt);
|
err = API.GetEventWindowMouseLocation(inEvent, out pt);
|
||||||
|
pt.Y -= mTitlebarHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = API.GetEventMouseDelta(inEvent, out pt);
|
||||||
|
pt.X += mouse_rel_x;
|
||||||
|
pt.Y += mouse_rel_y;
|
||||||
|
pt = ConfineMouseToWindow(thisEventWindow, pt);
|
||||||
|
ResetMouseToWindowCenter();
|
||||||
|
mouse_rel_x = pt.X;
|
||||||
|
mouse_rel_y = pt.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != OSStatus.NoError)
|
if (err != OSStatus.NoError && err != OSStatus.EventParameterNotFound)
|
||||||
{
|
{
|
||||||
// this error comes up from the application event handler.
|
// this error comes up from the application event handler.
|
||||||
if (err != OSStatus.EventParameterNotFound)
|
throw new MacOSException(err);
|
||||||
{
|
|
||||||
throw new MacOSException(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point mousePosInClient = new Point((int)pt.X, (int)pt.Y);
|
Point mousePosInClient = new Point((int)pt.X, (int)pt.Y);
|
||||||
if (this.windowState != WindowState.Fullscreen)
|
|
||||||
{
|
|
||||||
mousePosInClient.Y -= mTitlebarHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for enter/leave events
|
|
||||||
IntPtr thisEventWindow;
|
|
||||||
API.GetEventWindowRef(inEvent, out thisEventWindow);
|
|
||||||
CheckEnterLeaveEvents(thisEventWindow, mousePosInClient);
|
CheckEnterLeaveEvents(thisEventWindow, mousePosInClient);
|
||||||
|
|
||||||
switch (evt.MouseEventKind)
|
switch (evt.MouseEventKind)
|
||||||
{
|
{
|
||||||
case MouseEventKind.MouseDown:
|
case MouseEventKind.MouseDown:
|
||||||
button = API.GetEventMouseButton(inEvent);
|
case MouseEventKind.MouseUp:
|
||||||
|
button = API.GetEventMouseButton(inEvent);
|
||||||
|
bool pressed = evt.MouseEventKind == MouseEventKind.MouseDown;
|
||||||
|
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
|
||||||
case MouseButton.Primary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MouseButton.Secondary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MouseButton.Tertiary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return OSStatus.NoError;
|
|
||||||
|
|
||||||
case MouseEventKind.MouseUp:
|
|
||||||
button = API.GetEventMouseButton(inEvent);
|
|
||||||
|
|
||||||
switch (button)
|
|
||||||
{
|
|
||||||
case MouseButton.Primary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MouseButton.Secondary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MouseButton.Tertiary:
|
|
||||||
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
button = API.GetEventMouseButton(inEvent);
|
|
||||||
|
|
||||||
return OSStatus.NoError;
|
|
||||||
|
|
||||||
case MouseEventKind.WheelMoved:
|
|
||||||
|
|
||||||
int delta = API.GetEventMouseWheelDelta(inEvent) / 3;
|
|
||||||
|
|
||||||
InputDriver.Mouse[0].Wheel += delta;
|
|
||||||
|
|
||||||
return OSStatus.NoError;
|
|
||||||
|
|
||||||
case MouseEventKind.MouseMoved:
|
|
||||||
case MouseEventKind.MouseDragged:
|
|
||||||
|
|
||||||
//Debug.Print("Mouse Location: {0}, {1}", pt.X, pt.Y);
|
|
||||||
|
|
||||||
if (this.windowState == WindowState.Fullscreen)
|
|
||||||
{
|
|
||||||
if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y)
|
|
||||||
{
|
{
|
||||||
InputDriver.Mouse[0].Position = mousePosInClient;
|
case MouseButton.Primary:
|
||||||
|
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = pressed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseButton.Secondary:
|
||||||
|
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = pressed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseButton.Tertiary:
|
||||||
|
InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = pressed;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
return OSStatus.NoError;
|
||||||
|
|
||||||
else
|
case MouseEventKind.WheelMoved:
|
||||||
{
|
float delta = API.GetEventMouseWheelDelta(inEvent);
|
||||||
// ignore clicks in the title bar
|
InputDriver.Mouse[0].WheelPrecise += delta;
|
||||||
if (pt.Y < 0)
|
return OSStatus.NoError;
|
||||||
return OSStatus.EventNotHandled;
|
|
||||||
|
|
||||||
if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y)
|
case MouseEventKind.MouseMoved:
|
||||||
|
case MouseEventKind.MouseDragged:
|
||||||
|
if (this.windowState == WindowState.Fullscreen)
|
||||||
{
|
{
|
||||||
InputDriver.Mouse[0].Position = mousePosInClient;
|
if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y)
|
||||||
|
{
|
||||||
|
InputDriver.Mouse[0].Position = mousePosInClient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
// ignore clicks in the title bar
|
||||||
|
if (pt.Y < 0)
|
||||||
|
return OSStatus.EventNotHandled;
|
||||||
|
|
||||||
|
if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y)
|
||||||
|
{
|
||||||
|
InputDriver.Mouse[0].Position = mousePosInClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OSStatus.EventNotHandled;
|
||||||
|
|
||||||
return OSStatus.EventNotHandled;
|
default:
|
||||||
default:
|
Debug.Print("{0}", evt);
|
||||||
|
return OSStatus.EventNotHandled;
|
||||||
Debug.Print("{0}", evt);
|
|
||||||
|
|
||||||
return OSStatus.EventNotHandled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetMouseToWindowCenter()
|
||||||
|
{
|
||||||
|
OpenTK.Input.Mouse.SetPosition(
|
||||||
|
(Bounds.Left + Bounds.Right) / 2,
|
||||||
|
(Bounds.Top + Bounds.Bottom) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt)
|
private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt)
|
||||||
{
|
{
|
||||||
if (window == null)
|
if (window == null)
|
||||||
|
@ -589,11 +584,28 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Point in client (window) coordinates
|
||||||
|
private HIPoint ConfineMouseToWindow(IntPtr window, HIPoint client)
|
||||||
|
{
|
||||||
|
if (client.X < 0)
|
||||||
|
client.X = 0;
|
||||||
|
if (client.X >= Width)
|
||||||
|
client.X = Width - 1;
|
||||||
|
if (client.Y < 0)
|
||||||
|
client.Y = 0;
|
||||||
|
if (client.Y >= Height)
|
||||||
|
client.Y = Height - 1;
|
||||||
|
|
||||||
|
Debug.Print("[{0}:{1}]", client.X, client.Y);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode)
|
private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode)
|
||||||
{
|
{
|
||||||
code = API.GetEventKeyboardKeyCode(inEvent);
|
code = API.GetEventKeyboardKeyCode(inEvent);
|
||||||
charCode = API.GetEventKeyboardChar(inEvent);
|
charCode = API.GetEventKeyboardChar(inEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessModifierKey(IntPtr inEvent)
|
private void ProcessModifierKey(IntPtr inEvent)
|
||||||
{
|
{
|
||||||
MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent);
|
MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent);
|
||||||
|
@ -662,7 +674,6 @@ namespace OpenTK.Platform.MacOS
|
||||||
API.SizeWindow(window.WindowRef, width, height, true);
|
API.SizeWindow(window.WindowRef, width, height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void LoadSize()
|
private void LoadSize()
|
||||||
{
|
{
|
||||||
if (WindowState == WindowState.Fullscreen)
|
if (WindowState == WindowState.Fullscreen)
|
||||||
|
@ -687,15 +698,12 @@ namespace OpenTK.Platform.MacOS
|
||||||
public Point PointToClient(Point point)
|
public Point PointToClient(Point point)
|
||||||
{
|
{
|
||||||
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
|
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
|
||||||
Debug.Print("Rect: {0}", r);
|
|
||||||
|
|
||||||
return new Point(point.X - r.X, point.Y - r.Y);
|
return new Point(point.X - r.X, point.Y - r.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point PointToScreen(Point point)
|
public Point PointToScreen(Point point)
|
||||||
{
|
{
|
||||||
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
|
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
|
||||||
Debug.Print("Rect: {0}", r);
|
|
||||||
|
|
||||||
return new Point(point.X + r.X, point.Y + r.Y);
|
return new Point(point.X + r.X, point.Y + r.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,7 +727,6 @@ namespace OpenTK.Platform.MacOS
|
||||||
get { return mInputDriver; }
|
get { return mInputDriver; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Icon Icon
|
public Icon Icon
|
||||||
{
|
{
|
||||||
get { return mIcon; }
|
get { return mIcon; }
|
||||||
|
@ -892,8 +899,21 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
public bool CursorVisible
|
public bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return CG.CursorIsVisible(); }
|
||||||
set { }
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
CG.DisplayShowCursor(IntPtr.Zero);
|
||||||
|
CG.AssociateMouseAndMouseCursorPosition(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CG.DisplayHideCursor(IntPtr.Zero);
|
||||||
|
ResetMouseToWindowCenter();
|
||||||
|
CG.AssociateMouseAndMouseCursorPosition(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
|
Loading…
Reference in a new issue