Merge pull request #481 from UbbeLoL/master

Remote desktop can now wake a client up from an active screensaver
This commit is contained in:
MaxXor 2016-07-14 19:39:42 +02:00 committed by GitHub
commit 14d9f5989c
3 changed files with 122 additions and 9 deletions

View File

@ -112,6 +112,19 @@ namespace xClient.Core.Commands
int offsetY = allScreens[command.MonitorIndex].Bounds.Y;
Point p = new Point(command.X + offsetX, command.Y + offsetY);
// Disable screensaver if active before input
switch (command.Action)
{
case MouseAction.LeftDown:
case MouseAction.LeftUp:
case MouseAction.RightDown:
case MouseAction.RightUp:
case MouseAction.MoveCursor:
if (NativeMethodsHelper.IsScreensaverActive())
NativeMethodsHelper.DisableScreensaver();
break;
}
switch (command.Action)
{
case MouseAction.LeftDown:
@ -140,6 +153,9 @@ namespace xClient.Core.Commands
public static void HandleDoKeyboardEvent(Packets.ServerPackets.DoKeyboardEvent command, Client client)
{
if (NativeMethodsHelper.IsScreensaverActive())
NativeMethodsHelper.DisableScreensaver();
NativeMethodsHelper.DoKeyPress(command.Key, command.KeyDown);
}

View File

@ -1,4 +1,5 @@
using System.Drawing;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using xClient.Core.Utilities;
@ -17,7 +18,7 @@ namespace xClient.Core.Helper
public static uint GetLastInputInfoTickCount()
{
NativeMethods.LASTINPUTINFO lastInputInfo = new NativeMethods.LASTINPUTINFO();
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
lastInputInfo.cbSize = (uint) Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
return NativeMethods.GetLastInputInfo(ref lastInputInfo) ? lastInputInfo.dwTime : 0;
@ -47,5 +48,64 @@ namespace xClient.Core.Helper
{
NativeMethods.keybd_event(key, 0, keyDown ? KEYEVENTF_KEYDOWN : KEYEVENTF_KEYUP, 0);
}
private const int SPI_GETSCREENSAVERRUNNING = 114;
public static bool IsScreensaverActive()
{
var running = IntPtr.Zero;
if (!NativeMethods.SystemParametersInfo(
SPI_GETSCREENSAVERRUNNING,
0,
ref running,
0))
{
// Something went wrong (Marshal.GetLastWin32Error)
}
return running != IntPtr.Zero;
}
private const uint DESKTOP_WRITEOBJECTS = 0x0080;
private const uint DESKTOP_READOBJECTS = 0x0001;
private const int WM_CLOSE = 16;
private const uint SPI_SETSCREENSAVEACTIVE = 0x0011;
private const uint SPIF_SENDWININICHANGE = 0x0002;
public static void DisableScreensaver()
{
var handle = NativeMethods.OpenDesktop("Screen-saver", 0,
false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
if (handle != IntPtr.Zero)
{
NativeMethods.EnumDesktopWindows(handle, (hWnd, lParam) =>
{
if (NativeMethods.IsWindowVisible(hWnd))
NativeMethods.PostMessage(hWnd, WM_CLOSE, 0, 0);
// Continue enumeration even if it fails
return true;
},
IntPtr.Zero);
NativeMethods.CloseDesktop(handle);
}
else
{
NativeMethods.PostMessage(NativeMethods.GetForegroundWindow(), WM_CLOSE,
0, 0);
}
// We need to restart the counter for next screensaver according to
// https://support.microsoft.com/en-us/kb/140723
// (this may not be needed since we simulate mouse click afterwards)
var dummy = IntPtr.Zero;
// Doesn't really matter if this fails
NativeMethods.SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1 /* TRUE */, ref dummy, SPIF_SENDWININICHANGE);
}
}
}

View File

@ -12,10 +12,8 @@ namespace xClient.Core.Utilities
public struct LASTINPUTINFO
{
public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
[MarshalAs(UnmanagedType.U4)]
public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime;
[MarshalAs(UnmanagedType.U4)] public UInt32 cbSize;
[MarshalAs(UnmanagedType.U4)] public UInt32 dwTime;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
@ -23,11 +21,11 @@ namespace xClient.Core.Utilities
public static extern bool DeleteFile(string name);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule,
[MarshalAs(UnmanagedType.LPStr)]string procName);
[MarshalAs(UnmanagedType.LPStr)] string procName);
[DllImport("user32.dll")]
public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
@ -60,7 +58,8 @@ namespace xClient.Core.Utilities
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
public static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight,
[In] IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);
@ -79,5 +78,43 @@ namespace xClient.Core.Utilities
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe int memcpy(void* dst, void* src, uint count);
[DllImport("user32.dll")]
public static extern bool SystemParametersInfo(
uint uAction, uint uParam, ref IntPtr lpvParam,
uint flags);
[DllImport("user32.dll")]
public static extern bool SystemParametersInfo(
uint uAction, uint uParam, ref bool lpvParam,
uint flags);
[DllImport("user32.dll")]
public static extern int PostMessage(IntPtr hWnd,
int wMsg, int wParam, int lParam);
[DllImport("user32.dll")]
public static extern IntPtr OpenDesktop(
string hDesktop, int flags, bool inherit,
uint desiredAccess);
[DllImport("user32.dll")]
public static extern bool CloseDesktop(
IntPtr hDesktop);
public delegate bool EnumDesktopWindowsProc(
IntPtr hDesktop, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool EnumDesktopWindows(
IntPtr hDesktop, EnumDesktopWindowsProc callback,
IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool IsWindowVisible(
IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
}