1
2
3
4
5 package oshi.hardware.platform.windows;
6
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13 import com.sun.jna.platform.win32.Advapi32;
14 import com.sun.jna.platform.win32.Guid;
15 import com.sun.jna.platform.win32.SetupApi;
16 import com.sun.jna.platform.win32.WinBase;
17 import com.sun.jna.platform.win32.WinError;
18 import com.sun.jna.platform.win32.WinNT;
19 import com.sun.jna.platform.win32.WinNT.HANDLE;
20 import com.sun.jna.platform.win32.WinReg.HKEY;
21
22 import oshi.annotation.concurrent.Immutable;
23 import oshi.hardware.Display;
24 import oshi.hardware.common.AbstractDisplay;
25 import oshi.jna.ByRef.CloseableIntByReference;
26 import oshi.jna.Struct.CloseableSpDeviceInterfaceData;
27 import oshi.jna.Struct.CloseableSpDevinfoData;
28
29
30
31
32 @Immutable
33 final class WindowsDisplay extends AbstractDisplay {
34
35 private static final Logger LOG = LoggerFactory.getLogger(WindowsDisplay.class);
36
37 private static final SetupApi SU = SetupApi.INSTANCE;
38 private static final Advapi32 ADV = Advapi32.INSTANCE;
39
40 private static final Guid.GUID GUID_DEVINTERFACE_MONITOR = new Guid.GUID("E6F07B5F-EE97-4a90-B076-33F57BF4EAA7");
41
42
43
44
45
46
47 WindowsDisplay(byte[] edid) {
48 super(edid);
49 LOG.debug("Initialized WindowsDisplay");
50 }
51
52
53
54
55
56
57 public static List<Display> getDisplays() {
58 List<Display> displays = new ArrayList<>();
59
60 HANDLE hDevInfo = SU.SetupDiGetClassDevs(GUID_DEVINTERFACE_MONITOR, null, null,
61 SetupApi.DIGCF_PRESENT | SetupApi.DIGCF_DEVICEINTERFACE);
62 if (!hDevInfo.equals(WinBase.INVALID_HANDLE_VALUE)) {
63 try (CloseableSpDeviceInterfaceData deviceInterfaceData = new CloseableSpDeviceInterfaceData();
64 CloseableSpDevinfoData info = new CloseableSpDevinfoData()) {
65 deviceInterfaceData.cbSize = deviceInterfaceData.size();
66
67 for (int memberIndex = 0; SU.SetupDiEnumDeviceInfo(hDevInfo, memberIndex, info); memberIndex++) {
68 HKEY key = SU.SetupDiOpenDevRegKey(hDevInfo, info, SetupApi.DICS_FLAG_GLOBAL, 0, SetupApi.DIREG_DEV,
69 WinNT.KEY_QUERY_VALUE);
70
71 byte[] edid = new byte[1];
72
73 try (CloseableIntByReference pType = new CloseableIntByReference();
74 CloseableIntByReference lpcbData = new CloseableIntByReference()) {
75 if (ADV.RegQueryValueEx(key, "EDID", 0, pType, edid, lpcbData) == WinError.ERROR_MORE_DATA) {
76 edid = new byte[lpcbData.getValue()];
77 if (ADV.RegQueryValueEx(key, "EDID", 0, pType, edid, lpcbData) == WinError.ERROR_SUCCESS) {
78 Display display = new WindowsDisplay(edid);
79 displays.add(display);
80 }
81 }
82 }
83 Advapi32.INSTANCE.RegCloseKey(key);
84 }
85 }
86 SU.SetupDiDestroyDeviceInfoList(hDevInfo);
87 }
88 return displays;
89 }
90 }