1 #ifndef DI_DISPLAYID_H 2 #define DI_DISPLAYID_H 3 4 /** 5 * libdisplay-info's low-level API for VESA Display Identification Data 6 * (DisplayID). 7 * 8 * The library implements DisplayID version 1.3, available at: 9 * https://vesa.org/vesa-standards/ 10 */ 11 12 #include <stdbool.h> 13 #include <stdint.h> 14 15 /** 16 * DisplayID data structure. 17 */ 18 struct di_displayid; 19 20 /** 21 * Get the DisplayID version. 22 */ 23 int 24 di_displayid_get_version(const struct di_displayid *displayid); 25 26 /** 27 * Get the DisplayID revision. 28 */ 29 int 30 di_displayid_get_revision(const struct di_displayid *displayid); 31 32 /** 33 * Product type identifier, defined in section 2.3. 34 */ 35 enum di_displayid_product_type { 36 /* Extension section */ 37 DI_DISPLAYID_PRODUCT_TYPE_EXTENSION = 0x00, 38 /* Test structure or equipment */ 39 DI_DISPLAYID_PRODUCT_TYPE_TEST = 0x01, 40 /* Display panel or other transducer, LCD or PDP module, etc. */ 41 DI_DISPLAYID_PRODUCT_TYPE_DISPLAY_PANEL = 0x02, 42 /* Standalone display device, desktop monitor, TV monitor, etc. */ 43 DI_DISPLAYID_PRODUCT_TYPE_STANDALONE_DISPLAY = 0x03, 44 /* Television receiver */ 45 DI_DISPLAYID_PRODUCT_TYPE_TV_RECEIVER = 0x04, 46 /* Repeater/translator */ 47 DI_DISPLAYID_PRODUCT_TYPE_REPEATER = 0x05, 48 /* Direct drive monitor */ 49 DI_DISPLAYID_PRODUCT_TYPE_DIRECT_DRIVE = 0x06, 50 }; 51 52 /** 53 * Get the DisplayID product type. 54 */ 55 enum di_displayid_product_type 56 di_displayid_get_product_type(const struct di_displayid *displayid); 57 58 /** 59 * DisplayID data block tag. 60 */ 61 enum di_displayid_data_block_tag { 62 /*Product Identification Data Block */ 63 DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID = 0x00, 64 /* Display Parameters Data Block */ 65 DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS = 0x01, 66 /* Color Characteristics Data Block */ 67 DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT = 0x02, 68 /* Video Timing Modes Type I - Detailed Timings Data Block */ 69 DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING = 0x03, 70 /* Video Timing Modes Type II - Detailed Timings Data Block */ 71 DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING = 0x04, 72 /* Video Timing Modes Type III - Short Timings Data Block */ 73 DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING = 0x05, 74 /* Video Timing Modes Type IV - DMT Timings Data Block */ 75 DI_DISPLAYID_DATA_BLOCK_TYPE_IV_TIMING = 0x06, 76 /* Supported Timing Modes - VESA DMT Timings Data Block */ 77 DI_DISPLAYID_DATA_BLOCK_VESA_TIMING = 0x07, 78 /* Supported Timing Modes - CTA-861 Timings Data Block */ 79 DI_DISPLAYID_DATA_BLOCK_CEA_TIMING = 0x08, 80 /* Video Timing Range Data Block */ 81 DI_DISPLAYID_DATA_BLOCK_TIMING_RANGE_LIMITS = 0x09, 82 /* Product Serial Number Data Block */ 83 DI_DISPLAYID_DATA_BLOCK_PRODUCT_SERIAL = 0x0A, 84 /* General-purpose ASCII String Data Block */ 85 DI_DISPLAYID_DATA_BLOCK_ASCII_STRING = 0x0B, 86 /* Display Device Data Data Block */ 87 DI_DISPLAYID_DATA_BLOCK_DISPLAY_DEVICE_DATA = 0x0C, 88 /* Interface Power Sequencing Data Block */ 89 DI_DISPLAYID_DATA_BLOCK_INTERFACE_POWER_SEQ = 0x0D, 90 /* Transfer Characteristics Data Block */ 91 DI_DISPLAYID_DATA_BLOCK_TRANSFER_CHARACT = 0x0E, 92 /* Display Interface Data Block */ 93 DI_DISPLAYID_DATA_BLOCK_DISPLAY_INTERFACE = 0x0F, 94 /* Stereo Display Interface Data Block */ 95 DI_DISPLAYID_DATA_BLOCK_STEREO_DISPLAY_INTERFACE = 0x10, 96 /* Video Timing Modes Type V - Short Timings Data Block */ 97 DI_DISPLAYID_DATA_BLOCK_TYPE_V_TIMING = 0x11, 98 /* Tiled Display Topology Data Block */ 99 DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO = 0x12, 100 /* Video Timing Modes Type VI - Detailed Timings Data Block */ 101 DI_DISPLAYID_DATA_BLOCK_TYPE_VI_TIMING = 0x13, 102 }; 103 104 /** 105 * A DisplayID data block. 106 */ 107 struct di_displayid_data_block; 108 109 /** 110 * Get a DisplayID data block tag. 111 */ 112 enum di_displayid_data_block_tag 113 di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block); 114 115 /** 116 * Display parameters feature support flags, defined in section 4.2.3. 117 */ 118 struct di_displayid_display_params_features { 119 /* Audio support on video interface */ 120 bool audio; 121 /* Audio inputs are provided separately from the video interface */ 122 bool separate_audio_inputs; 123 /* Audio information received via the video interface will automatically 124 * override any other audio input channels provided */ 125 bool audio_input_override; 126 /* Display supports the VESA Display Power Management (DPM) standard */ 127 bool power_management; 128 /* Display is capable of only a single fixed timing */ 129 bool fixed_timing; 130 /* Display is capable of supporting timings at only a single fixed pixel 131 * format */ 132 bool fixed_pixel_format; 133 /* Display supports ACP, ISRC1 or ISRC2 packets */ 134 bool ai; 135 /* Display by default will de-interlace any interlaced video input */ 136 bool deinterlacing; 137 }; 138 139 /** 140 * Display parameters data block, defined in section 4.2. 141 */ 142 struct di_displayid_display_params { 143 /* Image size in millimeters accurate to the thenths place, zero if unset */ 144 float horiz_image_mm, vert_image_mm; 145 /* Native format size in pixels, zero if unset */ 146 int32_t horiz_pixels, vert_pixels; 147 /* Feature flags */ 148 const struct di_displayid_display_params_features *features; 149 /* Transfer characteristic gamma, zero if unset */ 150 float gamma; 151 /* Aspect ratio (long axis divided by short axis) */ 152 float aspect_ratio; 153 /* Color bit depth (dynamic range) */ 154 int32_t bits_per_color_overall, bits_per_color_native; 155 }; 156 157 /** 158 * Get display parameters from a DisplayID data block. 159 * 160 * Returns NULL if the data block tag isn't 161 * DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS. 162 */ 163 const struct di_displayid_display_params * 164 di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block); 165 166 enum di_displayid_type_i_ii_vii_timing_stereo_3d { 167 /* This timing is always displayed monoscopic (no stereo) */ 168 DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_NEVER = 0x00, 169 /* This timing is always displayed in stereo */ 170 DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_ALWAYS = 0x01, 171 /* This timing is displayed in mono or stereo depending on a user action 172 * (wearing the stereo glasses, etc.) */ 173 DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_USER = 0x02, 174 }; 175 176 enum di_displayid_timing_aspect_ratio { 177 DI_DISPLAYID_TIMING_ASPECT_RATIO_1_1 = 0x00, 178 DI_DISPLAYID_TIMING_ASPECT_RATIO_5_4 = 0x01, 179 DI_DISPLAYID_TIMING_ASPECT_RATIO_4_3 = 0x02, 180 DI_DISPLAYID_TIMING_ASPECT_RATIO_15_9 = 0x03, 181 DI_DISPLAYID_TIMING_ASPECT_RATIO_16_9 = 0x04, 182 DI_DISPLAYID_TIMING_ASPECT_RATIO_16_10 = 0x05, 183 DI_DISPLAYID_TIMING_ASPECT_RATIO_64_27 = 0x06, 184 DI_DISPLAYID_TIMING_ASPECT_RATIO_256_135 = 0x07, 185 DI_DISPLAYID_TIMING_ASPECT_RATIO_UNDEFINED = 0x08, 186 }; 187 188 enum di_displayid_type_i_ii_vii_timing_sync_polarity { 189 DI_DISPLAYID_TYPE_I_II_VII_TIMING_SYNC_NEGATIVE = 0x00, 190 DI_DISPLAYID_TYPE_I_II_VII_TIMING_SYNC_POSITIVE = 0x01, 191 }; 192 193 /** 194 * Type I timing, defined in DisplayID 1.3 section 4.4.1 and 195 * Type II timing, defined in DisplayID 1.3 section 4.4.2 and 196 * Type VII timing, defined in DisplayID 2.0 section 4.3.1. 197 */ 198 struct di_displayid_type_i_ii_vii_timing { 199 double pixel_clock_mhz; /* mega-hertz */ 200 bool preferred; 201 enum di_displayid_type_i_ii_vii_timing_stereo_3d stereo_3d; 202 bool interlaced; 203 enum di_displayid_timing_aspect_ratio aspect_ratio; 204 int32_t horiz_active, vert_active; 205 int32_t horiz_blank, vert_blank; 206 int32_t horiz_offset, vert_offset; 207 int32_t horiz_sync_width, vert_sync_width; 208 enum di_displayid_type_i_ii_vii_timing_sync_polarity horiz_sync_polarity, vert_sync_polarity; 209 }; 210 211 /** 212 * Get type I timings from a DisplayID data block. 213 * 214 * The returned array is NULL-terminated. 215 * 216 * Returns NULL if the data block tag isn't 217 * DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING. 218 */ 219 const struct di_displayid_type_i_ii_vii_timing *const * 220 di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *data_block); 221 222 /** 223 * Get type II timings from a DisplayID data block. 224 * 225 * The returned array is NULL-terminated. 226 * 227 * Returns NULL if the data block tag isn't 228 * DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING. 229 */ 230 const struct di_displayid_type_i_ii_vii_timing *const * 231 di_displayid_data_block_get_type_ii_timings(const struct di_displayid_data_block *data_block); 232 233 /** 234 * Behavior when more than 1 tile and less than total number of tiles are driven 235 * by the source. 236 */ 237 enum di_displayid_tiled_topo_missing_recv_behavior { 238 /* Undefined */ 239 DI_DISPLAYID_TILED_TOPO_MISSING_RECV_UNDEF = 0, 240 /* The image is displayed on the tile only */ 241 DI_DISPLAYID_TILED_TOPO_MISSING_RECV_TILE_ONLY = 1, 242 }; 243 244 /** 245 * Behavior of this tile when it is the only tile receiving an image from the 246 * source. 247 */ 248 enum di_displayid_tiled_topo_single_recv_behavior { 249 /* Undefined */ 250 DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_UNDEF = 0, 251 /* Image is displayed on the tile only */ 252 DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_TILE_ONLY = 1, 253 /* Image is scaled to fit the entire tiled display */ 254 DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_SCALED = 2, 255 /* Image is cloned to all other tiles of the entire tiled display */ 256 DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_CLONED = 3, 257 }; 258 259 /** 260 * Tiled display capabilities. 261 */ 262 struct di_displayid_tiled_topo_caps { 263 /* The tiled display is within a single physical display enclosure */ 264 bool single_enclosure; 265 266 /* Behavior when subsets of the tiles of the entire tiled display are 267 * receiving images from source */ 268 enum di_displayid_tiled_topo_missing_recv_behavior missing_recv_behavior; 269 enum di_displayid_tiled_topo_single_recv_behavior single_recv_behavior; 270 }; 271 272 /** 273 * Tiled display bezel information. 274 * 275 * The lengths are measured in pixels, accurate to the tenths place. 276 */ 277 struct di_displayid_tiled_topo_bezel { 278 float top_px, bottom_px, right_px, left_px; 279 }; 280 281 /** 282 * Tiled display topology, defined in section 4.14. 283 */ 284 struct di_displayid_tiled_topo { 285 /* Capabilities */ 286 const struct di_displayid_tiled_topo_caps *caps; 287 288 /* Total number of horizontal/vertical tiles */ 289 int32_t total_horiz_tiles, total_vert_tiles; 290 /* Horizontal/vertical tile location */ 291 int32_t horiz_tile_location, vert_tile_location; 292 /* Horizontal/vertical size in pixels */ 293 int32_t horiz_tile_pixels, vert_tile_lines; 294 295 /* Bezel information, NULL if unset */ 296 const struct di_displayid_tiled_topo_bezel *bezel; 297 298 /* Vendor PnP ID, product code and serial number */ 299 char vendor_id[3]; 300 uint16_t product_code; 301 uint32_t serial_number; 302 }; 303 304 /** 305 * Get tiled display topology from a DisplayID data block. 306 * 307 * Returns NULL if the data block tag isn't 308 * DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO. 309 */ 310 const struct di_displayid_tiled_topo * 311 di_displayid_data_block_get_tiled_topo(const struct di_displayid_data_block *data_block); 312 313 /** 314 * Formula/algorithm for type III timings. 315 */ 316 enum di_displayid_type_iii_timing_algo { 317 /* VESA CVT, standard blanking */ 318 DI_DISPLAYID_TYPE_III_TIMING_CVT_STANDARD_BLANKING = 0, 319 /* VESA CVT, reduced blanking */ 320 DI_DISPLAYID_TYPE_III_TIMING_CVT_REDUCED_BLANKING = 1, 321 }; 322 323 /** 324 * Type III timing, defined in section 4.4.3. 325 */ 326 struct di_displayid_type_iii_timing { 327 bool preferred; 328 enum di_displayid_type_iii_timing_algo algo; 329 enum di_displayid_timing_aspect_ratio aspect_ratio; 330 /* Horizontal Active Image (in pixels) */ 331 int32_t horiz_active; 332 bool interlaced; 333 /* Frame/Field Refresh Rate (in Hz) */ 334 int32_t refresh_rate_hz; 335 }; 336 337 /** 338 * Get type III timings from a DisplayID data block. 339 * 340 * The returned array is NULL-terminated. 341 * 342 * Returns NULL if the data block tag isn't 343 * DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING. 344 */ 345 const struct di_displayid_type_iii_timing *const * 346 di_displayid_data_block_get_type_iii_timings(const struct di_displayid_data_block *data_block); 347 348 /** 349 * Get DisplayID data blocks. 350 * 351 * The returned array is NULL-terminated. 352 */ 353 const struct di_displayid_data_block *const * 354 di_displayid_get_data_blocks(const struct di_displayid *displayid); 355 356 #endif 357