Skip to content

Commit

Permalink
multi monitor support for mouse input remapping
Browse files Browse the repository at this point in the history
  • Loading branch information
komefai committed Apr 14, 2018
1 parent ea5d88f commit cf7ce2c
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 60 deletions.
27 changes: 14 additions & 13 deletions PS4Macro/Classes/Remapping/Remapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public enum AnalogStick

public class Remapper
{
private const int MOUSE_CENTER_X = 500;
private const int MOUSE_CENTER_Y = 500;
private const int MOUSE_RELEASE_TIME = 50;
//private const int MOUSE_CENTER_X = 500;
//private const int MOUSE_CENTER_Y = 500;
//private const int MOUSE_RELEASE_TIME = 50;
private const int MOUSE_SENSITIVITY_DIVISOR = 100000;

// Delegates
Expand Down Expand Up @@ -453,8 +453,8 @@ public void OnMouseEvent(object sender, GlobalMouseHookEventArgs e)
var rawY = e.MouseData.Point.Y;

// Ignore if at center
if (rawX == MOUSE_CENTER_X && rawY == MOUSE_CENTER_Y)
return;
//if (rawX == MOUSE_CENTER_X && rawY == MOUSE_CENTER_Y)
// return;

#region Store mouse stroke
var newStroke = new MouseStroke()
Expand All @@ -476,35 +476,36 @@ public void OnMouseEvent(object sender, GlobalMouseHookEventArgs e)
CurrentMouseStroke = newStroke;
#endregion

#region Adjust cursor position
var tmpX = rawX;
var tmpY = rawY;
#region Adjust cursor position;
var didSetPosition = false;
var workingArea = Screen.PrimaryScreen.WorkingArea;
var screen = Screen.FromHandle(RemotePlayProcess.MainWindowHandle);
var workingArea = screen.WorkingArea;
var tmpX = rawX - workingArea.X;
var tmpY = rawY - workingArea.Y;

if (tmpX >= workingArea.Width)
{
CursorOverflowX += workingArea.Width;
tmpX = 0;
//tmpX = 0;
didSetPosition = true;
}
else if (tmpX <= 0)
{
CursorOverflowX -= workingArea.Width;
tmpX = workingArea.Width;
//tmpX = workingArea.Width;
didSetPosition = true;
}

if (tmpY >= workingArea.Height)
{
CursorOverflowY += workingArea.Height;
tmpY = 0;
//tmpY = 0;
didSetPosition = true;
}
else if (tmpY <= 0)
{
CursorOverflowY -= workingArea.Height;
tmpY = workingArea.Height;
//tmpY = workingArea.Height;
didSetPosition = true;
}

Expand Down
206 changes: 159 additions & 47 deletions PS4Macro/Classes/Remapping/RemapperUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,165 @@ namespace PS4Macro.Classes.Remapping
{
public class RemapperUtility
{
#region WindowInfo
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr FindWindow(string strClassName, string strWindowName);

[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam);

[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);

private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

private static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;

foreach (ProcessThread t in process.Threads)
{
windowHandle = FindWindowInThread(t.Id, compareTitle);
if (windowHandle != IntPtr.Zero)
{
break;
}
}

return windowHandle;
}

private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
return true;
}, IntPtr.Zero);

return windowHandle;
}

[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hwnd, ref RECT rectangle);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;

public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}

public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }

public int X
{
get { return Left; }
set { Right -= (Left - value); Left = value; }
}

public int Y
{
get { return Top; }
set { Bottom -= (Top - value); Top = value; }
}

public int Height
{
get { return Bottom - Top; }
set { Bottom = value + Top; }
}

public int Width
{
get { return Right - Left; }
set { Right = value + Left; }
}

public System.Drawing.Point Location
{
get { return new System.Drawing.Point(Left, Top); }
set { X = value.X; Y = value.Y; }
}

public System.Drawing.Size Size
{
get { return new System.Drawing.Size(Width, Height); }
set { Width = value.Width; Height = value.Height; }
}

public static implicit operator System.Drawing.Rectangle(RECT r)
{
return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
}

public static implicit operator RECT(System.Drawing.Rectangle r)
{
return new RECT(r);
}

public static bool operator ==(RECT r1, RECT r2)
{
return r1.Equals(r2);
}

public static bool operator !=(RECT r1, RECT r2)
{
return !r1.Equals(r2);
}

public bool Equals(RECT r)
{
return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
}

public override bool Equals(object obj)
{
if (obj is RECT)
return Equals((RECT)obj);
else if (obj is System.Drawing.Rectangle)
return Equals(new RECT((System.Drawing.Rectangle)obj));
return false;
}

public override int GetHashCode()
{
return ((System.Drawing.Rectangle)this).GetHashCode();
}

public override string ToString()
{
return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
}
}

public static Rectangle FindWindowLocation(Process process)
{
IntPtr handle = process.MainWindowHandle;
RECT rect = new RECT();
GetWindowRect(handle, ref rect);
return rect;
}
#endregion

#region SetCursorPosition
[DllImport("user32.dll")]
private static extern IntPtr SetCursorPos(int x, int y);
Expand Down Expand Up @@ -204,53 +363,6 @@ public static bool ShowSystemCursor(bool show)
[DllImport("User32")]
private static extern int ShowWindow(int hwnd, int nCmdShow);

[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool EnumThreadWindows(int threadId, EnumWindowsProc callback, IntPtr lParam);

[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);

private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

private static IntPtr FindWindowInProcess(Process process, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;

foreach (ProcessThread t in process.Threads)
{
windowHandle = FindWindowInThread(t.Id, compareTitle);
if (windowHandle != IntPtr.Zero)
{
break;
}
}

return windowHandle;
}

private static IntPtr FindWindowInThread(int threadId, Func<string, bool> compareTitle)
{
IntPtr windowHandle = IntPtr.Zero;
EnumThreadWindows(threadId, (hWnd, lParam) =>
{
StringBuilder text = new StringBuilder(200);
GetWindowText(hWnd, text, 200);
if (compareTitle(text.ToString()))
{
windowHandle = hWnd;
return false;
}
return true;
}, IntPtr.Zero);

return windowHandle;
}

public static void ShowStreamingToolBar(Process process, bool show)
{
IntPtr streamingToolBar = FindWindowInProcess(process, title => title.Equals("StreamingToolBar"));
Expand Down

0 comments on commit cf7ce2c

Please sign in to comment.