Skip to content

Commit

Permalink
Add support for HDR LUTs to GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
ledoge committed Nov 7, 2021
1 parent d8a1756 commit e313a2c
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 48 deletions.
21 changes: 15 additions & 6 deletions DwmLutGUI/DwmLutGUI/Injector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,29 @@ public static void Inject(IEnumerable<MonitorData> monitors)

foreach (var monitor in monitors)
{
if (string.IsNullOrEmpty(monitor.LutPath)) continue;
var path = LutsPath + monitor.Position.Replace(',', '_') + ".cube";
File.Copy(monitor.LutPath, path);
ClearPermissions(path);
if (!string.IsNullOrEmpty(monitor.SdrLutPath))
{
var path = LutsPath + monitor.Position.Replace(',', '_') + ".cube";
File.Copy(monitor.SdrLutPath, path);
ClearPermissions(path);
}

if (string.IsNullOrEmpty(monitor.HdrLutPath)) continue;
{
var path = LutsPath + monitor.Position.Replace(',', '_') + "_hdr.cube";
File.Copy(monitor.HdrLutPath, path);
ClearPermissions(path);
}
}

var failed = false;
var bytes = Encoding.ASCII.GetBytes(DllPath);
var dwmInstances = Process.GetProcessesByName("dwm");
foreach (var dwm in dwmInstances)
{
var address = VirtualAllocEx(dwm.Handle, IntPtr.Zero, (UIntPtr) bytes.Length,
var address = VirtualAllocEx(dwm.Handle, IntPtr.Zero, (UIntPtr)bytes.Length,
AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite);
WriteProcessMemory(dwm.Handle, address, bytes, (UIntPtr) bytes.Length, out _);
WriteProcessMemory(dwm.Handle, address, bytes, (UIntPtr)bytes.Length, out _);
var thread = CreateRemoteThread(dwm.Handle, IntPtr.Zero, 0, LoadlibraryA, address, 0, out _);
WaitForSingleObject(thread, uint.MaxValue);

Expand Down
97 changes: 77 additions & 20 deletions DwmLutGUI/DwmLutGUI/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class MainViewModel : INotifyPropertyChanged
private bool _isActive;

private readonly string _configPath;
private readonly Dictionary<uint, string> _config;
private readonly Dictionary<uint, string[]> _config;

public MainViewModel()
{
Expand All @@ -33,11 +33,12 @@ public MainViewModel()
{
var xElem = XElement.Load(_configPath);
_config = xElem.Descendants("monitor")
.ToDictionary(x => (uint) x.Attribute("id"), x => (string) x.Attribute("lut"));
.ToDictionary(x => (uint)x.Attribute("id"),
x => new[] { (string)x.Attribute("sdr_lut"), (string)x.Attribute("hdr_lut") });
}
else
{
_config = new Dictionary<uint, string>();
_config = new Dictionary<uint, string[]>();
}

Monitors = new ObservableCollection<MonitorData>();
Expand All @@ -64,35 +65,84 @@ public MonitorData SelectedMonitor
if (value == _selectedMonitor) return;
_selectedMonitor = value;
OnPropertyChanged();
OnPropertyChanged(nameof(LutPath));
OnPropertyChanged(nameof(SdrLutPath));
OnPropertyChanged(nameof(HdrLutPath));
}
get => _selectedMonitor;
}

public string LutPath
private void SaveConfig()
{
var xElem = new XElement("monitors",
_config.Select(x =>
new XElement("monitor", new XAttribute("id", x.Key),
x.Value[0] != null ? new XAttribute("sdr_lut", x.Value[0]) : null,
x.Value[1] != null ? new XAttribute("hdr_lut", x.Value[1]) : null)));
xElem.Save(_configPath);
}

public string SdrLutPath
{
set
{
if (SelectedMonitor == null || SelectedMonitor.LutPath == value) return;
SelectedMonitor.LutPath = value;
if (SelectedMonitor == null || SelectedMonitor.SdrLutPath == value) return;
SelectedMonitor.SdrLutPath = value;
OnPropertyChanged();

var key = SelectedMonitor.DeviceId;
if (!string.IsNullOrEmpty(value))
{
_config[key] = value;
if (!_config.ContainsKey(key))
{
_config[key] = new string[2];
}

_config[key][0] = value;
}
else
{
_config.Remove(key);
_config[key][0] = null;
if (_config[key][1] == null)
{
_config.Remove(key);
}
}

var xElem = new XElement("monitors",
_config.Select(x =>
new XElement("monitor", new XAttribute("id", x.Key), new XAttribute("lut", x.Value))));
xElem.Save(_configPath);
SaveConfig();
}
get => SelectedMonitor?.LutPath;
get => SelectedMonitor?.SdrLutPath;
}

public string HdrLutPath
{
set
{
if (SelectedMonitor == null || SelectedMonitor.HdrLutPath == value) return;
SelectedMonitor.HdrLutPath = value;
OnPropertyChanged();

var key = SelectedMonitor.DeviceId;
if (!string.IsNullOrEmpty(value))
{
if (!_config.ContainsKey(key))
{
_config[key] = new string[2];
}

_config[key][1] = value;
}
else
{
_config[key][1] = null;
if (_config[key][0] == null)
{
_config.Remove(key);
}
}

SaveConfig();
}
get => SelectedMonitor?.HdrLutPath;
}

public bool IsActive
Expand Down Expand Up @@ -136,14 +186,20 @@ public void UpdateMonitors()

var position = path.Position.X + "," + path.Position.Y;

string lutPath = null;
string sdrLutPath = null;
string hdrLutPath = null;
if (_config.ContainsKey(deviceId))
{
sdrLutPath = _config[deviceId][0];
}

if (_config.ContainsKey(deviceId))
{
lutPath = _config[deviceId];
hdrLutPath = _config[deviceId][1];
}

Monitors.Add(new MonitorData(deviceId, path.DisplaySource.SourceId + 1, name, resolution, refreshRate,
connector, position, lutPath));
connector, position, sdrLutPath, hdrLutPath));
}

if (selectedId == null) return;
Expand All @@ -158,7 +214,8 @@ public void UpdateMonitors()
public void ReInject()
{
Injector.Uninject();
if (!Monitors.All(monitor => string.IsNullOrEmpty(monitor.LutPath)))
if (!Monitors.All(monitor =>
string.IsNullOrEmpty(monitor.SdrLutPath) && string.IsNullOrEmpty(monitor.HdrLutPath)))
{
Injector.Inject(Monitors);
}
Expand All @@ -177,8 +234,8 @@ private void UpdateActiveStatus()
var status = Injector.GetStatus();
if (status != null)
{
IsActive = (bool) status;
ActiveText = (bool) status ? "Active" : "Inactive";
IsActive = (bool)status;
ActiveText = (bool)status ? "Active" : "Inactive";
}
else
{
Expand Down
32 changes: 24 additions & 8 deletions DwmLutGUI/DwmLutGUI/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DwmLutGUI"
mc:Ignorable="d"
Title="DwmLutGUI" Height="350" Width="525" MinHeight="150" MinWidth="300">
Title="DwmLutGUI" Height="400" Width="600" MinHeight="200" MinWidth="300">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
Expand All @@ -15,21 +15,36 @@
</StatusBar>
<DockPanel Margin="6">
<Grid DockPanel.Dock="Top" Margin="0,0,0,6">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="LUT file:" />
<TextBlock Margin="0,0,0,6" Text="SDR LUT:" />
<TextBox IsEnabled="{Binding SelectedMonitor, TargetNullValue=false}"
Text="{Binding LutPath, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"
Text="{Binding SdrLutPath, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"
Grid.Row="0" Grid.Column="1" Width="Auto" Margin="6,0,6,6" />
<Button IsEnabled="{Binding SelectedMonitor, TargetNullValue=false}" Grid.Row="0" Grid.Column="2"
Content="Browse..."
Width="75" Margin="0,0,6,6" VerticalAlignment="Bottom" Click="SdrLutBrowse_Click" />
<Button IsEnabled="{Binding SdrLutPath, TargetNullValue=false}" Grid.Row="0" Grid.Column="3"
Content="Clear"
Width="75" Margin="0,0,0,6" Click="SdrLutClear_Click" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="HDR LUT:" />
<TextBox Grid.Row="1" IsEnabled="{Binding SelectedMonitor, TargetNullValue=false}"
Text="{Binding HdrLutPath, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"
Grid.Column="1" Width="Auto" Margin="6,0,6,0" />
<Button IsEnabled="{Binding SelectedMonitor, TargetNullValue=false}" Grid.Column="2"
<Button Grid.Row="1" IsEnabled="{Binding SelectedMonitor, TargetNullValue=false}" Grid.Column="2"
Content="Browse..."
Width="75" Margin="0,0,6,0" VerticalAlignment="Bottom" Click="LutBrowse_Click" />
<Button IsEnabled="{Binding LutPath, TargetNullValue=false}" Grid.Column="3" Content="Clear"
Width="75" Click="LutClear_Click" />
Width="75" Margin="0,0,6,0" VerticalAlignment="Bottom" Click="HdrLutBrowse_Click" />
<Button Grid.Row="1" IsEnabled="{Binding HdrLutPath, TargetNullValue=false}" Grid.Column="3"
Content="Clear"
Width="75" Click="HdrLutClear_Click" />
</Grid>
<Grid DockPanel.Dock="Bottom">
<Button Content="Refresh" Width="75" HorizontalAlignment="Left"
Expand All @@ -50,7 +65,8 @@
<DataGridTextColumn Header="Refresh rate" Binding="{Binding RefreshRate}" />
<DataGridTextColumn Header="Connector" Binding="{Binding Connector}" />
<DataGridTextColumn Header="Position" Binding="{Binding Position}" />
<DataGridTextColumn Header="LUT file" Width="*" Binding="{Binding LutFilename}">
<DataGridTextColumn Header="SDR LUT" Width="*" Binding="{Binding SdrLutFilename}" />
<DataGridTextColumn Header="HDR LUT" Width="*" Binding="{Binding HdrLutFilename}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Margin" Value="0,0,-1,0" />
Expand Down
24 changes: 19 additions & 5 deletions DwmLutGUI/DwmLutGUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class MainWindow
public MainWindow()
{
InitializeComponent();
_viewModel = (MainViewModel) DataContext;
_viewModel = (MainViewModel)DataContext;
_applyOnCooldown = false;
}

Expand All @@ -34,18 +34,32 @@ private void MonitorRefreshButton_Click(object sender, System.Windows.RoutedEven
_viewModel.UpdateMonitors();
}

private void LutBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
private void SdrLutBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
{
var lutPath = BrowseLuts();
if (!string.IsNullOrEmpty(lutPath))
{
_viewModel.LutPath = lutPath;
_viewModel.SdrLutPath = lutPath;
}
}

private void LutClear_Click(object sender, System.Windows.RoutedEventArgs e)
private void SdrLutClear_Click(object sender, System.Windows.RoutedEventArgs e)
{
_viewModel.LutPath = null;
_viewModel.SdrLutPath = null;
}

private void HdrLutBrowse_Click(object sender, System.Windows.RoutedEventArgs e)
{
var lutPath = BrowseLuts();
if (!string.IsNullOrEmpty(lutPath))
{
_viewModel.HdrLutPath = lutPath;
}
}

private void HdrLutClear_Click(object sender, System.Windows.RoutedEventArgs e)
{
_viewModel.HdrLutPath = null;
}

private void Disable_Click(object sender, System.Windows.RoutedEventArgs e)
Expand Down
33 changes: 24 additions & 9 deletions DwmLutGUI/DwmLutGUI/MonitorData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ public class MonitorData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private string _lutPath;
private string _sdrLutPath;
private string _hdrLutPath;

public MonitorData(uint deviceId, uint sourceId, string name, string resolution, string refreshRate,
string connector, string position, string lutPath)
string connector, string position, string sdrLutPath, string hdrLutPath)
{
DeviceId = deviceId;
SourceId = sourceId;
Expand All @@ -19,7 +20,8 @@ public MonitorData(uint deviceId, uint sourceId, string name, string resolution,
RefreshRate = refreshRate;
Connector = connector;
Position = position;
LutPath = lutPath;
SdrLutPath = sdrLutPath;
HdrLutPath = hdrLutPath;
}

public uint DeviceId { get; }
Expand All @@ -30,17 +32,30 @@ public MonitorData(uint deviceId, uint sourceId, string name, string resolution,
public string Connector { get; }
public string Position { get; }

public string LutPath
public string SdrLutPath
{
set
{
if (value == _lutPath) return;
_lutPath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LutFilename)));
if (value == _sdrLutPath) return;
_sdrLutPath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SdrLutFilename)));
}
get => _lutPath;
get => _sdrLutPath;
}

public string LutFilename => Path.GetFileName(LutPath) ?? "None";
public string HdrLutPath
{
set
{
if (value == _hdrLutPath) return;
_hdrLutPath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HdrLutFilename)));
}
get => _hdrLutPath;
}

public string SdrLutFilename => Path.GetFileName(SdrLutPath) ?? "None";

public string HdrLutFilename => Path.GetFileName(HdrLutPath) ?? "None";
}
}

0 comments on commit e313a2c

Please sign in to comment.