Skip to content

Commit

Permalink
Merge pull request #1 from tombayley/feature/ddc
Browse files Browse the repository at this point in the history
Feature/ddc
  • Loading branch information
tombayley authored Dec 13, 2023
2 parents fbe183d + a0f9d84 commit 224060a
Show file tree
Hide file tree
Showing 35 changed files with 1,388 additions and 140 deletions.
2 changes: 1 addition & 1 deletion Installer/Installer.iss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define AppName "Night Glow"
#define AppExe "NightGlow.exe"
#define AppVersion "1.1.0"
#define AppVersion "2.0.0"

[Setup]
AppId={{8B87A5F9-0C03-4B92-9080-DDCF75DC18A4}
Expand Down
21 changes: 21 additions & 0 deletions NightGlow.MonitorConfig/Monitors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace NightGlow.MonitorConfig;

public class Monitors
{

public List<VirtualMonitor> VirtualMonitors = new List<VirtualMonitor>();

public bool Scan()
{
VirtualMonitors.Clear();
bool success = WinApi.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumCallback, IntPtr.Zero);
return success;
}

private bool MonitorEnumCallback(IntPtr hMonitor, IntPtr hdcMonitor, ref WinApi.RECT lprcMonitor, IntPtr dwData)
{
VirtualMonitors.Add(new VirtualMonitor(hMonitor, VirtualMonitors.Count));
return true;
}

}
9 changes: 9 additions & 0 deletions NightGlow.MonitorConfig/NightGlow.MonitorConfig.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
77 changes: 77 additions & 0 deletions NightGlow.MonitorConfig/PhysicalMonitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System.Diagnostics;
using static NightGlow.MonitorConfig.WinApi;

namespace NightGlow.MonitorConfig;

public class PhysicalMonitor
{

// Sometimes setting/getting monitor settings can fail. Retry this many times before assuming failure.
private const int DDC_ATTEMPTS = 3;

PHYSICAL_MONITOR Monitor;

public string Description;

private readonly Setting Brightness = new();
private readonly Setting Contrast = new();

public PhysicalMonitor(PHYSICAL_MONITOR monitor)
{
Monitor = monitor;
Description = new string(Monitor.szPhysicalMonitorDescription);
}

public Setting GetBrightness()
{
bool success = RetryGet((monitor) => GetMonitorBrightness(
monitor, out Brightness.Min, out Brightness.Current, out Brightness.Max), Monitor.hPhysicalMonitor
);
return Brightness;
}

public void SetBrightness(uint value)
{
bool success = RetrySet(SetMonitorBrightness, Monitor.hPhysicalMonitor, value);
if (success)
Brightness.Current = value;
}

public Setting GetContrast()
{
bool success = RetryGet((monitor) => GetMonitorContrast(
monitor, out Contrast.Min, out Contrast.Current, out Contrast.Max), Monitor.hPhysicalMonitor
);
return Contrast;
}

public void SetContrast(uint value)
{
bool success = RetrySet(SetMonitorContrast, Monitor.hPhysicalMonitor, value);
if (success)
Contrast.Current = value;
}

private bool RetrySet(Func<nint, uint, bool> function, nint monitor, uint value)
{
int attempt = 1;
while (attempt <= DDC_ATTEMPTS)
{
if (function(monitor, value)) return true;
attempt++;
}
return false;
}

private bool RetryGet(Func<nint, bool> function, nint monitor)
{
int attempt = 1;
while (attempt <= DDC_ATTEMPTS)
{
if (function(monitor)) return true;
attempt++;
}
return false;
}

}
24 changes: 24 additions & 0 deletions NightGlow.MonitorConfig/Setting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace NightGlow.MonitorConfig;

public class Setting
{

public uint Min;
public uint Max;
public uint Current;

public Setting()
{
Min = 0;
Max = 0;
Current = 0;
}

public Setting(uint min, uint max, uint current)
{
Min = min;
Max = max;
Current = current;
}

}
106 changes: 106 additions & 0 deletions NightGlow.MonitorConfig/VirtualMonitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using static NightGlow.MonitorConfig.WinApi;

namespace NightGlow.MonitorConfig;

public class VirtualMonitor
{

public string DeviceName = "";
public string FriendlyName = "";

public List<PhysicalMonitor> PhysicalMonitors = new();

private MONITORINFOEX MonitorInfo;

public VirtualMonitor(IntPtr hMonitor, int index)
{
MonitorInfo = new MONITORINFOEX { cbSize = (uint)Marshal.SizeOf<MONITORINFOEX>() };

if (!GetMonitorInfo(hMonitor, ref MonitorInfo))
{
// TODO throw error or log
Debug.WriteLine("Error: GetMonitorInfo");
}

DeviceName = MonitorInfo.szDevice;

LoadFriendlyName(index);

GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, out uint physicalMonitorCount);
if (physicalMonitorCount == 0)
return;

PHYSICAL_MONITOR[] physicalMonitorArray = new PHYSICAL_MONITOR[physicalMonitorCount];
GetPhysicalMonitorsFromHMONITOR(hMonitor, physicalMonitorCount, physicalMonitorArray);

for (int i = 0; i < physicalMonitorCount; i++)
{
PhysicalMonitors.Add(new PhysicalMonitor(physicalMonitorArray[i]));
}
}

public bool IsPrimary()
{
return (MonitorInfo.dwFlags & MONITORINFOF.MONITORINFOF_PRIMARY) == MONITORINFOF.MONITORINFOF_PRIMARY;
}

private void LoadFriendlyName(int index)
{
FriendlyName = "";

uint pathCount = 0, modeCount = 0;

long error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
ref pathCount, ref modeCount);
if (error != ERROR_SUCCESS)
{
// TODO throw error or log
Debug.WriteLine("Error: GetDisplayConfigBufferSizes");
return;
}

DISPLAYCONFIG_PATH_INFO[] displayPaths = new DISPLAYCONFIG_PATH_INFO[pathCount];
DISPLAYCONFIG_MODE_INFO[] displayModes = new DISPLAYCONFIG_MODE_INFO[modeCount];

error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
if (error != ERROR_SUCCESS)
{
// TODO throw error or log
Debug.WriteLine("Error: QueryDisplayConfig");
return;
}

int modeTargetCount = 0;
for (int i = 0; i < modeCount; i++)
{
if (displayModes[i].infoType != DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
continue;

if (modeTargetCount != index)
{
modeTargetCount++;
continue;
}

DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME();
deviceName.header.size = (uint)Marshal.SizeOf(typeof(DISPLAYCONFIG_TARGET_DEVICE_NAME));
deviceName.header.adapterId = displayModes[i].adapterId;
deviceName.header.id = displayModes[i].id;
deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;

error = DisplayConfigGetDeviceInfo(ref deviceName);
if (error != ERROR_SUCCESS)
{
// TODO throw error or log
Debug.WriteLine("Error: DisplayConfigGetDeviceInfo");
return;
}
FriendlyName = deviceName.monitorFriendlyDeviceName;
return;
}
}

}
Loading

0 comments on commit 224060a

Please sign in to comment.