Fixed a mouse input bug when the virtual screen's left-most coordinate is in the negative. Refactored ICapturer virtual screen methods.

This commit is contained in:
Jared Goodwin 2019-04-10 16:49:44 -07:00
parent 0690a54c3d
commit 0bd2261be7
9 changed files with 63 additions and 66 deletions

View File

@ -20,11 +20,12 @@ The following steps will configure your Windows 10 machine for building the Remo
* The output folder will now contain the server, with the clients in the Downloads folder.
## Hosting a Server (Windows)
* Create a site in IIS that will run Remotely.
* Run Install-RemotelyServer.ps1 (as an administrator), which is in the [Utilities folder in source control](https://raw.githubusercontent.com/Jay-Rad/Remotely/master/Utilities/Install-RemotelyServer.ps1).
* Download and install the .NET Core Runtime (not the SDK).
* Link: https://dotnet.microsoft.com/download
* This includes the Hosting Bundle for Windows, which allows you to run ASP.NET Core in IIS.
* Create a site in IIS that will run Remotely.
* Run Install-RemotelyServer.ps1 (as an administrator), which is in the [Utilities folder in source control](https://raw.githubusercontent.com/Jay-Rad/Remotely/master/Utilities/Install-RemotelyServer.ps1).
* Important: If you installed .NET Core Runtime before installing all the required IIS features (which is done in the script), you may need to run a repair on the .NET Core Runtime installation.
* Change values in appsettings.json for your environment.
* If using SQLite configuration, make sure the ApplicationPool's account has write access to the DB file location.
* The script will do this for you, assuming all default settings.
@ -50,6 +51,16 @@ The following steps will configure your Windows 10 machine for building the Remo
* After creating your account on the website, you can set "AllowSelfRegistration" to false in appsettings.json to disable registration.
* Documentation for hosting behind Nginx can be found here: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2
## Logging
* On clients, logs are kept in %temp%\Remotely_Logs.txt.
* For the Agent running as a Windows service, this maps to C:\Windows\Temp\Remotely_Logs.txt.
* On the server, some event information is explicitly written to the EventLogs table in the database.
* Built-in ASP.NET Core logs are written to the console (stdout). You can redirect this to a file if desired.
* In IIS, this can be done in the web.config file by setting stdoutLogEnabled to true.
* On Windows Servers, the above logs are also written to the Windows Event Log.
* You can configure logging levels and other settings in appsetttings.json.
* More information: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2
## Remote Control Requirements
* Windows: Only the latest version of Windows 10 is tested.
* Requires .NET Framework 4.7.2.

View File

@ -17,8 +17,7 @@ namespace Remotely_ScreenCast.Core.Capture
int SelectedScreen { get; }
void SetSelectedScreen(int screenNumber);
int GetScreenCount();
double GetVirtualScreenHeight();
double GetVirtualScreenWidth();
Rectangle GetVirtualScreenBounds();
void Capture();
void Init();

View File

@ -152,17 +152,6 @@ namespace Remotely_ScreenCast.Core.Capture
}
}
public static Tuple<double, double> GetAbsolutePercentFromRelativePercent(double percentX, double percentY, ICapturer capturer)
{
var absoluteX = (capturer.CurrentScreenBounds.Width * percentX) + capturer.CurrentScreenBounds.Left;
var absoluteY = (capturer.CurrentScreenBounds.Height * percentY) + capturer.CurrentScreenBounds.Top;
return new Tuple<double, double>(absoluteX / capturer.GetVirtualScreenWidth(), absoluteY / capturer.GetVirtualScreenHeight());
}
public static Tuple<double, double> GetAbsolutePointFromRelativePercent(double percentX, double percentY, ICapturer capturer)
{
var absoluteX = (capturer.CurrentScreenBounds.Width * percentX) + capturer.CurrentScreenBounds.Left;
var absoluteY = (capturer.CurrentScreenBounds.Height * percentY) + capturer.CurrentScreenBounds.Top;
return new Tuple<double, double>(absoluteX, absoluteY);
}
}
}

View File

@ -86,8 +86,7 @@ namespace Remotely_ScreenCast.Core.Sockets
{
if (Conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
{
var xyPercents = ScreenCaster.GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
KeyboardMouseInput.SendMouseMove(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendMouseMove(percentX, percentY, viewer);
}
});
@ -95,14 +94,13 @@ namespace Remotely_ScreenCast.Core.Sockets
{
if (Conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
{
var xyPercents = ScreenCaster.GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
if (button == 0)
{
KeyboardMouseInput.SendLeftMouseDown(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer);
}
else if (button == 2)
{
KeyboardMouseInput.SendRightMouseDown(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendRightMouseDown(percentX, percentY, viewer);
}
}
});
@ -111,14 +109,13 @@ namespace Remotely_ScreenCast.Core.Sockets
{
if (Conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
{
var xyPercents = ScreenCaster.GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
if (button == 0)
{
KeyboardMouseInput.SendLeftMouseUp(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer);
}
else if (button == 2)
{
KeyboardMouseInput.SendRightMouseUp(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendRightMouseUp(percentX, percentY, viewer);
}
}
});
@ -204,9 +201,8 @@ namespace Remotely_ScreenCast.Core.Sockets
{
if (Conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
{
var xyPercents = ScreenCaster.GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
KeyboardMouseInput.SendLeftMouseDown(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendLeftMouseUp(xyPercents.Item1, xyPercents.Item2, viewer);
KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer);
KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer);
}
});
Connection.On("SharedFileIDs", (List<string> fileIDs) => {

View File

@ -51,24 +51,19 @@ namespace Remotely_ScreenCast.Linux.Capture
return LibX11.XScreenCount(Display);
}
public double GetVirtualScreenHeight()
public Rectangle GetVirtualScreenBounds()
{
double height = 0;
for (var i = 0; i < GetScreenCount(); i++)
{
height += LibX11.XHeightOfScreen(LibX11.XScreenOfDisplay(Display, i));
}
return height;
}
public double GetVirtualScreenWidth()
{
double width = 0;
int width = 0;
for (var i = 0; i < GetScreenCount(); i++)
{
width += LibX11.XWidthOfScreen(LibX11.XScreenOfDisplay(Display, i));
}
return width;
int height = 0;
for (var i = 0; i < GetScreenCount(); i++)
{
height += LibX11.XHeightOfScreen(LibX11.XScreenOfDisplay(Display, i));
}
return new Rectangle(0, 0, width, height);
}
public void Init()

View File

@ -65,14 +65,9 @@ namespace Remotely_ScreenCast.Win.Capture
return Screen.AllScreens.Length;
}
public double GetVirtualScreenHeight()
public Rectangle GetVirtualScreenBounds()
{
return SystemInformation.VirtualScreen.Height;
}
public double GetVirtualScreenWidth()
{
return SystemInformation.VirtualScreen.Width;
return SystemInformation.VirtualScreen;
}
public void Init()

View File

@ -125,14 +125,9 @@ namespace Remotely_ScreenCast.Win.Capture
return Screen.AllScreens.Length;
}
public double GetVirtualScreenHeight()
public Rectangle GetVirtualScreenBounds()
{
return SystemInformation.VirtualScreen.Height;
}
public double GetVirtualScreenWidth()
{
return SystemInformation.VirtualScreen.Width;
return SystemInformation.VirtualScreen;
}
public void Init()

View File

@ -3,6 +3,7 @@ using Remotely_ScreenCast.Core.Models;
using System;
using Remotely_Shared.Win32;
using static Remotely_Shared.Win32.User32;
using Remotely_ScreenCast.Core.Capture;
namespace Remotely_ScreenCast.Win.Input
{
@ -10,45 +11,50 @@ namespace Remotely_ScreenCast.Win.Input
{
public uint SendLeftMouseDown(double percentX, double percentY, Viewer viewer)
{
var xyPercent = GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
// Coordinates must be normalized. The bottom-right coordinate is mapped to 65535.
var normalizedX = percentX * 65535D;
var normalizedY = percentY * 65535D;
var normalizedX = xyPercent.Item1 * 65535D;
var normalizedY = xyPercent.Item2 * 65535D;
var union = new InputUnion() { mi = new MOUSEINPUT() { dwFlags = MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.LEFTDOWN | MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = GetMessageExtraInfo() } };
var input = new INPUT() { type = InputType.MOUSE, U = union };
return SendInput(1, new INPUT[] { input }, INPUT.Size);
}
public uint SendLeftMouseUp(double percentX, double percentY, Viewer viewer)
{
var xyPercent = GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
// Coordinates must be normalized. The bottom-right coordinate is mapped to 65535.
var normalizedX = percentX * 65535D;
var normalizedY = percentY * 65535D;
var normalizedX = xyPercent.Item1 * 65535D;
var normalizedY = xyPercent.Item2 * 65535D;
var union = new InputUnion() { mi = new MOUSEINPUT() { dwFlags = MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.LEFTUP | MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = GetMessageExtraInfo() } };
var input = new INPUT() { type = InputType.MOUSE, U = union };
return SendInput(1, new INPUT[] { input }, INPUT.Size);
}
public uint SendRightMouseDown(double percentX, double percentY, Viewer viewer)
{
var xyPercent = GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
// Coordinates must be normalized. The bottom-right coordinate is mapped to 65535.
var normalizedX = percentX * 65535D;
var normalizedY = percentY * 65535D;
var normalizedX = xyPercent.Item1 * 65535D;
var normalizedY = xyPercent.Item2 * 65535D;
var union = new InputUnion() { mi = new MOUSEINPUT() { dwFlags = MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.RIGHTDOWN | MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = GetMessageExtraInfo() } };
var input = new INPUT() { type = InputType.MOUSE, U = union };
return SendInput(1, new INPUT[] { input }, INPUT.Size);
}
public uint SendRightMouseUp(double percentX, double percentY, Viewer viewer)
{
var xyPercent = GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
// Coordinates must be normalized. The bottom-right coordinate is mapped to 65535.
var normalizedX = percentX * 65535D;
var normalizedY = percentY * 65535D;
var normalizedX = xyPercent.Item1 * 65535D;
var normalizedY = xyPercent.Item2 * 65535D;
var union = new InputUnion() { mi = new MOUSEINPUT() { dwFlags = MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.RIGHTUP | MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = GetMessageExtraInfo() } };
var input = new INPUT() { type = InputType.MOUSE, U = union };
return SendInput(1, new INPUT[] { input }, INPUT.Size);
}
public uint SendMouseMove(double percentX, double percentY, Viewer viewer)
{
var xyPercent = GetAbsolutePercentFromRelativePercent(percentX, percentY, viewer.Capturer);
// Coordinates must be normalized. The bottom-right coordinate is mapped to 65535.
var normalizedX = percentX * 65535D;
var normalizedY = percentY * 65535D;
var normalizedX = xyPercent.Item1 * 65535D;
var normalizedY = xyPercent.Item2 * 65535D;
var union = new InputUnion() { mi = new MOUSEINPUT() { dwFlags = MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.MOVE | MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = GetMessageExtraInfo() } };
var input = new INPUT() { type = InputType.MOUSE, U = union };
return SendInput(1, new INPUT[] { input }, INPUT.Size);
@ -220,6 +226,17 @@ namespace Remotely_ScreenCast.Win.Input
return keyCode;
}
public Tuple<double, double> GetAbsolutePercentFromRelativePercent(double percentX, double percentY, ICapturer capturer)
{
var absoluteX = (capturer.CurrentScreenBounds.Width * percentX) + capturer.CurrentScreenBounds.Left - capturer.GetVirtualScreenBounds().Left;
var absoluteY = (capturer.CurrentScreenBounds.Height * percentY) + capturer.CurrentScreenBounds.Top - capturer.GetVirtualScreenBounds().Top;
return new Tuple<double, double>(absoluteX / capturer.GetVirtualScreenBounds().Width, absoluteY / capturer.GetVirtualScreenBounds().Height);
}
public Tuple<double, double> GetAbsolutePointFromRelativePercent(double percentX, double percentY, ICapturer capturer)
{
var absoluteX = (capturer.CurrentScreenBounds.Width * percentX) + capturer.CurrentScreenBounds.Left;
var absoluteY = (capturer.CurrentScreenBounds.Height * percentY) + capturer.CurrentScreenBounds.Top;
return new Tuple<double, double>(absoluteX, absoluteY);
}
}
}

View File

@ -1 +1 @@
2019.04.10.0649
2019.04.10.0829