View Javadoc
1   /*
2    * Copyright 2016-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.mac;
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.Pointer;
14  import com.sun.jna.platform.mac.CoreFoundation.CFDataRef;
15  import com.sun.jna.platform.mac.CoreFoundation.CFStringRef;
16  import com.sun.jna.platform.mac.CoreFoundation.CFTypeRef;
17  import com.sun.jna.platform.mac.IOKit.IOIterator;
18  import com.sun.jna.platform.mac.IOKit.IORegistryEntry;
19  import com.sun.jna.platform.mac.IOKitUtil;
20  
21  import oshi.annotation.concurrent.Immutable;
22  import oshi.hardware.Display;
23  import oshi.hardware.common.AbstractDisplay;
24  
25  /**
26   * A Display
27   */
28  @Immutable
29  final class MacDisplay extends AbstractDisplay {
30  
31      private static final Logger LOG = LoggerFactory.getLogger(MacDisplay.class);
32  
33      /**
34       * Constructor for MacDisplay.
35       *
36       * @param edid a byte array representing a display EDID
37       */
38      MacDisplay(byte[] edid) {
39          super(edid);
40          LOG.debug("Initialized MacDisplay");
41      }
42  
43      /**
44       * Gets Display Information
45       *
46       * @return An array of Display objects representing monitors, etc.
47       */
48      public static List<Display> getDisplays() {
49          List<Display> displays = new ArrayList<>();
50          // Iterate IO Registry IODisplayConnect
51          IOIterator serviceIterator = IOKitUtil.getMatchingServices("IODisplayConnect");
52          if (serviceIterator != null) {
53              CFStringRef cfEdid = CFStringRef.createCFString("IODisplayEDID");
54              IORegistryEntry sdService = serviceIterator.next();
55              while (sdService != null) {
56                  // Display properties are in a child entry
57                  IORegistryEntry properties = sdService.getChildEntry("IOService");
58                  if (properties != null) {
59                      // look up the edid by key
60                      CFTypeRef edidRaw = properties.createCFProperty(cfEdid);
61                      if (edidRaw != null) {
62                          CFDataRef edid = new CFDataRef(edidRaw.getPointer());
63                          // Edid is a byte array of 128 bytes
64                          int length = edid.getLength();
65                          Pointer p = edid.getBytePtr();
66                          displays.add(new MacDisplay(p.getByteArray(0, length)));
67                          edid.release();
68                      }
69                      properties.release();
70                  }
71                  // iterate
72                  sdService.release();
73                  sdService = serviceIterator.next();
74              }
75              serviceIterator.release();
76              cfEdid.release();
77          }
78          return displays;
79      }
80  }