Merge remote-tracking branch 'frassle/issue76' into develop
This commit is contained in:
commit
74cff79d64
2 changed files with 171 additions and 4 deletions
|
@ -371,6 +371,21 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region GetMessageTime
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the message time for the last message retrieved by the
|
||||
/// GetMessage function. The time is a long integer that specifies the
|
||||
/// elapsed time, in milliseconds, from the time the system was started
|
||||
/// to the time the message was created (that is, placed in the thread's
|
||||
/// message queue).
|
||||
/// </summary>
|
||||
/// <returns>The return value specifies the message time.</returns>
|
||||
[DllImport("User32.dll")]
|
||||
internal static extern int GetMessageTime();
|
||||
|
||||
#endregion
|
||||
|
||||
#region SendMessage
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
|
@ -1004,6 +1019,30 @@ namespace OpenTK.Platform.Windows
|
|||
[DllImport("user32.dll")]
|
||||
public static extern bool SetCursorPos(int X, int Y);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a history of up to 64 previous coordinates of the mouse or pen.
|
||||
/// </summary>
|
||||
/// <param name="cbSize">The size, in bytes, of the MouseMovePoint structure.</param>
|
||||
/// <param name="pointsIn">
|
||||
/// A pointer to a MOUSEMOVEPOINT structure containing valid mouse
|
||||
/// coordinates (in screen coordinates). It may also contain a time
|
||||
/// stamp.
|
||||
/// </param>
|
||||
/// <param name="pointsBufferOut">
|
||||
/// A pointer to a buffer that will receive the points. It should be at
|
||||
/// least cbSize * nBufPoints in size.
|
||||
/// </param>
|
||||
/// <param name="nBufPoints">The number of points to be retrieved.</param>
|
||||
/// <param name="resolution">
|
||||
/// The resolution desired. This parameter can GMMP_USE_DISPLAY_POINTS
|
||||
/// or GMMP_USE_HIGH_RESOLUTION_POINTS.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
[DllImport("user32", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
unsafe internal static extern int GetMouseMovePointsEx(
|
||||
uint cbSize, MouseMovePoint* pointsIn,
|
||||
MouseMovePoint* pointsBufferOut, int nBufPoints, uint resolution);
|
||||
|
||||
#region Async input
|
||||
|
||||
#region GetCursorPos
|
||||
|
@ -1633,6 +1672,27 @@ namespace OpenTK.Platform.Windows
|
|||
internal static readonly IntPtr MESSAGE_ONLY = new IntPtr(-3);
|
||||
|
||||
internal static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
|
||||
|
||||
// System Error Codes
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
|
||||
|
||||
/// <summary>
|
||||
/// The point passed to GetMouseMovePoints is not in the buffer.
|
||||
/// </summary>
|
||||
internal const int ERROR_POINT_NOT_FOUND = 1171;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the points using the display resolution.
|
||||
/// </summary>
|
||||
internal const int GMMP_USE_DISPLAY_POINTS = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves high resolution points. Points can range from zero to
|
||||
/// 65,535 (0xFFFF) in both x and y coordinates. This is the resolution
|
||||
/// provided by absolute coordinate pointing devices such as drawing
|
||||
/// tablets.
|
||||
/// </summary>
|
||||
internal const int GMMP_USE_HIGH_RESOLUTION_POINTS = 2;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -2917,6 +2977,36 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region MouseMovePoint
|
||||
|
||||
/// <summary>
|
||||
/// Contains information about the mouse's location in screen coordinates.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MouseMovePoint
|
||||
{
|
||||
/// <summary>
|
||||
/// The x-coordinate of the mouse.
|
||||
/// </summary>
|
||||
public int X;
|
||||
/// <summary>
|
||||
/// The y-coordinate of the mouse.
|
||||
/// </summary>
|
||||
public int Y;
|
||||
/// <summary>
|
||||
/// The time stamp of the mouse coordinate.
|
||||
/// </summary>
|
||||
public int Time;
|
||||
/// <summary>
|
||||
/// Additional information associated with this coordinate.
|
||||
/// </summary>
|
||||
public IntPtr ExtraInfo;
|
||||
|
||||
public static readonly int SizeInBytes = Marshal.SizeOf(default(MouseMovePoint));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Enums ---
|
||||
|
|
|
@ -70,6 +70,7 @@ namespace OpenTK.Platform.Windows
|
|||
bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible).
|
||||
bool focused;
|
||||
bool mouse_outside_window = true;
|
||||
int mouse_last_timestamp = 0;
|
||||
bool invisible_since_creation; // Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront).
|
||||
int suppress_resize; // Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events.
|
||||
bool is_in_modal_loop; // set to true whenever we enter the modal resize/move event loop
|
||||
|
@ -403,10 +404,86 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
void HandleMouseMove(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Point point = new Point(
|
||||
(short)((uint)lParam.ToInt32() & 0x0000FFFF),
|
||||
(short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));
|
||||
mouse.Position = point;
|
||||
unsafe
|
||||
{
|
||||
Point point = new Point(
|
||||
(short)((uint)lParam.ToInt32() & 0x0000FFFF),
|
||||
(short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));
|
||||
|
||||
// GetMouseMovePointsEx works with screen coordinates
|
||||
Point screenPoint = point;
|
||||
Functions.ClientToScreen(handle, ref screenPoint);
|
||||
int timestamp = Functions.GetMessageTime();
|
||||
|
||||
// & 0xFFFF to handle multiple monitors http://support.microsoft.com/kb/269743
|
||||
MouseMovePoint movePoint = new MouseMovePoint()
|
||||
{
|
||||
X = screenPoint.X & 0xFFFF,
|
||||
Y = screenPoint.Y & 0xFFFF,
|
||||
Time = timestamp,
|
||||
};
|
||||
|
||||
// Max points GetMouseMovePointsEx can return is 64.
|
||||
int numPoints = 64;
|
||||
|
||||
MouseMovePoint* movePoints = stackalloc MouseMovePoint[numPoints];
|
||||
|
||||
// GetMouseMovePointsEx fills in movePoints so that the most
|
||||
// recent events are at low indices in the array.
|
||||
int points = Functions.GetMouseMovePointsEx(
|
||||
(uint)MouseMovePoint.SizeInBytes,
|
||||
&movePoint, movePoints, numPoints,
|
||||
Constants.GMMP_USE_DISPLAY_POINTS);
|
||||
|
||||
int lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
// No points returned or search point not found
|
||||
if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
|
||||
{
|
||||
// Just use the mouse move position
|
||||
mouse.Position = point;
|
||||
}
|
||||
else if (points == -1)
|
||||
{
|
||||
throw new System.ComponentModel.Win32Exception(lastError);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Exclude the current position.
|
||||
Point currentScreenPosition = new Point(mouse.X, mouse.Y);
|
||||
Functions.ClientToScreen(handle, ref currentScreenPosition);
|
||||
|
||||
// Find the first move point we've already seen.
|
||||
int i = 0;
|
||||
for (i = 0; i < points; ++i)
|
||||
{
|
||||
if (movePoints[i].Time < mouse_last_timestamp)
|
||||
break;
|
||||
if (movePoints[i].Time == mouse_last_timestamp &&
|
||||
movePoints[i].X == currentScreenPosition.X &&
|
||||
movePoints[i].Y == currentScreenPosition.Y)
|
||||
break;
|
||||
}
|
||||
|
||||
// Now move the mouse to each point before the one just found.
|
||||
while (--i >= 0)
|
||||
{
|
||||
Point position = new Point(movePoints[i].X, movePoints[i].Y);
|
||||
// Handle multiple monitors http://support.microsoft.com/kb/269743
|
||||
if (position.X > 32767)
|
||||
{
|
||||
position.X -= 65536;
|
||||
}
|
||||
if (position.Y > 32767)
|
||||
{
|
||||
position.Y -= 65536;
|
||||
}
|
||||
Functions.ScreenToClient(handle, ref position);
|
||||
mouse.Position = position;
|
||||
}
|
||||
}
|
||||
mouse_last_timestamp = timestamp;
|
||||
}
|
||||
|
||||
if (mouse_outside_window)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue