Internal screen detection

This commit is contained in:
Serge
2023-08-18 18:15:12 +02:00
parent 584755ea93
commit 190786a15a
2 changed files with 132 additions and 28 deletions

View File

@@ -1,4 +1,6 @@
using System.ComponentModel; using GHelper.Helpers;
using NvAPIWrapper.Display;
using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace GHelper.Display namespace GHelper.Display
@@ -259,6 +261,49 @@ namespace GHelper.Display
#endregion #endregion
[Flags]
public enum DisplayDeviceStates : int
{
ATTACHED_TO_DESKTOP = 0x01,
PRIMARY_DEVICE = 0x04,
MIRRORING_DRIVER = 0x08,
VGA_COMPATIBLE = 0x10,
REMOVABLE = 0x20,
DISCONNECTED = 0x2000000,
REMOTE = 0x4000000,
MODESPRUNED = 0x8000000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPLAY_DEVICE
{
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceString;
public DisplayDeviceStates StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceKey;
}
[DllImport(nameof(User32), CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool EnumDisplayDevices(
string? lpDevice,
uint iDevNum,
ref DISPLAY_DEVICE lpDisplayDevice,
uint dwFlags);
private static DISPLAYCONFIG_TARGET_DEVICE_NAME DeviceName(LUID adapterId, uint targetId) private static DISPLAYCONFIG_TARGET_DEVICE_NAME DeviceName(LUID adapterId, uint targetId)
{ {
var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME
@@ -298,6 +343,33 @@ namespace GHelper.Display
} }
public static IEnumerable<DISPLAY_DEVICE> GetDisplayDevices()
{
var displayAdapter = new DISPLAY_DEVICE();
displayAdapter.cb = Marshal.SizeOf<DISPLAY_DEVICE>();
var displayAdapterNumber = default(uint);
while (EnumDisplayDevices(null, displayAdapterNumber, ref displayAdapter, 1))
{
var displayMonitor = new DISPLAY_DEVICE();
displayMonitor.cb = Marshal.SizeOf<DISPLAY_DEVICE>();
var displayMonitorNumber = default(uint);
while (EnumDisplayDevices(displayAdapter.DeviceName, displayMonitorNumber, ref displayMonitor, 1))
{
var isAttached = (displayMonitor.StateFlags & DisplayDeviceStates.ATTACHED_TO_DESKTOP) == DisplayDeviceStates.ATTACHED_TO_DESKTOP;
var isMirroring = (displayMonitor.StateFlags & DisplayDeviceStates.MIRRORING_DRIVER) == DisplayDeviceStates.MIRRORING_DRIVER;
if (isAttached && !isMirroring) yield return displayMonitor;
displayMonitorNumber++;
}
displayAdapterNumber++;
}
}
} }
} }

View File

@@ -1,5 +1,8 @@
using System.Collections; using Microsoft.VisualBasic.Logging;
using System.Collections;
using System.Diagnostics.Metrics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms;
using static GHelper.Display.ScreenInterrogatory; using static GHelper.Display.ScreenInterrogatory;
namespace GHelper.Display namespace GHelper.Display
@@ -145,20 +148,12 @@ namespace GHelper.Display
public const int ENUM_CURRENT_SETTINGS = -1; public const int ENUM_CURRENT_SETTINGS = -1;
public const string defaultDevice = @"\\.\DISPLAY1"; public const string defaultDevice = @"\\.\DISPLAY1";
public static string? FindLaptopScreen(bool log = false)
{
string? laptopScreen = null;
var screens = Screen.AllScreens;
private static string? FindInternalName(bool log = false)
{
try try
{ {
var devices = GetAllDevices().ToArray(); var devices = GetAllDevices().ToArray();
Array.Sort(devices, new DeviceComparer());
Array.Sort(screens, new ScreenComparer());
int count = 0;
string internalName = AppConfig.GetString("internal_display"); string internalName = AppConfig.GetString("internal_display");
foreach (var device in devices) foreach (var device in devices)
@@ -167,31 +162,68 @@ namespace GHelper.Display
device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED || device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED ||
device.monitorFriendlyDeviceName == internalName) device.monitorFriendlyDeviceName == internalName)
{ {
if (log) Logger.WriteLine(device.monitorDevicePath + " " + device.outputTechnology);
AppConfig.Set("internal_display", device.monitorFriendlyDeviceName); AppConfig.Set("internal_display", device.monitorFriendlyDeviceName);
var names = device.monitorDevicePath.Split("#");
if (count < screens.Length) return names[1];
{
laptopScreen = screens[count].DeviceName;
}
else
{
laptopScreen = defaultDevice;
}
} }
if (log) Logger.WriteLine(device.monitorFriendlyDeviceName + ":" + device.outputTechnology.ToString() + device.connectorInstance.ToString() + ": " + ((count < screens.Length) ? screens[count].DeviceName : ""));
count++;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.WriteLine(ex.ToString()); Logger.WriteLine(ex.ToString());
Logger.WriteLine("Can't detect internal screen");
laptopScreen = Screen.PrimaryScreen.DeviceName;
} }
return null;
}
static string ExtractDisplay(string input)
{
int index = input.IndexOf('\\', 4); // Start searching from index 4 to skip ""
if (index != -1)
{
string extracted = input.Substring(0, index);
return extracted;
}
return input;
}
public static string? FindLaptopScreen(bool log = false)
{
string? laptopScreen = null;
string? internalName = FindInternalName(log);
if (internalName == null)
{
Logger.WriteLine("Internal screen off");
return null;
}
try
{
var displays = GetDisplayDevices().ToArray();
foreach (var display in displays)
{
if (log) Logger.WriteLine(display.DeviceID + " " + display.DeviceName);
if (display.DeviceID.Contains(internalName))
{
laptopScreen = ExtractDisplay(display.DeviceName);
break;
}
}
}
catch (Exception ex)
{
Logger.WriteLine(ex.ToString());
}
if (laptopScreen is null)
{
Logger.WriteLine("Default internal screen");
laptopScreen = Screen.PrimaryScreen.DeviceName;
}
return laptopScreen; return laptopScreen;
} }