151 lines
4.2 KiB
C#
151 lines
4.2 KiB
C#
/*
|
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using Microsoft.Win32;
|
|
using SafeExamBrowser.Logging.Contracts;
|
|
using SafeExamBrowser.Monitoring.Contracts.Display;
|
|
using SafeExamBrowser.Monitoring.Contracts.Display.Events;
|
|
using SafeExamBrowser.SystemComponents.Contracts;
|
|
using SafeExamBrowser.WindowsApi.Contracts;
|
|
using OperatingSystem = SafeExamBrowser.SystemComponents.Contracts.OperatingSystem;
|
|
|
|
namespace SafeExamBrowser.Monitoring.Display
|
|
{
|
|
public class DisplayMonitor : IDisplayMonitor
|
|
{
|
|
private IBounds originalWorkingArea;
|
|
private ILogger logger;
|
|
private INativeMethods nativeMethods;
|
|
private ISystemInfo systemInfo;
|
|
private string wallpaper;
|
|
|
|
public event DisplayChangedEventHandler DisplayChanged;
|
|
|
|
public DisplayMonitor(ILogger logger, INativeMethods nativeMethods, ISystemInfo systemInfo)
|
|
{
|
|
this.logger = logger;
|
|
this.nativeMethods = nativeMethods;
|
|
this.systemInfo = systemInfo;
|
|
}
|
|
|
|
public void InitializePrimaryDisplay(int taskbarHeight)
|
|
{
|
|
InitializeWorkingArea(taskbarHeight);
|
|
InitializeWallpaper();
|
|
}
|
|
|
|
public void PreventSleepMode()
|
|
{
|
|
nativeMethods.PreventSleepMode();
|
|
logger.Info("Disabled sleep mode and display timeout.");
|
|
}
|
|
|
|
public void ResetPrimaryDisplay()
|
|
{
|
|
ResetWorkingArea();
|
|
ResetWallpaper();
|
|
}
|
|
|
|
public void StartMonitoringDisplayChanges()
|
|
{
|
|
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
|
logger.Info("Started monitoring display changes.");
|
|
}
|
|
|
|
public void StopMonitoringDisplayChanges()
|
|
{
|
|
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
|
|
logger.Info("Stopped monitoring display changes.");
|
|
}
|
|
|
|
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
|
{
|
|
logger.Info("Display change detected!");
|
|
Task.Run(() => DisplayChanged?.Invoke());
|
|
}
|
|
|
|
private void InitializeWorkingArea(int taskbarHeight)
|
|
{
|
|
var identifier = GetIdentifierForPrimaryDisplay();
|
|
|
|
if (originalWorkingArea == null)
|
|
{
|
|
originalWorkingArea = nativeMethods.GetWorkingArea();
|
|
LogWorkingArea($"Saved original working area for {identifier}", originalWorkingArea);
|
|
}
|
|
|
|
var area = new Bounds
|
|
{
|
|
Left = 0,
|
|
Top = 0,
|
|
Right = Screen.PrimaryScreen.Bounds.Width,
|
|
Bottom = Screen.PrimaryScreen.Bounds.Height - taskbarHeight
|
|
};
|
|
|
|
LogWorkingArea($"Trying to set new working area for {identifier}", area);
|
|
nativeMethods.SetWorkingArea(area);
|
|
LogWorkingArea($"Working area of {identifier} is now set to", nativeMethods.GetWorkingArea());
|
|
}
|
|
|
|
private void InitializeWallpaper()
|
|
{
|
|
if (systemInfo.OperatingSystem == OperatingSystem.Windows7)
|
|
{
|
|
var path = nativeMethods.GetWallpaperPath();
|
|
|
|
if (!String.IsNullOrEmpty(path))
|
|
{
|
|
wallpaper = path;
|
|
logger.Info($"Saved wallpaper image: {wallpaper}.");
|
|
}
|
|
|
|
nativeMethods.RemoveWallpaper();
|
|
logger.Info("Removed current wallpaper.");
|
|
}
|
|
}
|
|
|
|
private void ResetWorkingArea()
|
|
{
|
|
var identifier = GetIdentifierForPrimaryDisplay();
|
|
|
|
if (originalWorkingArea != null)
|
|
{
|
|
nativeMethods.SetWorkingArea(originalWorkingArea);
|
|
LogWorkingArea($"Restored original working area for {identifier}", originalWorkingArea);
|
|
}
|
|
else
|
|
{
|
|
logger.Warn($"Could not restore original working area for {identifier}!");
|
|
}
|
|
}
|
|
|
|
private void ResetWallpaper()
|
|
{
|
|
if (systemInfo.OperatingSystem == OperatingSystem.Windows7 && !String.IsNullOrEmpty(wallpaper))
|
|
{
|
|
nativeMethods.SetWallpaper(wallpaper);
|
|
logger.Info($"Restored wallpaper image: {wallpaper}.");
|
|
}
|
|
}
|
|
|
|
private string GetIdentifierForPrimaryDisplay()
|
|
{
|
|
var display = Screen.PrimaryScreen.DeviceName?.Replace(@"\\.\", string.Empty);
|
|
|
|
return $"{display} ({Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height})";
|
|
}
|
|
|
|
private void LogWorkingArea(string message, IBounds area)
|
|
{
|
|
logger.Info($"{message}: Left = {area.Left}, Top = {area.Top}, Right = {area.Right}, Bottom = {area.Bottom}.");
|
|
}
|
|
}
|
|
}
|