| // Copyright (c) Microsoft Corporation |
| |
| #ifndef THIRD_PARTY_WIN_VIRTUAL_DISPLAY_DRIVER_EDID_H_ |
| #define THIRD_PARTY_WIN_VIRTUAL_DISPLAY_DRIVER_EDID_H_ |
| |
| #include <algorithm> |
| #include <array> |
| |
| namespace display::test { |
| |
| // Bytes 38-53 of an EDID (v1.4) blob contains timing information as a list of 8 |
| // 2-byte structures. The following structure represents a single record which |
| // consists of: X resolution, aspect ratio and vertical frequency. See: |
| // https://en.wikipedia.org/wiki/Extended_Display_Identification_Data |
| class EdidTimingEntry { |
| public: |
| // Sets the mode of this timing entry. Returns true on success, false |
| // otherwise. Based on EDID restrictions the following constraints exist: |
| // `width` should be between 256 and 2288. |
| // `height` should maintain an aspect ratio (width:height) of 16:10, 4:3, |
| // 5:4, 16:9. |
| // `freq` should be between 60 and 123. |
| bool SetMode(unsigned short width, |
| unsigned short height, |
| unsigned short freq); |
| // Get the width (in pixels) of the currently set mode. |
| int GetWidth(); |
| // Get the height (in pixels) of the currently set mode. |
| int GetHeight(); |
| // Get the vertical frequency (in pixels) of the currently set mode. |
| int GetVerticalFrequency(); |
| |
| private: |
| unsigned char x_pixels; |
| unsigned char aspect_ratio : 2; |
| unsigned char vertical_frequency : 6; |
| }; |
| |
| // Wrapper for a 128 byte EDID block with some basic support for extracting |
| // (Standard) timing information structures. |
| class Edid { |
| public: |
| // EDID block size (based on version 1.4). |
| static constexpr size_t kBlockSize = 128; |
| |
| explicit Edid(const Edid& other) = delete; |
| // Copying an existing blob of data. |
| explicit Edid(unsigned char edidData[kBlockSize]) { |
| std::copy_n(edidData, kBlockSize, edidBlock.begin()); |
| } |
| |
| const std::array<unsigned char, kBlockSize>& getEdidBlock() const { |
| return edidBlock; |
| } |
| |
| // Return a specified timing entry (Standard timing information; EDID 1.4). |
| // There are 8 entries. `entry` should be in in the range [0,8). |
| EdidTimingEntry* GetTimingEntry(int entry); |
| |
| // Set the 16-bit manufacturer product code (EDID 1.4). |
| void SetProductCode(uint16_t code); |
| |
| // Set the 32-bit serial number (EDID 1.4). |
| void SetSerialNumber(uint32_t serial); |
| |
| // Updates the checksum byte to be valid. |
| void UpdateChecksum(); |
| |
| private: |
| std::array<unsigned char, kBlockSize> edidBlock; |
| }; |
| |
| } // namespace display::test |
| |
| #endif // THIRD_PARTY_WIN_VIRTUAL_DISPLAY_DRIVER_EDID_H_ |