mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
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:
parent
0690a54c3d
commit
0bd2261be7
15
README.md
15
README.md
@ -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.
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
2019.04.10.0649
|
||||
2019.04.10.0829
|
||||
|
||||
Loading…
Reference in New Issue
Block a user